kernel-2_6_6-1_441
authorMarc Fiuczynski <mef@cs.princeton.edu>
Wed, 15 Sep 2004 17:11:52 +0000 (17:11 +0000)
committerMarc Fiuczynski <mef@cs.princeton.edu>
Wed, 15 Sep 2004 17:11:52 +0000 (17:11 +0000)
1710 files changed:
.config
.config.old
CREDITS
Documentation/arm/memory.txt
Documentation/binfmt_misc.txt
Documentation/fb/framebuffer.txt
Documentation/filesystems/Exporting
Documentation/filesystems/Locking
Documentation/filesystems/ntfs.txt
Documentation/filesystems/proc.txt
Documentation/ide.txt
Documentation/ioctl-number.txt
Documentation/kernel-parameters.txt
Documentation/networking/00-INDEX
Documentation/networking/ip-sysctl.txt
Documentation/networking/packet_mmap.txt
MAINTAINERS
Makefile
arch/alpha/kernel/init_task.c
arch/alpha/mm/numa.c
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/boot/compressed/head.S
arch/arm/configs/ebsa110_defconfig
arch/arm/configs/lpd7a400_defconfig
arch/arm/configs/lpd7a404_defconfig
arch/arm/kernel/debug.S
arch/arm/kernel/entry-armv.S
arch/arm/kernel/init_task.c
arch/arm/kernel/process.c
arch/arm/kernel/signal.c
arch/arm/lib/Makefile
arch/arm/lib/io-acorn.S
arch/arm/mach-clps711x/Kconfig
arch/arm/mach-ebsa110/io.c
arch/arm/mach-epxa10db/Kconfig
arch/arm/mach-footbridge/Kconfig
arch/arm/mach-integrator/Kconfig
arch/arm/mach-integrator/Makefile
arch/arm/mach-integrator/impd1.c
arch/arm/mach-integrator/integrator_cp.c
arch/arm/mach-iop3xx/Kconfig
arch/arm/mach-ixp4xx/Kconfig
arch/arm/mach-lh7a40x/Kconfig
arch/arm/mach-lh7a40x/arch-lpd7a40x.c
arch/arm/mach-omap/Kconfig
arch/arm/mach-omap/board-generic.c
arch/arm/mach-omap/board-innovator.c
arch/arm/mach-omap/board-osk.c
arch/arm/mach-omap/board-perseus2.c
arch/arm/mach-omap/bus.c
arch/arm/mach-omap/clocks.c
arch/arm/mach-omap/common.c
arch/arm/mach-omap/dma.c
arch/arm/mach-omap/fpga.c
arch/arm/mach-omap/gpio.c
arch/arm/mach-omap/irq.c
arch/arm/mach-omap/ocpi.c
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/idp.c
arch/arm/mach-pxa/leds-idp.c
arch/arm/mach-pxa/leds-lubbock.c
arch/arm/mach-pxa/leds-mainstone.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/pm.c
arch/arm/mach-s3c2410/Kconfig
arch/arm/mach-sa1100/Kconfig
arch/arm/mach-sa1100/cpu-sa1100.c
arch/arm/mach-sa1100/cpu-sa1110.c
arch/arm/mach-versatile/Makefile
arch/arm/mm/fault-armv.c
arch/arm/mm/fault.c
arch/arm/mm/mmap.c
arch/arm/mm/proc-syms.c
arch/arm/tools/mach-types
arch/arm26/kernel/init_task.c
arch/cris/arch-v10/drivers/ethernet.c
arch/cris/kernel/process.c
arch/h8300/Kconfig
arch/h8300/kernel/init_task.c
arch/h8300/kernel/ptrace.c
arch/h8300/platform/h8s/entry.S
arch/h8300/platform/h8s/ptrace_h8s.c
arch/i386/Kconfig
arch/i386/defconfig
arch/i386/kernel/Makefile
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/apic.c
arch/i386/kernel/cpu/cpufreq/elanfreq.c
arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
arch/i386/kernel/dmi_scan.c
arch/i386/kernel/efi.c
arch/i386/kernel/i386_ksyms.c
arch/i386/kernel/i8259.c
arch/i386/kernel/init_task.c
arch/i386/kernel/io_apic.c
arch/i386/kernel/irq.c
arch/i386/kernel/mpparse.c
arch/i386/kernel/process.c
arch/i386/kernel/setup.c
arch/i386/kernel/signal.c
arch/i386/kernel/smp.c
arch/i386/kernel/smpboot.c
arch/i386/kernel/time_hpet.c
arch/i386/kernel/timers/timer_cyclone.c
arch/i386/kernel/timers/timer_pm.c
arch/i386/kernel/traps.c
arch/i386/kernel/vm86.c
arch/i386/lib/Makefile
arch/i386/lib/delay.c
arch/i386/mach-es7000/es7000plat.c
arch/i386/mach-visws/mpparse.c
arch/i386/mach-visws/traps.c
arch/i386/mach-voyager/voyager_basic.c
arch/i386/mach-voyager/voyager_smp.c
arch/i386/mach-voyager/voyager_thread.c
arch/i386/math-emu/errors.c
arch/i386/math-emu/fpu_arith.c
arch/i386/math-emu/fpu_aux.c
arch/i386/math-emu/fpu_entry.c
arch/i386/math-emu/fpu_etc.c
arch/i386/math-emu/fpu_proto.h
arch/i386/math-emu/fpu_system.h
arch/i386/math-emu/get_address.c
arch/i386/math-emu/load_store.c
arch/i386/math-emu/reg_compare.c
arch/i386/math-emu/reg_ld_str.c
arch/i386/mm/fault.c
arch/i386/mm/hugetlbpage.c
arch/i386/mm/init.c
arch/i386/mm/ioremap.c
arch/i386/pci/acpi.c
arch/i386/pci/fixup.c
arch/ia64/Kconfig
arch/ia64/ia32/binfmt_elf32.c
arch/ia64/ia32/ia32_entry.S
arch/ia64/kernel/acpi.c
arch/ia64/kernel/entry.S
arch/ia64/kernel/fsys.S
arch/ia64/kernel/gate.S
arch/ia64/kernel/head.S
arch/ia64/kernel/init_task.c
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/irq.c
arch/ia64/kernel/setup.c
arch/ia64/kernel/smpboot.c
arch/ia64/kernel/time.c
arch/ia64/kernel/vmlinux.lds.S
arch/ia64/lib/Makefile
arch/ia64/pci/pci.c
arch/ia64/sn/io/machvec/iomv.c
arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c
arch/m68k/kernel/process.c
arch/m68knommu/kernel/init_task.c
arch/mips/kernel/init_task.c
arch/parisc/kernel/init_task.c
arch/ppc/8260_io/fcc_enet.c
arch/ppc/8260_io/uart.c
arch/ppc/Kconfig
arch/ppc/Makefile
arch/ppc/boot/simple/embed_config.c
arch/ppc/kernel/Makefile
arch/ppc/kernel/align.c
arch/ppc/kernel/asm-offsets.c
arch/ppc/kernel/cputable.c
arch/ppc/kernel/entry.S
arch/ppc/kernel/irq.c
arch/ppc/kernel/misc.S
arch/ppc/kernel/pci.c
arch/ppc/kernel/ppc_htab.c
arch/ppc/kernel/ppc_ksyms.c
arch/ppc/kernel/process.c
arch/ppc/kernel/ptrace.c
arch/ppc/kernel/signal.c
arch/ppc/kernel/traps.c
arch/ppc/lib/locks.c
arch/ppc/mm/Makefile
arch/ppc/mm/fault.c
arch/ppc/mm/init.c
arch/ppc/mm/mmu_decl.h
arch/ppc/mm/pgtable.c
arch/ppc/mm/tlb.c
arch/ppc/platforms/Makefile
arch/ppc/syslib/Makefile
arch/ppc/syslib/open_pic.c
arch/ppc64/Kconfig
arch/ppc64/Makefile
arch/ppc64/kernel/align.c
arch/ppc64/kernel/asm-offsets.c
arch/ppc64/kernel/entry.S
arch/ppc64/kernel/head.S
arch/ppc64/kernel/iSeries_setup.c
arch/ppc64/kernel/init_task.c
arch/ppc64/kernel/mf_proc.c
arch/ppc64/kernel/misc.S
arch/ppc64/kernel/pacaData.c
arch/ppc64/kernel/pmac_feature.c
arch/ppc64/kernel/process.c
arch/ppc64/kernel/ptrace.c
arch/ppc64/kernel/ptrace32.c
arch/ppc64/kernel/rtas.c
arch/ppc64/kernel/signal.c
arch/ppc64/kernel/signal32.c
arch/ppc64/kernel/smp.c
arch/ppc64/kernel/sys_ppc32.c
arch/ppc64/kernel/syscalls.c
arch/ppc64/kernel/sysfs.c
arch/ppc64/kernel/traps.c
arch/ppc64/kernel/vio.c
arch/ppc64/kernel/viopath.c
arch/ppc64/mm/fault.c
arch/ppc64/mm/hash_utils.c
arch/ppc64/mm/hugetlbpage.c
arch/ppc64/mm/init.c
arch/ppc64/mm/tlb.c
arch/ppc64/xmon/xmon.c
arch/s390/appldata/appldata_base.c
arch/s390/defconfig
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/compat_signal.c
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/debug.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/head.S
arch/s390/kernel/head64.S
arch/s390/kernel/init_task.c
arch/s390/kernel/process.c
arch/s390/kernel/profile.c
arch/s390/kernel/ptrace.c
arch/s390/kernel/s390_ksyms.c
arch/s390/kernel/setup.c
arch/s390/kernel/signal.c
arch/s390/kernel/sys_s390.c
arch/s390/kernel/traps.c
arch/s390/lib/Makefile
arch/s390/lib/uaccess.S
arch/s390/lib/uaccess64.S
arch/s390/mm/extmem.c
arch/s390/mm/ioremap.c
arch/sh/kernel/init_task.c
arch/sparc/kernel/init_task.c
arch/sparc/kernel/unaligned.c
arch/sparc/mm/fault.c
arch/sparc/mm/srmmu.c
arch/sparc/mm/sun4c.c
arch/sparc64/defconfig
arch/sparc64/kernel/chmc.c
arch/sparc64/kernel/init_task.c
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/smp.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/kernel/sys32.S
arch/sparc64/kernel/sys_sunos32.c
arch/sparc64/kernel/unaligned.c
arch/sparc64/lib/Makefile
arch/sparc64/lib/debuglocks.c
arch/sparc64/math-emu/sfp-util.h
arch/sparc64/mm/fault.c
arch/sparc64/mm/init.c
arch/um/kernel/init_task.c
arch/v850/kernel/init_task.c
arch/x86_64/Makefile
arch/x86_64/defconfig
arch/x86_64/ia32/fpu32.c
arch/x86_64/ia32/ia32_ioctl.c
arch/x86_64/ia32/ia32_signal.c
arch/x86_64/ia32/ia32entry.S
arch/x86_64/ia32/ptrace32.c
arch/x86_64/ia32/sys_ia32.c
arch/x86_64/ia32/syscall32.c
arch/x86_64/ia32/tls32.c
arch/x86_64/kernel/acpi/sleep.c
arch/x86_64/kernel/e820.c
arch/x86_64/kernel/head64.c
arch/x86_64/kernel/i387.c
arch/x86_64/kernel/init_task.c
arch/x86_64/kernel/io_apic.c
arch/x86_64/kernel/irq.c
arch/x86_64/kernel/ldt.c
arch/x86_64/kernel/mce.c
arch/x86_64/kernel/mpparse.c
arch/x86_64/kernel/msr.c
arch/x86_64/kernel/process.c
arch/x86_64/kernel/ptrace.c
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/setup64.c
arch/x86_64/kernel/signal.c
arch/x86_64/kernel/smpboot.c
arch/x86_64/kernel/sys_x86_64.c
arch/x86_64/kernel/traps.c
arch/x86_64/kernel/vmlinux.lds.S
arch/x86_64/kernel/x8664_ksyms.c
arch/x86_64/lib/Makefile
arch/x86_64/lib/csum-wrappers.c
arch/x86_64/lib/io.c
arch/x86_64/lib/usercopy.c
arch/x86_64/mm/fault.c
arch/x86_64/mm/init.c
arch/x86_64/mm/ioremap.c
arch/x86_64/mm/numa.c
arch/x86_64/mm/pageattr.c
crypto/digest.c
drivers/acpi/Kconfig
drivers/acpi/pci_irq.c
drivers/acpi/pci_link.c
drivers/acpi/pci_root.c
drivers/acpi/tables.c
drivers/acpi/thermal.c
drivers/atm/ambassador.c
drivers/atm/atmtcp.c
drivers/atm/eni.c
drivers/atm/firestream.c
drivers/atm/fore200e.c
drivers/atm/fore200e.h
drivers/atm/he.c
drivers/atm/horizon.c
drivers/atm/idt77105.c
drivers/atm/iphase.c
drivers/atm/iphase.h
drivers/atm/lanai.c
drivers/atm/nicstar.c
drivers/atm/suni.c
drivers/atm/uPD98402.c
drivers/atm/zatm.c
drivers/base/cpu.c
drivers/base/node.c
drivers/block/DAC960.c
drivers/block/DAC960.h
drivers/block/Kconfig
drivers/block/carmel.c
drivers/block/cciss.c
drivers/block/cciss_scsi.c
drivers/block/cfq-iosched.c
drivers/block/cpqarray.c
drivers/block/elevator.c
drivers/block/floppy.c
drivers/block/ida_ioctl.h
drivers/block/ll_rw_blk.c
drivers/block/loop.c
drivers/block/paride/epat.c
drivers/block/paride/pf.c
drivers/block/paride/pg.c
drivers/block/paride/pt.c
drivers/block/ps2esdi.c
drivers/block/rd.c
drivers/block/umem.c
drivers/block/xd.c
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_vhci.c
drivers/cdrom/aztcd.c
drivers/cdrom/cdrom.c
drivers/cdrom/cdu31a.c
drivers/cdrom/optcd.c
drivers/cdrom/sjcd.c
drivers/cdrom/sonycd535.c
drivers/char/Kconfig
drivers/char/Makefile
drivers/char/applicom.c
drivers/char/cyclades.c
drivers/char/drm/drm_agpsupport.h
drivers/char/drm/drm_ioctl.h
drivers/char/drm/gamma_dma.c
drivers/char/drm/r128_state.c
drivers/char/drm/radeon.h
drivers/char/drm/radeon_drm.h
drivers/char/drm/radeon_drv.h
drivers/char/drm/radeon_mem.c
drivers/char/drm/radeon_state.c
drivers/char/drm/sis_mm.c
drivers/char/i8k.c
drivers/char/ipmi/ipmi_bt_sm.c
drivers/char/ipmi/ipmi_devintf.c
drivers/char/ipmi/ipmi_kcs_sm.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/ipmi/ipmi_smic_sm.c
drivers/char/ipmi/ipmi_watchdog.c
drivers/char/istallion.c
drivers/char/keyboard.c
drivers/char/lp.c
drivers/char/mem.c
drivers/char/mwave/3780i.c
drivers/char/mwave/3780i.h
drivers/char/mwave/mwavedd.c
drivers/char/mwave/tp3780i.c
drivers/char/mwave/tp3780i.h
drivers/char/nvram.c
drivers/char/pcmcia/synclink_cs.c
drivers/char/ppdev.c
drivers/char/rtc.c
drivers/char/scx200_gpio.c
drivers/char/sonypi.c
drivers/char/synclink.c
drivers/char/synclinkmp.c
drivers/char/toshiba.c
drivers/char/tpqic02.c
drivers/char/tty_io.c
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/cpu5wdt.c
drivers/char/watchdog/eurotechwdt.c
drivers/char/watchdog/i8xx_tco.c
drivers/char/watchdog/ib700wdt.c
drivers/char/watchdog/machzwd.c
drivers/char/watchdog/mixcomwd.c
drivers/char/watchdog/pcwd.c
drivers/char/watchdog/pcwd_pci.c
drivers/char/watchdog/pcwd_usb.c
drivers/char/watchdog/sbc60xxwdt.c
drivers/char/watchdog/sc1200wdt.c
drivers/char/watchdog/sc520_wdt.c
drivers/char/watchdog/scx200_wdt.c
drivers/char/watchdog/softdog.c
drivers/char/watchdog/w83627hf_wdt.c
drivers/char/watchdog/w83877f_wdt.c
drivers/char/watchdog/wafer5823wdt.c
drivers/char/watchdog/wdt.c
drivers/char/watchdog/wdt_pci.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_userspace.c
drivers/cpufreq/proc_intf.c
drivers/fc4/fc.c
drivers/firmware/edd.c
drivers/i2c/i2c-core.c
drivers/ide/Kconfig
drivers/ide/Makefile
drivers/ide/ide-cd.c
drivers/ide/ide-cd.h
drivers/ide/ide-disk.c
drivers/ide/ide-dma.c
drivers/ide/ide-floppy.c
drivers/ide/ide-io.c
drivers/ide/ide-pnp.c
drivers/ide/ide-probe.c
drivers/ide/ide-proc.c
drivers/ide/ide-tape.c
drivers/ide/ide-taskfile.c
drivers/ide/ide.c
drivers/ide/legacy/pdc4030.c
drivers/ide/pci/aec62xx.c
drivers/ide/pci/alim15x3.c
drivers/ide/pci/cmd64x.c
drivers/ide/pci/cs5520.c
drivers/ide/pci/cs5530.c
drivers/ide/pci/hpt34x.c
drivers/ide/pci/hpt366.c
drivers/ide/pci/ns87415.c
drivers/ide/pci/pdc202xx_new.c
drivers/ide/pci/pdc202xx_old.c
drivers/ide/pci/piix.c
drivers/ide/pci/rz1000.c
drivers/ide/pci/sc1200.c
drivers/ide/pci/siimage.c
drivers/ide/pci/sis5513.c
drivers/ide/pci/sl82c105.c
drivers/ide/pci/slc90e66.c
drivers/ide/pci/triflex.c
drivers/ide/pci/trm290.c
drivers/ide/pci/via82cxxx.c
drivers/ieee1394/csr1212.c
drivers/ieee1394/csr1212.h
drivers/ieee1394/eth1394.c
drivers/ieee1394/highlevel.c
drivers/ieee1394/hosts.c
drivers/ieee1394/hosts.h
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/nodemgr.c
drivers/ieee1394/ohci1394.c
drivers/ieee1394/sbp2.c
drivers/ieee1394/video1394.c
drivers/input/Kconfig
drivers/input/evbug.c
drivers/input/evdev.c
drivers/input/gameport/cs461x.c
drivers/input/gameport/emu10k1-gp.c
drivers/input/gameport/fm801-gp.c
drivers/input/gameport/gameport.c
drivers/input/gameport/lightning.c
drivers/input/gameport/ns558.c
drivers/input/gameport/vortex.c
drivers/input/input.c
drivers/input/joydev.c
drivers/input/joystick/Kconfig
drivers/input/joystick/a3d.c
drivers/input/joystick/adi.c
drivers/input/joystick/amijoy.c
drivers/input/joystick/analog.c
drivers/input/joystick/cobra.c
drivers/input/joystick/db9.c
drivers/input/joystick/gamecon.c
drivers/input/joystick/gf2k.c
drivers/input/joystick/grip.c
drivers/input/joystick/grip_mp.c
drivers/input/joystick/guillemot.c
drivers/input/joystick/iforce/Kconfig
drivers/input/joystick/iforce/Makefile
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-serio.c
drivers/input/joystick/iforce/iforce.h
drivers/input/joystick/interact.c
drivers/input/joystick/joydump.c
drivers/input/joystick/magellan.c
drivers/input/joystick/sidewinder.c
drivers/input/joystick/spaceball.c
drivers/input/joystick/spaceorb.c
drivers/input/joystick/stinger.c
drivers/input/joystick/tmdc.c
drivers/input/joystick/turbografx.c
drivers/input/joystick/twidjoy.c
drivers/input/joystick/warrior.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/maple_keyb.c
drivers/input/keyboard/sunkbd.c
drivers/input/keyboard/xtkbd.c
drivers/input/misc/Kconfig
drivers/input/misc/pcspkr.c
drivers/input/misc/sparcspkr.c
drivers/input/misc/uinput.c
drivers/input/mouse/Kconfig
drivers/input/mouse/Makefile
drivers/input/mouse/logips2pp.c
drivers/input/mouse/logips2pp.h
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse.h
drivers/input/mouse/synaptics.c
drivers/input/mouse/synaptics.h
drivers/input/mousedev.c
drivers/input/power.c
drivers/input/serio/Kconfig
drivers/input/serio/ambakmi.c
drivers/input/serio/ct82c710.c
drivers/input/serio/gscps2.c
drivers/input/serio/i8042.c
drivers/input/serio/parkbd.c
drivers/input/serio/q40kbd.c
drivers/input/serio/rpckbd.c
drivers/input/serio/serio.c
drivers/input/serio/serport.c
drivers/input/touchscreen/gunze.c
drivers/input/touchscreen/h3600_ts_input.c
drivers/input/tsdev.c
drivers/isdn/hisax/nj_s.c
drivers/isdn/i4l/isdn_common.c
drivers/md/Kconfig
drivers/md/Makefile
drivers/md/dm-ioctl.c
drivers/md/dm-table.c
drivers/md/dm.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid1.c
drivers/md/raid5.c
drivers/md/raid6main.c
drivers/media/common/saa7146_fops.c
drivers/media/dvb/frontends/tda1004x.c
drivers/message/fusion/isense.c
drivers/message/fusion/linux_compat.h
drivers/message/fusion/lsi/mpi_type.h
drivers/message/fusion/mptbase.c
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptctl.c
drivers/message/fusion/mptctl.h
drivers/message/fusion/mptlan.c
drivers/message/fusion/mptscsih.c
drivers/message/fusion/mptscsih.h
drivers/message/i2o/i2o_block.c
drivers/message/i2o/i2o_config.c
drivers/message/i2o/i2o_core.c
drivers/message/i2o/i2o_scsi.c
drivers/misc/ibmasm/ibmasmfs.c
drivers/mtd/chips/jedec_probe.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/Makefile
drivers/mtd/maps/lubbock-flash.c
drivers/mtd/mtdblock.c
drivers/net/3c501.c
drivers/net/3c503.c
drivers/net/3c505.c
drivers/net/3c507.c
drivers/net/3c509.c
drivers/net/3c523.c
drivers/net/3c527.c
drivers/net/3c59x.c
drivers/net/8139cp.c
drivers/net/8139too.c
drivers/net/82596.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/Space.c
drivers/net/ac3200.c
drivers/net/acenic.c
drivers/net/acenic.h
drivers/net/amd8111e.c
drivers/net/apne.c
drivers/net/appletalk/cops.c
drivers/net/appletalk/ipddp.c
drivers/net/arm/Kconfig
drivers/net/arm/Makefile
drivers/net/arm/am79c961a.c
drivers/net/at1700.c
drivers/net/au1000_eth.c
drivers/net/b44.c
drivers/net/bonding/bond_main.c
drivers/net/cs89x0.c
drivers/net/defxx.c
drivers/net/depca.c
drivers/net/depca.h
drivers/net/dl2k.c
drivers/net/e100.c
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_main.c
drivers/net/e2100.c
drivers/net/eepro.c
drivers/net/eepro100.c
drivers/net/eexpress.c
drivers/net/epic100.c
drivers/net/eql.c
drivers/net/es3210.c
drivers/net/eth16i.c
drivers/net/ewrk3.c
drivers/net/ewrk3.h
drivers/net/fc/iph5526.c
drivers/net/fealnx.c
drivers/net/fmv18x.c
drivers/net/forcedeth.c
drivers/net/hamachi.c
drivers/net/hamradio/baycom_epp.c
drivers/net/hamradio/baycom_par.c
drivers/net/hamradio/baycom_ser_fdx.c
drivers/net/hamradio/baycom_ser_hdx.c
drivers/net/hamradio/bpqether.c
drivers/net/hamradio/scc.c
drivers/net/hp-plus.c
drivers/net/hp.c
drivers/net/hp100.c
drivers/net/ibm_emac/ibm_emac_core.c
drivers/net/ibmlana.c
drivers/net/ibmveth.c
drivers/net/ioc3-eth.c
drivers/net/irda/ali-ircc.c
drivers/net/irda/ali-ircc.h
drivers/net/irda/irtty-sir.c
drivers/net/irda/nsc-ircc.c
drivers/net/irda/nsc-ircc.h
drivers/net/irda/smsc-ircc2.c
drivers/net/irda/via-ircc.c
drivers/net/irda/via-ircc.h
drivers/net/irda/w83977af_ir.c
drivers/net/irda/w83977af_ir.h
drivers/net/isa-skeleton.c
drivers/net/ixgb/ixgb_ethtool.c
drivers/net/ixgb/ixgb_main.c
drivers/net/jazzsonic.c
drivers/net/lance.c
drivers/net/lasi_82596.c
drivers/net/lne390.c
drivers/net/lp486e.c
drivers/net/macsonic.c
drivers/net/natsemi.c
drivers/net/ne-h8300.c
drivers/net/ne.c
drivers/net/ne2.c
drivers/net/ne3210.c
drivers/net/ni52.c
drivers/net/ns83820.c
drivers/net/oaknet.c
drivers/net/pci-skeleton.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/pcmcia/xirc2ps_cs.c
drivers/net/pcnet32.c
drivers/net/plip.c
drivers/net/r8169.c
drivers/net/rrunner.c
drivers/net/s2io.c
drivers/net/s2io.h
drivers/net/sb1000.c
drivers/net/sb1250-mac.c
drivers/net/shaper.c
drivers/net/sis900.c
drivers/net/slip.c
drivers/net/smc-mca.c
drivers/net/smc-ultra.c
drivers/net/smc-ultra32.c
drivers/net/smc9194.c
drivers/net/starfire.c
drivers/net/stnic.c
drivers/net/sun3_82586.c
drivers/net/sun3lance.c
drivers/net/sundance.c
drivers/net/sungem.c
drivers/net/sunhme.c
drivers/net/tg3.c
drivers/net/tlan.c
drivers/net/tulip/Kconfig
drivers/net/tulip/de4x5.c
drivers/net/tulip/de4x5.h
drivers/net/tulip/interrupt.c
drivers/net/tulip/tulip_core.c
drivers/net/tulip/winbond-840.c
drivers/net/tulip/xircom_tulip_cb.c
drivers/net/tun.c
drivers/net/typhoon.c
drivers/net/via-rhine.c
drivers/net/wan/dlci.c
drivers/net/wan/pc300_drv.c
drivers/net/wan/sbni.c
drivers/net/wan/sdla.c
drivers/net/wd.c
drivers/net/wireless/airo.c
drivers/net/wireless/prism54/isl_38xx.c
drivers/net/wireless/prism54/isl_38xx.h
drivers/net/wireless/prism54/isl_ioctl.c
drivers/net/wireless/prism54/isl_ioctl.h
drivers/net/wireless/prism54/islpci_dev.c
drivers/net/wireless/prism54/islpci_dev.h
drivers/net/wireless/prism54/islpci_eth.c
drivers/net/wireless/prism54/islpci_hotplug.c
drivers/net/wireless/prism54/islpci_mgt.c
drivers/net/wireless/prism54/islpci_mgt.h
drivers/net/wireless/prism54/oid_mgt.c
drivers/net/wireless/prism54/oid_mgt.h
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wl3501_cs.c
drivers/net/yellowfin.c
drivers/net/zorro8390.c
drivers/parisc/ccio-dma.c
drivers/parisc/ccio-rm-dma.c
drivers/pci/pci.ids
drivers/pcmcia/ds.c
drivers/pcmcia/i82365.c
drivers/pcmcia/pxa2xx_base.c
drivers/pcmcia/pxa2xx_lubbock.c
drivers/pcmcia/pxa2xx_mainstone.c
drivers/pcmcia/sa11xx_base.c
drivers/pcmcia/soc_common.c
drivers/pcmcia/soc_common.h
drivers/pcmcia/yenta_socket.c
drivers/pnp/isapnp/core.c
drivers/pnp/isapnp/proc.c
drivers/pnp/pnpbios/proc.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_cmb.c
drivers/s390/block/dasd_diag.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_int.h
drivers/s390/block/dasd_ioctl.c
drivers/s390/block/dasd_proc.c
drivers/s390/block/dcssblk.c
drivers/s390/block/xpram.c
drivers/s390/char/con3215.c
drivers/s390/char/keyboard.c
drivers/s390/char/sclp_tty.c
drivers/s390/char/sclp_vt220.c
drivers/s390/char/tape.h
drivers/s390/char/tape_34xx.c
drivers/s390/char/tape_block.c
drivers/s390/char/tape_char.c
drivers/s390/char/tape_core.c
drivers/s390/char/tape_proc.c
drivers/s390/char/tape_std.c
drivers/s390/cio/airq.c
drivers/s390/cio/blacklist.c
drivers/s390/cio/ccwgroup.c
drivers/s390/cio/chsc.c
drivers/s390/cio/chsc.h
drivers/s390/cio/cio.c
drivers/s390/cio/css.c
drivers/s390/cio/css.h
drivers/s390/cio/device.c
drivers/s390/cio/device_fsm.c
drivers/s390/cio/requestirq.c
drivers/s390/crypto/z90crypt.h
drivers/s390/crypto/z90main.c
drivers/s390/net/ctctty.c
drivers/s390/net/iucv.c
drivers/s390/net/netiucv.c
drivers/s390/net/qeth.h
drivers/s390/net/qeth_main.c
drivers/s390/net/qeth_sys.c
drivers/s390/s390mach.c
drivers/scsi/53c700.c
drivers/scsi/53c700.h
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/NCR53C9x.c
drivers/scsi/NCR_D700.c
drivers/scsi/advansys.c
drivers/scsi/aha152x.c
drivers/scsi/arm/acornscsi.c
drivers/scsi/arm/arxescsi.c
drivers/scsi/arm/cumana_1.c
drivers/scsi/arm/cumana_2.c
drivers/scsi/arm/ecoscsi.c
drivers/scsi/arm/eesox.c
drivers/scsi/arm/fas216.c
drivers/scsi/arm/oak.c
drivers/scsi/arm/powertec.c
drivers/scsi/ata_piix.c
drivers/scsi/constants.c
drivers/scsi/cpqfcTScontrol.c
drivers/scsi/dc390.h
drivers/scsi/dpt_i2o.c
drivers/scsi/dpti.h
drivers/scsi/eata_generic.h
drivers/scsi/eata_pio.c
drivers/scsi/esp.c
drivers/scsi/esp.h
drivers/scsi/fd_mcs.c
drivers/scsi/fdomain.c
drivers/scsi/gdth.c
drivers/scsi/ide-scsi.c
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/lasi700.c
drivers/scsi/megaraid.c
drivers/scsi/osst.c
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/qla1280.c
drivers/scsi/qlogicfc.c
drivers/scsi/qlogicpti.c
drivers/scsi/qlogicpti.h
drivers/scsi/scsi.h
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_debug.h
drivers/scsi/scsi_devinfo.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_ioctl.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_syms.c
drivers/scsi/scsi_transport_spi.c
drivers/scsi/scsiiom.c
drivers/scsi/sd.c
drivers/scsi/sg.c
drivers/scsi/sim710.c
drivers/scsi/sr.c
drivers/scsi/sr_ioctl.c
drivers/scsi/st.c
drivers/scsi/sym53c416.c
drivers/scsi/tmscsim.c
drivers/scsi/tmscsim.h
drivers/scsi/wd7000.c
drivers/serial/8250_acpi.c
drivers/serial/8250_hcdp.c
drivers/serial/8250_pnp.c
drivers/serial/Kconfig
drivers/serial/Makefile
drivers/serial/amba-pl011.c
drivers/serial/s3c2410.c
drivers/telephony/ixj.c
drivers/telephony/ixj.h
drivers/usb/Kconfig
drivers/usb/class/audio.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/usblp.c
drivers/usb/core/devices.c
drivers/usb/core/devio.c
drivers/usb/core/hcd-pci.c
drivers/usb/core/hcd.c
drivers/usb/core/hcd.h
drivers/usb/core/hub.c
drivers/usb/core/hub.h
drivers/usb/core/message.c
drivers/usb/core/sysfs.c
drivers/usb/core/usb.c
drivers/usb/core/usb.h
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/ether.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/ndis.h
drivers/usb/gadget/net2280.c
drivers/usb/gadget/rndis.c
drivers/usb/gadget/rndis.h
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/hc_sl811_rh.c
drivers/usb/host/ohci-dbg.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/ohci-q.c
drivers/usb/host/ohci-sa1111.c
drivers/usb/host/ohci.h
drivers/usb/host/uhci-hcd.c
drivers/usb/image/hpusbscsi.c
drivers/usb/image/mdc800.c
drivers/usb/image/microtek.c
drivers/usb/input/Kconfig
drivers/usb/input/ati_remote.c
drivers/usb/input/hid-core.c
drivers/usb/input/hiddev.c
drivers/usb/media/Kconfig
drivers/usb/media/dabusb.c
drivers/usb/media/ov511.c
drivers/usb/media/ov511.h
drivers/usb/media/pwc-if.c
drivers/usb/media/se401.c
drivers/usb/media/stv680.c
drivers/usb/media/usbvideo.c
drivers/usb/media/vicam.c
drivers/usb/media/w9968cf.c
drivers/usb/media/w9968cf.h
drivers/usb/misc/auerswald.c
drivers/usb/misc/legousbtower.c
drivers/usb/misc/phidgetservo.c
drivers/usb/misc/speedtch.c
drivers/usb/misc/usbtest.c
drivers/usb/net/catc.c
drivers/usb/net/kaweth.c
drivers/usb/net/pegasus.c
drivers/usb/net/pegasus.h
drivers/usb/net/rtl8150.c
drivers/usb/net/usbnet.c
drivers/usb/serial/bus.c
drivers/usb/serial/cyberjack.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/io_ti.c
drivers/usb/serial/kl5kusb105.c
drivers/usb/serial/kobil_sct.c
drivers/usb/serial/visor.c
drivers/usb/serial/visor.h
drivers/usb/serial/whiteheat.c
drivers/usb/storage/Kconfig
drivers/usb/storage/jumpshot.c
drivers/usb/storage/scsiglue.c
drivers/usb/storage/transport.c
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
drivers/usb/storage/usb.h
drivers/video/Kconfig
drivers/video/aty/radeon_accel.c
drivers/video/aty/radeon_base.c
drivers/video/console/fbcon.c
drivers/video/console/fbcon.h
drivers/video/console/sticore.c
drivers/video/console/vgacon.c
drivers/video/fbmem.c
drivers/video/imsttfb.c
drivers/video/kyro/fbdev.c
drivers/video/matrox/matroxfb_base.c
drivers/video/matrox/matroxfb_crtc2.c
drivers/video/modedb.c
drivers/video/pxafb.c
drivers/video/radeonfb.c
drivers/video/riva/Makefile
drivers/video/riva/fbdev.c
drivers/video/riva/rivafb.h
drivers/video/sbuslib.c
drivers/video/sis/300vtbl.h
drivers/video/sis/310vtbl.h
drivers/video/sis/init.c
drivers/video/sis/init.h
drivers/video/sis/init301.c
drivers/video/sis/init301.h
drivers/video/sis/initdef.h
drivers/video/sis/oem300.h
drivers/video/sis/oem310.h
drivers/video/sis/osdef.h
drivers/video/sis/sis.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/sis/vstruct.h
drivers/video/skeletonfb.c
drivers/video/sstfb.c
drivers/video/vga16fb.c
fs/afs/file.c
fs/afs/proc.c
fs/aio.c
fs/autofs/root.c
fs/binfmt_aout.c
fs/binfmt_elf.c
fs/binfmt_flat.c
fs/binfmt_misc.c
fs/cifs/AUTHORS
fs/cifs/CHANGES
fs/cifs/README
fs/cifs/TODO
fs/cifs/cifs_debug.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/fcntl.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/link.c
fs/cifs/transport.c
fs/cifs/xattr.c
fs/coda/file.c
fs/coda/pioctl.c
fs/coda/psdev.c
fs/coda/sysctl.c
fs/compat.c
fs/compat_ioctl.c
fs/devfs/base.c
fs/direct-io.c
fs/dquot.c
fs/eventpoll.c
fs/exec.c
fs/ext3/Makefile
fs/ext3/balloc.c
fs/ext3/file.c
fs/ext3/ialloc.c
fs/ext3/inode.c
fs/ext3/ioctl.c
fs/ext3/namei.c
fs/ext3/super.c
fs/ext3/xattr.c
fs/fs-writeback.c
fs/hfsplus/ioctl.c
fs/hugetlbfs/inode.c
fs/isofs/Makefile
fs/isofs/dir.c
fs/isofs/inode.c
fs/isofs/namei.c
fs/isofs/rock.c
fs/jbd/commit.c
fs/jbd/journal.c
fs/jbd/revoke.c
fs/jffs/inode-v23.c
fs/jfs/jfs_btree.h
fs/jfs/jfs_dmap.c
fs/jfs/jfs_dtree.c
fs/jfs/jfs_metapage.c
fs/jfs/jfs_txnmgr.c
fs/jfs/jfs_types.h
fs/jfs/namei.c
fs/jfs/xattr.c
fs/ncpfs/dir.c
fs/ncpfs/file.c
fs/ncpfs/ioctl.c
fs/ncpfs/ncplib_kernel.c
fs/ncpfs/ncplib_kernel.h
fs/nfs/direct.c
fs/nfs/idmap.c
fs/nfs/write.c
fs/nfsd/nfs3proc.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsfh.c
fs/ntfs/ChangeLog
fs/ntfs/Makefile
fs/ntfs/aops.c
fs/ntfs/attrib.c
fs/ntfs/compress.c
fs/ntfs/dir.c
fs/ntfs/inode.c
fs/ntfs/mft.c
fs/ntfs/mft.h
fs/ntfs/super.c
fs/partitions/Kconfig
fs/partitions/check.c
fs/partitions/msdos.c
fs/proc/base.c
fs/proc/generic.c
fs/proc/proc_misc.c
fs/quota_v1.c
fs/reiserfs/bitmap.c
fs/reiserfs/dir.c
fs/reiserfs/file.c
fs/reiserfs/inode.c
fs/reiserfs/journal.c
fs/reiserfs/stree.c
fs/reiserfs/super.c
fs/reiserfs/tail_conversion.c
fs/smbfs/file.c
fs/smbfs/ioctl.c
fs/smbfs/smbiod.c
fs/stat.c
fs/super.c
fs/sysfs/file.c
fs/udf/crc.c
fs/udf/file.c
fs/udf/misc.c
include/acpi/acpi_drivers.h
include/asm-alpha/resource.h
include/asm-arm/arch-ebsa110/io.h
include/asm-arm/arch-ebsa110/system.h
include/asm-arm/arch-ebsa110/timex.h
include/asm-arm/arch-ebsa110/uncompress.h
include/asm-arm/arch-integrator/impd1.h
include/asm-arm/arch-lh7a40x/hardware.h
include/asm-arm/arch-lh7a40x/memory.h
include/asm-arm/arch-omap/board-innovator.h
include/asm-arm/arch-omap/bus.h
include/asm-arm/arch-omap/dma.h
include/asm-arm/arch-omap/gpio.h
include/asm-arm/arch-omap/hardware.h
include/asm-arm/arch-omap/io.h
include/asm-arm/arch-omap/mux.h
include/asm-arm/arch-omap/omap1610.h
include/asm-arm/arch-omap/omap5912.h
include/asm-arm/arch-omap/omap730.h
include/asm-arm/arch-omap/time.h
include/asm-arm/arch-omap/uncompress.h
include/asm-arm/arch-pxa/hardware.h
include/asm-arm/arch-s3c2410/regs-gpio.h
include/asm-arm/arch-s3c2410/regs-irq.h
include/asm-arm/cacheflush.h
include/asm-arm/fpstate.h
include/asm-arm/pgtable.h
include/asm-arm/resource.h
include/asm-arm/thread_info.h
include/asm-arm/uaccess.h
include/asm-arm/unistd.h
include/asm-arm26/resource.h
include/asm-arm26/tlb.h
include/asm-arm26/unistd.h
include/asm-cris/resource.h
include/asm-cris/unistd.h
include/asm-generic/tlb.h
include/asm-h8300/io.h
include/asm-h8300/resource.h
include/asm-h8300/unistd.h
include/asm-i386/acpi.h
include/asm-i386/apic.h
include/asm-i386/bitops.h
include/asm-i386/checksum.h
include/asm-i386/delay.h
include/asm-i386/dma-mapping.h
include/asm-i386/floppy.h
include/asm-i386/genapic.h
include/asm-i386/hpet.h
include/asm-i386/i387.h
include/asm-i386/ide.h
include/asm-i386/io_apic.h
include/asm-i386/mach-bigsmp/mach_apic.h
include/asm-i386/mach-bigsmp/mach_mpspec.h
include/asm-i386/mach-default/mach_apic.h
include/asm-i386/mach-default/mach_mpspec.h
include/asm-i386/mach-es7000/mach_apic.h
include/asm-i386/mach-es7000/mach_mpspec.h
include/asm-i386/mach-generic/mach_apic.h
include/asm-i386/mach-generic/mach_mpspec.h
include/asm-i386/mach-numaq/mach_apic.h
include/asm-i386/mach-numaq/mach_mpspec.h
include/asm-i386/mach-summit/mach_apic.h
include/asm-i386/mach-summit/mach_mpspec.h
include/asm-i386/mach-visws/mach_apic.h
include/asm-i386/mpspec.h
include/asm-i386/mpspec_def.h
include/asm-i386/msi.h
include/asm-i386/pgtable.h
include/asm-i386/processor.h
include/asm-i386/resource.h
include/asm-i386/serial.h
include/asm-i386/timex.h
include/asm-i386/unistd.h
include/asm-ia64/bitops.h
include/asm-ia64/iosapic.h
include/asm-ia64/pgtable.h
include/asm-ia64/resource.h
include/asm-ia64/system.h
include/asm-ia64/unistd.h
include/asm-m68k/resource.h
include/asm-m68k/unistd.h
include/asm-m68knommu/unistd.h
include/asm-mips/checksum.h
include/asm-mips/resource.h
include/asm-mips/unistd.h
include/asm-parisc/checksum.h
include/asm-parisc/pgtable.h
include/asm-parisc/resource.h
include/asm-parisc/unistd.h
include/asm-ppc/bug.h
include/asm-ppc/elf.h
include/asm-ppc/hardirq.h
include/asm-ppc/io.h
include/asm-ppc/mmu.h
include/asm-ppc/mmu_context.h
include/asm-ppc/mpc8260.h
include/asm-ppc/ocp.h
include/asm-ppc/ocp_ids.h
include/asm-ppc/pgtable.h
include/asm-ppc/ppc_asm.h
include/asm-ppc/ppcboot.h
include/asm-ppc/processor.h
include/asm-ppc/ptrace.h
include/asm-ppc/reg.h
include/asm-ppc/reg_booke.h
include/asm-ppc/resource.h
include/asm-ppc/serial.h
include/asm-ppc/spinlock.h
include/asm-ppc/system.h
include/asm-ppc/tlbflush.h
include/asm-ppc/unistd.h
include/asm-ppc64/current.h
include/asm-ppc64/hardirq.h
include/asm-ppc64/io.h
include/asm-ppc64/paca.h
include/asm-ppc64/pgalloc.h
include/asm-ppc64/pgtable.h
include/asm-ppc64/ppc_asm.h
include/asm-ppc64/processor.h
include/asm-ppc64/ptrace.h
include/asm-ppc64/resource.h
include/asm-ppc64/system.h
include/asm-ppc64/thread_info.h
include/asm-ppc64/tlbflush.h
include/asm-ppc64/unistd.h
include/asm-ppc64/vio.h
include/asm-s390/atomic.h
include/asm-s390/checksum.h
include/asm-s390/compat.h
include/asm-s390/debug.h
include/asm-s390/idals.h
include/asm-s390/ipc.h
include/asm-s390/pgtable.h
include/asm-s390/ptrace.h
include/asm-s390/resource.h
include/asm-s390/setup.h
include/asm-s390/spinlock.h
include/asm-s390/string.h
include/asm-s390/thread_info.h
include/asm-s390/types.h
include/asm-s390/uaccess.h
include/asm-s390/unistd.h
include/asm-sh/checksum.h
include/asm-sh/resource.h
include/asm-sh/unistd.h
include/asm-sparc/checksum.h
include/asm-sparc/dma-mapping.h
include/asm-sparc/highmem.h
include/asm-sparc/pgtable.h
include/asm-sparc/pgtsrmmu.h
include/asm-sparc/pgtsun4.h
include/asm-sparc/pgtsun4c.h
include/asm-sparc/resource.h
include/asm-sparc/viking.h
include/asm-sparc64/bitops.h
include/asm-sparc64/checksum.h
include/asm-sparc64/resource.h
include/asm-um/unistd.h
include/asm-v850/resource.h
include/asm-v850/unistd.h
include/asm-x86_64/bitops.h
include/asm-x86_64/checksum.h
include/asm-x86_64/compat.h
include/asm-x86_64/desc.h
include/asm-x86_64/floppy.h
include/asm-x86_64/fpu32.h
include/asm-x86_64/i387.h
include/asm-x86_64/ia32.h
include/asm-x86_64/ia32_unistd.h
include/asm-x86_64/ide.h
include/asm-x86_64/io.h
include/asm-x86_64/mpspec.h
include/asm-x86_64/page.h
include/asm-x86_64/pgtable.h
include/asm-x86_64/processor.h
include/asm-x86_64/ptrace.h
include/asm-x86_64/resource.h
include/asm-x86_64/semaphore.h
include/asm-x86_64/sigcontext.h
include/asm-x86_64/uaccess.h
include/asm-x86_64/unistd.h
include/linux/acct.h
include/linux/acpi.h
include/linux/aio.h
include/linux/atm.h
include/linux/atmdev.h
include/linux/autoconf.h
include/linux/binfmts.h
include/linux/blkdev.h
include/linux/cciss_ioctl.h
include/linux/cdrom.h
include/linux/coda.h
include/linux/coda_proc.h
include/linux/compat_ioctl.h
include/linux/cpu.h
include/linux/cpumask.h
include/linux/edd.h
include/linux/efi.h
include/linux/ethtool.h
include/linux/ext3_fs.h
include/linux/ext3_fs_i.h
include/linux/ext3_fs_sb.h
include/linux/fb.h
include/linux/fd.h
include/linux/filter.h
include/linux/hugetlb.h
include/linux/i2o.h
include/linux/ide.h
include/linux/idr.h
include/linux/if.h
include/linux/if_arp.h
include/linux/if_bridge.h
include/linux/if_frad.h
include/linux/if_vlan.h
include/linux/input.h
include/linux/ipmi.h
include/linux/ipmi_msgdefs.h
include/linux/ipmi_smi.h
include/linux/ipv6.h
include/linux/iso_fs.h
include/linux/iso_fs_i.h
include/linux/ixjuser.h
include/linux/kmod.h
include/linux/mca.h
include/linux/mempolicy.h
include/linux/mii.h
include/linux/miscdevice.h
include/linux/mm.h
include/linux/mqueue.h
include/linux/mroute.h
include/linux/netdevice.h
include/linux/netfilter.h
include/linux/netfilter_arp/arp_tables.h
include/linux/netfilter_ipv4/ip_tables.h
include/linux/netfilter_ipv6/ip6_tables.h
include/linux/nfs4_mount.h
include/linux/nfs_fs.h
include/linux/nfsd/export.h
include/linux/nfsd/nfsd.h
include/linux/nfsd/xdr3.h
include/linux/page-flags.h
include/linux/pci_ids.h
include/linux/pkt_sched.h
include/linux/prctl.h
include/linux/raid/md_k.h
include/linux/raid/raid1.h
include/linux/reiserfs_fs.h
include/linux/reiserfs_fs_i.h
include/linux/sched.h
include/linux/sdla.h
include/linux/security.h
include/linux/serial_core.h
include/linux/serio.h
include/linux/signal.h
include/linux/skbuff.h
include/linux/stat.h
include/linux/sunrpc/svcauth.h
include/linux/syscalls.h
include/linux/tcp.h
include/linux/time.h
include/linux/udf_fs.h
include/linux/usb.h
include/linux/watchdog.h
include/linux/wavefront.h
include/net/ax25.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/rfcomm.h
include/net/dn_dev.h
include/net/dst.h
include/net/ip.h
include/net/ip6_route.h
include/net/ipv6.h
include/net/irda/irda_device.h
include/net/netrom.h
include/net/rose.h
include/net/sctp/command.h
include/net/sctp/sm.h
include/net/sctp/structs.h
include/net/sctp/user.h
include/net/sock.h
include/net/tcp.h
include/net/tux.h
include/net/x25.h
include/net/xfrm.h
include/scsi/scsi_eh.h
include/scsi/scsi_host.h
include/scsi/scsi_ioctl.h
include/sound/ainstr_gf1.h
include/sound/ainstr_iw.h
include/sound/ainstr_simple.h
include/sound/asound.h
include/sound/core.h
include/sound/emu10k1.h
include/sound/emux_synth.h
include/sound/gus.h
include/sound/hdsp.h
include/sound/hwdep.h
include/sound/info.h
include/sound/pcm.h
include/sound/seq_instr.h
include/sound/seq_kernel.h
include/sound/sscape_ioctl.h
include/sound/trident.h
include/sound/vx_core.h
include/sound/wavefront.h
include/video/sisfb.h
init/Kconfig
init/main.c
ipc/mqueue.c
ipc/shm.c
ipc/util.c
kernel/acct.c
kernel/compat.c
kernel/exit.c
kernel/fork.c
kernel/futex.c
kernel/kmod.c
kernel/module.c
kernel/posix-timers.c
kernel/power/pmdisk.c
kernel/power/swsusp.c
kernel/resource.c
kernel/sched.c
kernel/signal.c
kernel/sysctl.c
kernel/timer.c
kernel/uid16.c
kernel/user.c
kernel/workqueue.c
lib/idr.c
lib/rwsem.c
lib/string.c
lib/vsprintf.c
mm/filemap.c
mm/fremap.c
mm/highmem.c
mm/hugetlb.c
mm/memory.c
mm/mempolicy.c
mm/mempool.c
mm/mincore.c
mm/mlock.c
mm/mmap.c
mm/mprotect.c
mm/mremap.c
mm/msync.c
mm/nommu.c
mm/oom_kill.c
mm/page-writeback.c
mm/page_alloc.c
mm/rmap.c
mm/shmem.c
mm/swap_state.c
mm/truncate.c
mm/vmalloc.c
mm/vmscan.c
net/8021q/vlan.c
net/appletalk/ddp.c
net/atm/addr.c
net/atm/addr.h
net/atm/br2684.c
net/atm/common.c
net/atm/common.h
net/atm/ioctl.c
net/atm/lec.c
net/atm/lec.h
net/atm/mpc.c
net/atm/mpc.h
net/atm/mpoa_proc.c
net/atm/pppoatm.c
net/atm/proc.c
net/atm/resources.c
net/atm/resources.h
net/ax25/af_ax25.c
net/ax25/ax25_route.c
net/bluetooth/bnep/sock.c
net/bluetooth/cmtp/cmtp.h
net/bluetooth/cmtp/sock.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_sock.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/rfcomm/tty.c
net/bluetooth/sco.c
net/bridge/br.c
net/bridge/br_if.c
net/bridge/br_ioctl.c
net/bridge/br_netfilter.c
net/bridge/br_private.h
net/bridge/br_sysfs_br.c
net/bridge/br_sysfs_if.c
net/core/Makefile
net/core/dev.c
net/core/dst.c
net/core/ethtool.c
net/core/iovec.c
net/core/net-sysfs.c
net/core/netfilter.c
net/core/pktgen.c
net/core/sock.c
net/decnet/af_decnet.c
net/decnet/dn_dev.c
net/decnet/dn_route.c
net/decnet/sysctl_net_decnet.c
net/econet/af_econet.c
net/ipv4/ah4.c
net/ipv4/esp4.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ipcomp.c
net/ipv4/ipmr.c
net/ipv4/ipvs/ip_vs_core.c
net/ipv4/ipvs/ip_vs_ctl.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv4/netfilter/ip_conntrack_proto_tcp.c
net/ipv4/netfilter/ip_fw_compat.c
net/ipv4/netfilter/ip_nat_standalone.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_ECN.c
net/ipv4/netfilter/ipt_TCPMSS.c
net/ipv4/netfilter/ipt_recent.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_diag.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_output.c
net/ipv4/tcp_timer.c
net/ipv4/udp.c
net/ipv4/xfrm4_tunnel.c
net/ipv6/ah6.c
net/ipv6/datagram.c
net/ipv6/esp6.c
net/ipv6/exthdrs.c
net/ipv6/ip6_input.c
net/ipv6/ip6_output.c
net/ipv6/ipcomp6.c
net/ipv6/mcast.c
net/ipv6/ndisc.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/raw.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/ipx/af_ipx.c
net/ipx/ipx_route.c
net/irda/af_irda.c
net/irda/ircomm/ircomm_tty_ioctl.c
net/irda/irda_device.c
net/irda/irlmp.c
net/irda/irnet/irnet_ppp.c
net/irda/irnet/irnet_ppp.h
net/irda/irsysctl.c
net/key/af_key.c
net/netlink/af_netlink.c
net/netlink/netlink_dev.c
net/netrom/af_netrom.c
net/netrom/nr_route.c
net/packet/af_packet.c
net/rose/af_rose.c
net/rose/rose_route.c
net/sched/sch_cbq.c
net/sched/sch_delay.c
net/sched/sch_hfsc.c
net/sched/sch_htb.c
net/sched/sch_tbf.c
net/sctp/sm_make_chunk.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sctp/sysctl.c
net/socket.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/svcauth.c
net/sunrpc/svcauth_unix.c
net/sunrpc/svcsock.c
net/sunrpc/xprt.c
net/wanrouter/af_wanpipe.c
net/wanrouter/wanmain.c
net/x25/af_x25.c
net/x25/x25_link.c
net/x25/x25_route.c
scripts/basic/.docproc.cmd
scripts/basic/.fixdep.cmd
scripts/basic/.split-include.cmd
scripts/basic/docproc
scripts/basic/fixdep
scripts/basic/split-include
scripts/checkstack.pl
scripts/kconfig/.conf.o.cmd
scripts/kconfig/.mconf.o.cmd
scripts/kconfig/.zconf.tab.o.cmd
scripts/kconfig/conf
scripts/kconfig/conf.o
scripts/kconfig/libkconfig.so
scripts/kconfig/mconf.o
scripts/kconfig/zconf.tab.o
scripts/reference_init.pl
security/dummy.c
security/selinux/Makefile
security/selinux/hooks.c
security/selinux/include/av_inherit.h
security/selinux/include/av_perm_to_string.h
security/selinux/include/av_permissions.h
security/selinux/include/class_to_string.h
security/selinux/include/flask.h
security/selinux/include/security.h
security/selinux/selinuxfs.c
security/selinux/ss/mls.c
security/selinux/ss/policydb.c
security/selinux/ss/services.c
sound/core/control.c
sound/core/hwdep.c
sound/core/info.c
sound/core/memory.c
sound/core/oss/mixer_oss.c
sound/core/oss/pcm_oss.c
sound/core/pcm.c
sound/core/pcm_lib.c
sound/core/pcm_native.c
sound/core/rawmidi.c
sound/core/seq/Makefile
sound/core/seq/instr/Makefile
sound/core/seq/instr/ainstr_fm.c
sound/core/seq/instr/ainstr_gf1.c
sound/core/seq/instr/ainstr_iw.c
sound/core/seq/instr/ainstr_simple.c
sound/core/seq/oss/seq_oss.c
sound/core/seq/oss/seq_oss_ioctl.c
sound/core/seq/seq_clientmgr.c
sound/core/seq/seq_memory.c
sound/core/timer.c
sound/drivers/mpu401/mpu401.c
sound/drivers/opl3/opl3_lib.c
sound/drivers/opl3/opl3_synth.c
sound/drivers/opl4/opl4_proc.c
sound/isa/Kconfig
sound/isa/cs423x/Makefile
sound/isa/gus/gus_dram.c
sound/isa/gus/gus_instr.c
sound/isa/gus/gus_mem_proc.c
sound/isa/gus/gus_pcm.c
sound/isa/sb/emu8000_patch.c
sound/isa/sb/emu8000_pcm.c
sound/isa/sb/sb16_csp.c
sound/isa/sscape.c
sound/isa/wavefront/wavefront_fx.c
sound/isa/wavefront/wavefront_synth.c
sound/oss/ad1889.c
sound/oss/ali5455.c
sound/oss/awe_wave.c
sound/oss/btaudio.c
sound/oss/cmpci.c
sound/oss/cs4281/cs4281m.c
sound/oss/cs46xx.c
sound/oss/dmasound/dmasound_atari.c
sound/oss/emu10k1/audio.c
sound/oss/emu10k1/cardwi.c
sound/oss/emu10k1/cardwi.h
sound/oss/emu10k1/cardwo.c
sound/oss/emu10k1/cardwo.h
sound/oss/emu10k1/midi.c
sound/oss/emu10k1/mixer.c
sound/oss/emu10k1/passthrough.c
sound/oss/emu10k1/passthrough.h
sound/oss/es1370.c
sound/oss/es1371.c
sound/oss/esssolo1.c
sound/oss/forte.c
sound/oss/i810_audio.c
sound/oss/kahlua.c
sound/oss/maestro.c
sound/oss/maestro3.c
sound/oss/msnd.c
sound/oss/msnd.h
sound/oss/msnd_pinnacle.c
sound/oss/opl3.c
sound/oss/rme96xx.c
sound/oss/sb_audio.c
sound/oss/sb_card.c
sound/oss/sb_common.c
sound/oss/sonicvibes.c
sound/oss/trident.c
sound/oss/wavfront.c
sound/oss/ymfpci.c
sound/pci/cs4281.c
sound/pci/cs46xx/cs46xx_lib.c
sound/pci/cs46xx/dsp_spos_scb_lib.c
sound/pci/emu10k1/emufx.c
sound/pci/emu10k1/emuproc.c
sound/pci/es1938.c
sound/pci/korg1212/korg1212.c
sound/pci/mixart/mixart.c
sound/pci/nm256/nm256.c
sound/pci/rme32.c
sound/pci/rme96.c
sound/pci/rme9652/hdsp.c
sound/pci/rme9652/rme9652.c
sound/pci/trident/trident_memory.c
sound/pci/trident/trident_synth.c
sound/pci/vx222/vx222_ops.c
sound/pcmcia/vx/vxp_ops.c
sound/synth/emux/soundfont.c

diff --git a/.config b/.config
index de7e3e7..7445bef 100644 (file)
--- a/.config
+++ b/.config
@@ -12,6 +12,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_STANDALONE=y
+CONFIG_BROKEN_ON_SMP=y
 
 #
 # General setup
@@ -20,8 +21,10 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
 CONFIG_LOG_BUF_SHIFT=17
 CONFIG_HOTPLUG=y
 # CONFIG_IKCONFIG is not set
@@ -45,21 +48,19 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
 
 #
 # Processor type and features
 #
-# CONFIG_X86_PC is not set
+CONFIG_X86_PC=y
 # CONFIG_X86_ELAN is not set
 # CONFIG_X86_VOYAGER is not set
 # CONFIG_X86_NUMAQ is not set
 # CONFIG_X86_SUMMIT is not set
 # CONFIG_X86_BIGSMP is not set
 # CONFIG_X86_VISWS is not set
-CONFIG_X86_GENERICARCH=y
+# CONFIG_X86_GENERICARCH is not set
 # CONFIG_X86_ES7000 is not set
-CONFIG_X86_CYCLONE_TIMER=y
 # CONFIG_M386 is not set
 # CONFIG_M486 is not set
 # CONFIG_M586 is not set
@@ -99,16 +100,12 @@ CONFIG_X86_UACCESS_INDIRECT=y
 CONFIG_X86_HIGH_ENTRY=y
 CONFIG_HPET_TIMER=y
 CONFIG_HPET_EMULATE_RTC=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=32
-CONFIG_SCHED_SMT=y
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
-CONFIG_X86_LOCAL_APIC=y
-CONFIG_X86_IO_APIC=y
+# CONFIG_X86_UP_APIC is not set
 CONFIG_X86_TSC=y
 CONFIG_X86_MCE=y
 # CONFIG_X86_MCE_NONFATAL is not set
-CONFIG_X86_MCE_P4THERMAL=y
 CONFIG_TOSHIBA=m
 CONFIG_I8K=m
 CONFIG_MICROCODE=m
@@ -120,17 +117,13 @@ CONFIG_X86_CPUID=m
 #
 CONFIG_EDD=m
 # CONFIG_NOHIGHMEM is not set
-# CONFIG_HIGHMEM4G is not set
-CONFIG_HIGHMEM64G=y
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
 CONFIG_HIGHMEM=y
-CONFIG_X86_PAE=y
-# CONFIG_NUMA is not set
 CONFIG_HIGHPTE=y
 # CONFIG_MATH_EMULATION is not set
 CONFIG_MTRR=y
 # CONFIG_EFI is not set
-# CONFIG_IRQBALANCE is not set
-CONFIG_HAVE_DEC_LOCK=y
 CONFIG_REGPARM=y
 
 #
@@ -220,7 +213,6 @@ CONFIG_PCI_GOANY=y
 CONFIG_PCI_BIOS=y
 CONFIG_PCI_DIRECT=y
 CONFIG_PCI_MMCONFIG=y
-CONFIG_PCI_USE_VECTOR=y
 CONFIG_PCI_LEGACY_PROC=y
 # CONFIG_PCI_NAMES is not set
 CONFIG_ISA=y
@@ -247,7 +239,6 @@ CONFIG_HOTPLUG_PCI=y
 # CONFIG_HOTPLUG_PCI_FAKE is not set
 CONFIG_HOTPLUG_PCI_COMPAQ=m
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
-CONFIG_HOTPLUG_PCI_IBM=m
 # CONFIG_HOTPLUG_PCI_ACPI is not set
 # CONFIG_HOTPLUG_PCI_CPCI is not set
 CONFIG_HOTPLUG_PCI_PCIE=m
@@ -260,7 +251,7 @@ CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_MISC=m
+CONFIG_BINFMT_MISC=y
 
 #
 # Device Drivers
@@ -413,7 +404,6 @@ CONFIG_BLK_DEV_IDE=y
 # CONFIG_BLK_DEV_HD_IDE is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECS=m
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDETAPE=m
@@ -505,6 +495,7 @@ CONFIG_SCSI_FC_ATTRS=m
 # SCSI low-level drivers
 #
 CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
 # CONFIG_SCSI_7000FASST is not set
 CONFIG_SCSI_ACARD=m
 CONFIG_SCSI_AHA152X=m
@@ -541,7 +532,6 @@ CONFIG_SCSI_SATA_VIA=m
 CONFIG_SCSI_SATA_VITESSE=m
 CONFIG_SCSI_BUSLOGIC=m
 # CONFIG_SCSI_OMIT_FLASHPOINT is not set
-# CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_EATA is not set
@@ -612,6 +602,9 @@ CONFIG_MD_RAID6=m
 CONFIG_MD_MULTIPATH=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
 
 #
 # Fusion MPT device support
@@ -963,10 +956,12 @@ CONFIG_ACT200L_DONGLE=m
 #
 # Old SIR device drivers
 #
+CONFIG_IRPORT_SIR=m
 
 #
 # Old Serial dongle support
 #
+# CONFIG_DONGLE_OLD is not set
 
 #
 # FIR device drivers
@@ -1049,6 +1044,7 @@ CONFIG_WD80x3=m
 CONFIG_ULTRA=m
 CONFIG_SMC9194=m
 CONFIG_NET_VENDOR_RACAL=y
+# CONFIG_NI5010 is not set
 CONFIG_NI52=m
 CONFIG_NI65=m
 
@@ -1065,6 +1061,7 @@ CONFIG_DE4X5=m
 CONFIG_WINBOND_840=m
 CONFIG_DM9102=m
 CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_PCMCIA_XIRTULIP is not set
 # CONFIG_AT1700 is not set
 CONFIG_DEPCA=m
 CONFIG_HP100=m
@@ -1102,15 +1099,15 @@ CONFIG_SUNDANCE=m
 CONFIG_TLAN=m
 CONFIG_VIA_RHINE=m
 CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_VELOCITY=m
 CONFIG_NET_POCKET=y
 CONFIG_ATP=m
 CONFIG_DE600=m
 CONFIG_DE620=m
 
 #
-# Gigabit Ethernet (1000/10000 Mbit)
+# Ethernet (1000 Mbit)
 #
-CONFIG_NET_GIGE=y
 CONFIG_ACENIC=m
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
 CONFIG_DL2K=m
@@ -1122,6 +1119,10 @@ CONFIG_YELLOWFIN=m
 CONFIG_R8169=m
 CONFIG_SK98LIN=m
 CONFIG_TIGON3=m
+
+#
+# Ethernet (10000 Mbit)
+#
 CONFIG_IXGB=m
 CONFIG_IXGB_NAPI=y
 CONFIG_S2IO=m
@@ -1231,6 +1232,7 @@ CONFIG_ISDN_TTY_FAX=y
 #
 # ISDN feature submodules
 #
+CONFIG_ISDN_DRV_LOOP=m
 
 #
 # ISDN4Linux hardware drivers
@@ -1310,6 +1312,8 @@ CONFIG_ISDN_DRV_PCBIT=m
 CONFIG_ISDN_DRV_SC=m
 CONFIG_ISDN_DRV_ACT2000=m
 CONFIG_ISDN_DRV_TPAM=m
+CONFIG_HYSDN=m
+CONFIG_HYSDN_CAPI=y
 
 #
 # CAPI subsystem
@@ -1330,6 +1334,14 @@ CONFIG_ISDN_CAPI_CAPIDRV=m
 # Active AVM cards
 #
 CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1ISA=m
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_T1ISA=m
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
 
 #
 # Active Eicon DIVA Server cards
@@ -1437,12 +1449,25 @@ CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
 CONFIG_ROCKETPORT=m
 # CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
 CONFIG_SYNCLINK=m
 CONFIG_SYNCLINKMP=m
 CONFIG_N_HDLC=m
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
 CONFIG_STALDRV=y
+# CONFIG_STALLION is not set
+# CONFIG_ISTALLION is not set
 
 #
 # Serial drivers
@@ -1539,6 +1564,7 @@ CONFIG_SONYPI=m
 #
 # Ftape, the floppy tape device driver
 #
+# CONFIG_FTAPE is not set
 CONFIG_AGP=y
 CONFIG_AGP_ALI=y
 CONFIG_AGP_ATI=y
@@ -1567,6 +1593,7 @@ CONFIG_DRM_SIS=m
 CONFIG_SYNCLINK_CS=m
 CONFIG_MWAVE=m
 # CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
 CONFIG_HANGCHECK_TIMER=m
 
 #
@@ -1589,6 +1616,7 @@ CONFIG_I2C_ALI1563=m
 CONFIG_I2C_ALI15X3=m
 CONFIG_I2C_AMD756=m
 CONFIG_I2C_AMD8111=m
+# CONFIG_I2C_ELEKTOR is not set
 CONFIG_I2C_I801=m
 CONFIG_I2C_I810=m
 CONFIG_I2C_ISA=m
@@ -1675,6 +1703,7 @@ CONFIG_VIDEO_ZORAN_DC10=m
 CONFIG_VIDEO_ZORAN_DC30=m
 CONFIG_VIDEO_ZORAN_LML33=m
 CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_MEYE=m
 CONFIG_VIDEO_SAA7134=m
 CONFIG_VIDEO_MXB=m
 CONFIG_VIDEO_DPC=m
@@ -1704,7 +1733,52 @@ CONFIG_RADIO_ZOLTRIX=m
 #
 # Digital Video Broadcasting Devices
 #
-# CONFIG_DVB is not set
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported Frontend Modules
+#
+CONFIG_DVB_TWINHAN_DST=m
+CONFIG_DVB_STV0299=m
+# CONFIG_DVB_SP887X is not set
+# CONFIG_DVB_ALPS_TDLB7 is not set
+CONFIG_DVB_ALPS_TDMB7=m
+CONFIG_DVB_ATMEL_AT76C651=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_GRUNDIG_29504_491=m
+CONFIG_DVB_GRUNDIG_29504_401=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_VES1X93=m
+# CONFIG_DVB_TDA1004X is not set
+CONFIG_DVB_NXT6000=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_SKYSTAR=m
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
 CONFIG_VIDEO_SAA7146=m
 CONFIG_VIDEO_SAA7146_VV=m
 CONFIG_VIDEO_VIDEOBUF=m
@@ -1727,6 +1801,7 @@ CONFIG_VIDEO_SELECT=y
 CONFIG_FB_HGA=m
 CONFIG_FB_HGA_ACCEL=y
 CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
 CONFIG_FB_I810=m
 CONFIG_FB_I810_GTF=y
 CONFIG_FB_MATROX=m
@@ -1937,6 +2012,7 @@ CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=m
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_RW_DETECT=y
 CONFIG_USB_STORAGE_DATAFAB=y
 CONFIG_USB_STORAGE_FREECOM=y
 CONFIG_USB_STORAGE_ISD200=y
@@ -2028,6 +2104,7 @@ CONFIG_USB_USS720=m
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
 CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
 CONFIG_USB_SERIAL_EMPEG=m
 CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -2223,7 +2300,6 @@ CONFIG_MINIX_SUBPARTITION=y
 CONFIG_SOLARIS_X86_PARTITION=y
 CONFIG_UNIXWARE_DISKLABEL=y
 # CONFIG_LDM_PARTITION is not set
-# CONFIG_NEC98_PARTITION is not set
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 CONFIG_SUN_PARTITION=y
@@ -2275,8 +2351,7 @@ CONFIG_NLS_UTF8=m
 #
 # Profiling support
 #
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
+# CONFIG_PROFILING is not set
 
 #
 # Kernel hacking
@@ -2293,8 +2368,6 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_FRAME_POINTER is not set
-CONFIG_X86_FIND_SMP_CONFIG=y
-CONFIG_X86_MPPARSE=y
 
 #
 # Security options
@@ -2340,9 +2413,5 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
-CONFIG_X86_SMP=y
-CONFIG_X86_HT=y
 CONFIG_X86_BIOS_REBOOT=y
-CONFIG_X86_TRAMPOLINE=y
-CONFIG_X86_STD_RESOURCES=y
 CONFIG_PC=y
index a1d48d7..ef6ee16 100644 (file)
@@ -4,9 +4,10 @@
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_GENERIC_ISA_DMA=y
-CONFIG_SMP=y
+# CONFIG_SMP is not set
 # CONFIG_HOTPLUG_CPU is not set
 CONFIG_SCHED_SMT=y
+# CONFIG_HPET is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@ CONFIG_STANDALONE=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_IKCONFIG is not set
@@ -147,7 +149,7 @@ CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_MISC=m
+CONFIG_BINFMT_MISC=y
 
 #
 # Device Drivers
@@ -392,6 +394,7 @@ CONFIG_SCSI_FC_ATTRS=y
 # SCSI low-level drivers
 #
 CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
 # CONFIG_SCSI_7000FASST is not set
 CONFIG_SCSI_ACARD=m
 CONFIG_SCSI_AHA152X=m
@@ -503,6 +506,9 @@ CONFIG_MD_RAID5=m
 CONFIG_MD_RAID6=m
 CONFIG_MD_MULTIPATH=m
 CONFIG_BLK_DEV_DM=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
 CONFIG_DM_CRYPT=m
 
 #
@@ -860,7 +866,7 @@ CONFIG_PCMCIA_XIRCOM=m
 CONFIG_DEPCA=m
 CONFIG_HP100=m
 # CONFIG_NET_ISA is not set
-# CONFIG_EWRK3 is not set
+CONFIG_EWRK3=m
 CONFIG_E2100=m
 CONFIG_EEXPRESS=m
 CONFIG_EEXPRESS_PRO=m
@@ -907,6 +913,7 @@ CONFIG_SUNDANCE=m
 CONFIG_TLAN=m
 CONFIG_VIA_RHINE=m
 CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_VELOCITY=m
 CONFIG_NET_POCKET=y
 CONFIG_ATP=m
 CONFIG_DE600=m
@@ -1585,7 +1592,7 @@ CONFIG_RADIO_ZOLTRIX=m
 #
 # Digital Video Broadcasting Devices
 #
-# CONFIG_DVB is not set
+CONFIG_DVB=y
 CONFIG_DVB_CORE=m
 
 #
@@ -1646,6 +1653,7 @@ CONFIG_FB_VESA=y
 CONFIG_VIDEO_SELECT=y
 CONFIG_FB_HGA=m
 CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
 CONFIG_FB_I810=m
 CONFIG_FB_I810_GTF=y
 CONFIG_FB_MATROX=m
@@ -1863,6 +1871,7 @@ CONFIG_USB_STORAGE_HP8200e=y
 CONFIG_USB_STORAGE_SDDR09=y
 CONFIG_USB_STORAGE_SDDR55=y
 CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_RW_DETECT=y
 
 #
 # USB Human Interface Devices (HID)
@@ -2209,8 +2218,8 @@ CONFIG_NLS_UTF8=m
 #
 # Profiling support
 #
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
+# CONFIG_PROFILING is not set
+# CONFIG_OPROFILE is not set
 
 #
 # Tux
@@ -2251,7 +2260,7 @@ CONFIG_SECURITY_SELINUX_BOOTPARAM=y
 CONFIG_SECURITY_SELINUX_DISABLE=y
 CONFIG_SECURITY_SELINUX_DEVELOP=y
 # CONFIG_SECURITY_SELINUX_MLS is not set
-# CONFIG_AUDIT is not set
+CONFIG_AUDIT=y
 CONFIG_AUDITSYSCALL=y
 
 #
@@ -2286,14 +2295,14 @@ CONFIG_CRC32=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_PC=y
-# CONFIG_X86_PC is not set
+CONFIG_X86_PC=y
 # CONFIG_X86_ELAN is not set
 # CONFIG_X86_VOYAGER is not set
 # CONFIG_X86_NUMAQ is not set
 # CONFIG_X86_SUMMIT is not set
 # CONFIG_X86_BIGSMP is not set
 # CONFIG_X86_VISWS is not set
-CONFIG_X86_GENERICARCH=y
+# CONFIG_X86_GENERICARCH is not set
 # CONFIG_X86_ES7000 is not set
 # CONFIG_M386 is not set
 # CONFIG_M486 is not set
@@ -2329,7 +2338,7 @@ CONFIG_X86_INTEL_USERCOPY=y
 CONFIG_X86_USE_PPRO_CHECKSUM=y
 CONFIG_HPET_TIMER=y
 CONFIG_HPET_EMULATE_RTC=y
-CONFIG_NR_CPUS=32
+CONFIG_NR_CPUS=8
 CONFIG_X86_LOCAL_APIC=y
 CONFIG_X86_IO_APIC=y
 CONFIG_X86_TSC=y
@@ -2345,7 +2354,6 @@ CONFIG_X86_CPUID=m
 CONFIG_EDD=m
 # CONFIG_NOHIGHMEM is not set
 CONFIG_HIGHMEM4G=y
-CONFIG_HIGHMEM64G=y
 # CONFIG_HIGHMEM64G is not set
 CONFIG_HIGHMEM=y
 CONFIG_HIGHPTE=y
@@ -2404,12 +2412,8 @@ CONFIG_NVRAM=m
 CONFIG_IBM_ASM=m
 CONFIG_M686=y
 # CONFIG_NOHIGHMEM is not set
-CONFIG_HIGHMEM64G=y
-CONFIG_HOTPLUG_PCI=y
-CONFIG_HOTPLUG_PCI_COMPAQ=m
-CONFIG_HOTPLUG_PCI_IBM=m
+# CONFIG_SMP is not set
+CONFIG_HIGHMEM4G=y
 # CONFIG_HIGHMEM64G is not set
-# CONFIG_EWRK3 is not set
-CONFIG_NR_CPUS=32
-# CONFIG_X86_PC is not set
-CONFIG_X86_GENERICARCH=y
+# CONFIG_PROFILING is not set
+# CONFIG_OPROFILE is not set
diff --git a/CREDITS b/CREDITS
index 9eb5b85..ebaff39 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -2571,6 +2571,14 @@ P: 1024D/EDBB6147 7B36 0E07 04BC 11DC A7A0  D3F7 7185 9E7A EDBB 6147
 D: sonypi, meye drivers, mct_u232 usb serial hacks
 S: Paris, France
 
+N: Matt Porter
+E: mporter@kernel.crashing.org
+D: Motorola PowerPC PReP support
+D: cPCI PowerPC support
+D: Embedded PowerPC 4xx/6xx/7xx/74xx support
+S: Chandler, Arizona 85249
+S: USA
+
 N: Frederic Potter 
 E: fpotter@cirpack.com
 D: Some PCI kernel support
@@ -3109,12 +3117,13 @@ S: Beaverton, Oregon 97005
 S: USA
 
 N: Marcelo W. Tosatti
-E: marcelo@conectiva.com.br
-W: http://bazar.conectiva.com.br/~marcelo/
-D: Miscellaneous kernel hacker (mostly VM/MM work)
-S: Conectiva S.A.
-S: R. Tocantins, 89 - Cristo Rei
-S: 80050-430 - Curitiba - Paraná
+E: marcelo.tosatti@cyclades.com
+D: Miscellaneous kernel hacker
+D: v2.4 kernel maintainer
+D: Current pc300/cyclades maintainer
+S: Cyclades Corporation
+S: Av Cristovao Colombo, 462. Floresta.
+S: Porto Alegre
 S: Brazil
 
 N: Stefan Traby
index 967ce6c..4b1c93a 100644 (file)
@@ -1,7 +1,7 @@
                Kernel Memory Layout on ARM Linux
 
                Russell King <rmk@arm.linux.org.uk>
-                       April 27, 2003 (2.5.68)
+                       May 21, 2004 (2.6.6)
 
 This document describes the virtual memory layout which the Linux
 kernel uses for ARM processors.  It indicates which regions are
@@ -29,32 +29,30 @@ ffff0000    ffff0fff        CPU vector page.
                                CPU supports vector relocation (control
                                register V bit.)
 
-ffe00000       fffeffff        Free for platform use, not recommended.
+ffc00000       fffeffff        DMA memory mapping region.  Memory returned
+                               by the dma_alloc_xxx functions will be
+                               dynamically mapped here.
 
-ffc00000       ffdfffff        2MB consistent memory mapping.
-                               Memory returned by the consistent_alloc
-                               low level function will be dynamically
-                               mapped here.
+ff000000       ffbfffff        Reserved for future expansion of DMA
+                               mapping region.
 
-ff000000       ffbfffff        Free for platform use, not recommended.
+VMALLOC_END    feffffff        Free for platform use, recommended.
 
-VMALLOC_END    ff000000        Free for platform use, recommended.
-
-VMALLOC_START  VMALLOC_END     vmalloc() / ioremap() space.
+VMALLOC_START  VMALLOC_END-1   vmalloc() / ioremap() space.
                                Memory returned by vmalloc/ioremap will
                                be dynamically placed in this region.
                                VMALLOC_START may be based upon the value
                                of the high_memory variable.
 
-PAGE_OFFSET    high_memory     Kernel direct-mapped RAM region.
+PAGE_OFFSET    high_memory-1   Kernel direct-mapped RAM region.
                                This maps the platforms RAM, and typically
                                maps all platform RAM in a 1:1 relationship.
 
-TASK_SIZE      PAGE_OFFSET     Kernel module space
+TASK_SIZE      PAGE_OFFSET-1   Kernel module space
                                Kernel modules inserted via insmod are
                                placed here using dynamic mappings.
 
-00001000       TASK_SIZE       User space mappings
+00001000       TASK_SIZE-1     User space mappings
                                Per-thread mappings are placed here via
                                the mmap() system call.
 
index 3de8edb..d097f09 100644 (file)
@@ -15,7 +15,7 @@ First you must mount binfmt_misc:
        mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc 
 
 To actually register a new binary type, you have to set up a string looking like
-:name:type:offset:magic:mask:interpreter: (where you can choose the ':' upon
+:name:type:offset:magic:mask:interpreter:flags (where you can choose the ':' upon
 your needs) and echo it to /proc/sys/fs/binfmt_misc/register.
 Here is what the fields mean:
  - 'name' is an identifier string. A new /proc file will be created with this
@@ -34,6 +34,28 @@ Here is what the fields mean:
    The mask is anded with the byte sequence of the file.
  - 'interpreter' is the program that should be invoked with the binary as first
    argument (specify the full path)
+ - 'flags' is an optional field that controls several aspects of the invocation
+   of the interpreter. It is a string of capital letters, each controls a certain
+   aspect. The following flags are supported -
+      'P' - preserve-argv[0].  Legacy behavior of binfmt_misc is to overwrite the
+            original argv[0] with the full path to the binary.  When this flag is
+            included, binfmt_misc will add an argument to the argument vector for
+            this purpose, thus preserving the original argv[0].
+      'O' - open-binary. Legacy behavior of binfmt_misc is to pass the full path
+            of the binary to the interpreter as an argument. When this flag is
+            included, binfmt_misc will open the file for reading and pass its
+            descriptor as an argument, instead of the full path, thus allowing
+            the interpreter to execute non-readable binaries. This feature should
+            be used with care - the interpreter has to be trusted not to emit
+            the contents of the non-readable binary.
+      'C' - credentials. Currently, the behavior of binfmt_misc is to calculate
+            the credentials and security token of the new process according to
+            the interpreter. When this flag is included, these attributes are
+            calculated according to the binary. It also implies the 'O' flag.
+            This feature should be used with care as the interpreter
+            will run with root permissions when a setuid binary owned by root
+            is run with binfmt_misc.
+
 
 There are some restrictions:
  - the whole register string may not exceed 255 characters
@@ -83,9 +105,9 @@ If you want to pass special arguments to your interpreter, you can
 write a wrapper script for it. See Documentation/java.txt for an
 example.
 
-Your interpreter should NOT look in the PATH for the filename; the
-kernel passes it the full filename to use.  Using the PATH can cause
-unexpected behaviour and be a security hazard.
+Your interpreter should NOT look in the PATH for the filename; the kernel
+passes it the full filename (or the file descriptor) to use.  Using $PATH can
+cause unexpected behaviour and can be a security hazard.
 
 
 There is a web page about binfmt_misc at
index b8d0b78..610e780 100644 (file)
@@ -190,7 +190,7 @@ We'll say that the horizontal scanrate is about 31 kHz:
     1/(32.141E-6 s) = 31.113E3 Hz
 
 A full screen counts 480 (yres) lines, but we have to consider the vertical
-retrace too (e.g. 49 `pixels'). So a full screen will take
+retrace too (e.g. 49 `lines'). So a full screen will take
 
     (480+49)*32.141E-6 s = 17.002E-3 s
 
index 548dcf4..31047e0 100644 (file)
@@ -32,7 +32,7 @@ tree.  This means that if any filesystem object is in the dcache, then
 all of the ancestors of that filesystem object are also in the dcache.
 As normal access is by filename this prefix is created naturally and
 maintained easily (by each object maintaining a reference count on
-it's parent).
+its parent).
 
 However when objects are included into the dcache by interpreting a
 filehandle fragment, there is no automatic creation of a path prefix
@@ -44,15 +44,15 @@ the dcache that are not needed for normal filesystem access.
 2/ The dcache must be prepared for a newly found (via ->lookup) directory
    to already have a (non-connected) dentry, and must be able to move
    that dentry into place (based on the parent and name in the
-   ->lookup).   This is particuarly needed for directories as
+   ->lookup).   This is particularly needed for directories as
    it is a dcache invariant that directories only have one dentry.
 
 To implement these features, the dcache has:
 
-a/ A dentry flag  DCACHE_DISCONNECTED which is set on
-   and dentry that might not be part of the proper prefix.
+a/ A dentry flag DCACHE_DISCONNECTED which is set on
+   any dentry that might not be part of the proper prefix.
    This is set when anonymous dentries are created, and cleared when a
-   dentry is noticed to be a child on a dentry which is in the proper
+   dentry is noticed to be a child of a dentry which is in the proper
    prefix. 
 
 b/ A per-superblock list "s_anon" of dentries which are the roots of
@@ -123,9 +123,9 @@ filesystem:
   get_name.  When given a parent dentry and a child dentry, this
     should find a name in the directory identified by the parent
     dentry, which leads to the object identified by the child dentry.
-    If no get_name function is supplied, a default implementation
-    which used vfs_readdir to find potential names, and matches inode
-    numbers to find the correct match.
+    If no get_name function is supplied, a default implementation is
+    provided which uses vfs_readdir to find potential names, and
+    matches inode numbers to find the correct match.
 
   get_parent.  When given a dentry for a directory, this should return 
     a dentry for the parent.  Quite possibly the parent dentry will
@@ -135,7 +135,7 @@ filesystem:
     ->lookup("..") is *not* used as a default as it can leave ".."
     entries in the dcache which are too messy to work with.
 
-  get_dentry.  When given a opaque datum, this should find the
+  get_dentry.  When given an opaque datum, this should find the
     implied object and create a dentry for it (possibly with
     d_alloc_anon). 
     The opaque datum is whatever is passed down by the decode_fh
@@ -143,7 +143,7 @@ filesystem:
     fragment.
     decode_fh passes two datums through find_exported_dentry.  One that 
     should be used to identify the target object, and one that can be
-    used to identify the objects parent, should that be necessary.
+    used to identify the object's parent, should that be necessary.
     The default get_dentry function assumes that the datum contains an
     inode number and a generation number, and it attempts to get the
     inode using "iget" and check it's validity by matching the
@@ -164,8 +164,8 @@ filehandle assuming the format used by the default encode_fh and
 passed them to find_exported_dentry.
 
 
-A filehandle fragment consists of an array of 1 or more 4byte words.
-Together with a one byte "type".
+A filehandle fragment consists of an array of 1 or more 4byte words,
+together with a one byte "type".
 The decode_fh routine should not depend on the stated size that is
 passed to it.  This size may be larger than the original filehandle
 generated by encode_fh, in which case it will have been padded with
index 83e6a8f..e0ef1f8 100644 (file)
@@ -203,20 +203,34 @@ currently-in-progress I/O.
 
 If the filesystem is not called for "sync" and it determines that it
 would need to block against in-progress I/O to be able to start new I/O
-against the page the filesystem shoud redirty the page (usually with
-__set_page_dirty_nobuffers()), then unlock the page and return zero. 
+against the page the filesystem should redirty the page with
+redirty_page_for_writepage(), then unlock the page and return zero.
 This may also be done to avoid internal deadlocks, but rarely.
 
 If the filesytem is called for sync then it must wait on any
 in-progress I/O and then start new I/O.
 
 The filesystem should unlock the page synchronously, before returning
-to the caller.  If the page has write I/O underway against it,
-writepage() should run SetPageWriteback() against the page prior to
-unlocking it.  The write I/O completion handler should run
-end_page_writeback() against the page.
-
-That is: after 2.5.12, pages which are under writeout are *not* locked.
+to the caller.
+
+Unless the filesystem is going to redirty_page_for_writepage(), unlock the page
+and return zero, writepage *must* run set_page_writeback() against the page,
+followed by unlocking it.  Once set_page_writeback() has been run against the
+page, write I/O can be submitted and the write I/O completion handler must run
+end_page_writeback() once the I/O is complete.  If no I/O is submitted, the
+filesystem must run end_page_writeback() against the page before returning from
+writepage.
+
+That is: after 2.5.12, pages which are under writeout are *not* locked.  Note,
+if the filesystem needs the page to be locked during writeout, that is ok, too,
+the page is allowed to be unlocked at any point in time between the calls to
+set_page_writeback() and end_page_writeback().
+
+Note, failure to run either redirty_page_for_writepage() or the combination of
+set_page_writeback()/end_page_writeback() on a page submitted to writepage
+will leave the page itself marked clean but it will be tagged as dirty in the
+radix tree.  This incoherency can lead to all sorts of hard-to-debug problems
+in the filesystem like having dirty inodes at umount and losing written data.
 
        ->sync_page() locking rules are not well-defined - usually it is called
 with lock on page, but that is not guaranteed. Considering the currently
index 1cdc5d2..018ec96 100644 (file)
@@ -273,6 +273,21 @@ ChangeLog
 
 Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
 
+2.1.14:
+       - Fix an NFSd caused deadlock reported by several users.
+2.1.13:
+       - Implement writing of inodes (access time updates are not implemented
+         yet so mounting with -o noatime,nodiratime is enforced).
+       - Enable writing out of resident files so you can now overwrite any
+         uncompressed, unencrypted, nonsparse file as long as you do not
+         change the file size.
+       - Add housekeeping of ntfs system files so that ntfsfix no longer needs
+         to be run after writing to an NTFS volume.
+         NOTE:  This still leaves quota tracking and user space journalling on
+         the side but they should not cause data corruption.  In the worst
+         case the charged quotas will be out of date ($Quota) and some
+         userspace applications might get confused due to the out of date
+         userspace journal ($UsnJrnl).
 2.1.12:
        - Fix the second fix to the decompression engine from the 2.1.9 release
          and some further internals cleanups.
index 7dd9fc9..3993449 100644 (file)
@@ -201,7 +201,7 @@ Table 1-3: Kernel info in /proc
  devices     Available devices (block and character)           
  dma         Used DMS channels                                 
  filesystems Supported filesystems                             
- driver             Various drivers grouped here, currently rtc        (2.4)
+ driver             Various drivers grouped here, currently rtc (2.4) and hpet (2.6)
  execdomains Execdomains, related to security                  (2.4)
  fb         Frame Buffer devices                               (2.4)
  fs         File system parameters, currently nfs/exports      (2.4)
@@ -1632,7 +1632,8 @@ flush
 
 Writing to this file results in a flush of the routing cache.
 
-gc_elastic, gc_interval, gc_min_interval, gc_tresh, gc_timeout
+gc_elasticity, gc_interval, gc_min_interval, gc_tresh, gc_timeout,
+gc_thresh, gc_thresh1, gc_thresh2, gc_thresh3
 --------------------------------------------------------------
 
 Values to  control  the  frequency  and  behavior  of  the  garbage collection
index 07811d2..58853a4 100644 (file)
@@ -248,6 +248,13 @@ Summary of ide driver parameters for kernel command line
                          allowing ide-floppy, ide-tape, and ide-cdrom|writers
                          to use ide-scsi emulation on a device specific option.
 
+ "hdx=stroke"          : Should you have a system w/ an AWARD Bios and your
+                         drives are larger than 32GB and it will not boot,
+                         one is required to perform a few OEM operations first.
+                         The option is called "stroke" because it allows one
+                         to "soft clip" the drive to work around a barrier
+                         limit.
+
  "idebus=xx"           : inform IDE driver of VESA/PCI bus speed in MHz,
                          where "xx" is between 20 and 66 inclusive,
                          used when tuning chipset PIO modes.
index 1af5712..2be1218 100644 (file)
@@ -189,3 +189,5 @@ Code        Seq#    Include File            Comments
                                        <mailto:michael.klein@puffin.lb.shuttle.de>
 0xDD   00-3F   ZFCP device driver      see drivers/s390/scsi/
                                        <mailto:aherrman@de.ibm.com>
+0xF3   00-3F   video/sisfb.h           sisfb (in development)
+                                       <mailto:thomas@winischhofer.net>
index 591e458..c26a38a 100644 (file)
@@ -896,8 +896,8 @@ running once the system is up.
        psmouse.rate=   [HW,MOUSE] Set desired mouse report rate, in reports
                        per second.
        psmouse.resetafter=
-                       [HW,MOUSE] Try to reset Synaptics Touchpad after so many
-                       bad packets (0 = never).
+                       [HW,MOUSE] Try to reset the device after so many bad packets
+                       (0 = never).
        psmouse.resolution=
                        [HW,MOUSE] Set desired mouse resolution, in dpi.
        psmouse.smartscroll=
index 029e9c7..834993d 100644 (file)
@@ -4,8 +4,6 @@
        - information on the 3Com EtherLink Plus (3c505) driver.
 6pack.txt
        - info on the 6pack protocol, an alternative to KISS for AX.25
-8139too.txt
-       - info on the 8139too driver for RTL-8139 based network cards.
 Configurable
        - info on some of the configurable network parameters
 DLINK.txt
index 708e12a..10304b4 100644 (file)
@@ -17,6 +17,16 @@ ip_no_pmtu_disc - BOOLEAN
        Disable Path MTU Discovery.
        default FALSE
 
+min_pmtu - INTEGER
+       default 562 - minimum discovered Path MTU
+
+mtu_expires - INTEGER
+       Time, in seconds, that cached PMTU information is kept.
+
+min_adv_mss - INTEGER
+       The advertised MSS depends on the first hop route MTU, but will
+       never be lower than this setting.
+
 IP Fragmentation:
 
 ipfrag_high_thresh - INTEGER
@@ -345,6 +355,20 @@ tcp_default_win_scale - INTEGER
        conections.
        Default: 7
 
+
+tcp_frto - BOOLEAN
+       Enables F-RTO, an enhanced recovery algorithm for TCP retransmission
+       timeouts.  It is particularly beneficial in wireless environments
+       where packet loss is typically due to random radio interference
+       rather than intermediate router congestion.
+
+somaxconn - INTEGER
+       Limit of socket listen() backlog, known in userspace as SOMAXCONN.
+       Defaults to 128.  See also tcp_max_syn_backlog for additional tuning
+       for TCP sockets.
+
+IP Variables:
+
 ip_local_port_range - 2 INTEGERS
        Defines the local port range that is used by TCP and UDP to
        choose the local port. The first number is the first, the 
@@ -586,6 +610,19 @@ arp_ignore - INTEGER
        The max value from conf/{all,interface}/arp_ignore is used
        when ARP request is received on the {interface}
 
+app_solicit - INTEGER
+       The maximum number of probes to send to the user space ARP daemon
+       via netlink before dropping back to multicast probes (see
+       mcast_solicit).  Defaults to 0.
+
+disable_policy - BOOLEAN
+       Disable IPSEC policy (SPD) for this interface
+
+disable_xfrm - BOOLEAN
+       Disable IPSEC encryption on this interface, whatever the policy
+
+
+
 tag - INTEGER
        Allows you to write a number, which can be used as required.
        Default value is 0.
@@ -678,9 +715,11 @@ accept_redirects - BOOLEAN
                            disabled if local forwarding is enabled.
 
 autoconf - BOOLEAN
-       Configure link-local addresses using L2 hardware addresses.
+       Autoconfigure addresses using Prefix Information in Router 
+       Advertisements.
 
-       Default: TRUE
+       Functional default: enabled if accept_ra is enabled.
+                           disabled if accept_ra is disabled.
 
 dad_transmits - INTEGER
        The amount of Duplicate Address Detection probes to send.
@@ -804,4 +843,25 @@ bridge-nf-filter-vlan-tagged - BOOLEAN
        Default: 1
 
 
+UNDOCUMENTED:
+
+dev_weight FIXME
+discovery_slots FIXME
+discovery_timeout FIXME
+fast_poll_increase FIXME
+ip6_queue_maxlen FIXME
+lap_keepalive_time FIXME
+lo_cong FIXME
+max_baud_rate FIXME
+max_dgram_qlen FIXME
+max_noreply_time FIXME
+max_tx_data_size FIXME
+max_tx_window FIXME
+min_tx_turn_time FIXME
+mod_cong FIXME
+no_cong FIXME
+no_cong_thresh FIXME
+slot_timeout FIXME
+warn_noreply_time FIXME
+
 $Id: ip-sysctl.txt,v 1.20 2001/12/13 09:00:18 davem Exp $
index 091b2d2..8d4cf78 100644 (file)
@@ -1,11 +1,3 @@
-
-DaveM:
-
-If you agree with it I will send two small patches to modify
-kernel's configure help. 
-
-       Ulisses
-
 --------------------------------------------------------------------------------
 + ABSTRACT
 --------------------------------------------------------------------------------
@@ -405,8 +397,3 @@ then poll for frames.
    
    Jesse Brandeburg, for fixing my grammathical/spelling errors
 
->>> EOF
--
-To unsubscribe from this list: send the line "unsubscribe linux-net" in
-the body of a message to majordomo@vger.kernel.org
-More majordomo info at  http://vger.kernel.org/majordomo-info.html
\ No newline at end of file
index 5f2455e..1b254cd 100644 (file)
@@ -90,6 +90,20 @@ M:   dave@thedillows.org
 L:     linux-net@vger.kernel.org
 S:     Maintained
 
+3W-XXXX ATA-RAID CONTROLLER DRIVER
+P:     Adam Radford
+M:     linuxraid@amcc.com
+L:     linux-scsi@vger.kernel.org
+W:     http://www.amcc.com
+S:     Supported
+
+3W-9XXX SATA-RAID CONTROLLER DRIVER
+P:     Adam Radford
+M:     linuxraid@amcc.com
+L:     linux-scsi@vger.kernel.org
+W:     http://www.amcc.com
+S:     Supported
+
 53C700 AND 53C700-66 SCSI DRIVER
 P:     James E.J. Bottomley
 M:     James.Bottomley@HansenPartnership.com
@@ -944,15 +958,15 @@ S:        Maintained
 IA64 (Itanium) PLATFORM
 P:     David Mosberger-Tang
 M:     davidm@hpl.hp.com
-L:     linux-ia64@linuxia64.org
-W:     http://www.linuxia64.org/
+L:     linux-ia64@vger.kernel.org
+W:     http://www.ia64-linux.org/
 S:     Maintained
 
 SN-IA64 (Itanium) SUB-PLATFORM
 P:     Jesse Barnes
 M:     jbarnes@sgi.com
 L:     linux-altix@sgi.com
-L:     linux-ia64@linuxia64.org
+L:     linux-ia64@vger.kernel.org
 W:     http://www.sgi.com/altix
 S:     Maintained
 
@@ -1251,6 +1265,13 @@ W:       http://www.linuxppc.org/
 L:     linuxppc-dev@lists.linuxppc.org
 S:     Maintained
 
+LINUX FOR POWERPC EMBEDDED PPC4XX
+P:     Matt Porter
+M:     mporter@kernel.crashing.org
+W:     http://www.penguinppc.org/
+L:     linuxppc-embedded@lists.linuxppc.org
+S:     Maintained
+
 LLC (802.2)
 P:     Arnaldo Carvalho de Melo
 M:     acme@conectiva.com.br
@@ -1390,8 +1411,6 @@ S:        Maintained
 NCP FILESYSTEM
 P:     Petr Vandrovec
 M:     vandrove@vc.cvut.cz
-P:     Volker Lendecke
-M:     vl@kki.org
 L:     linware@sh.cvut.cz
 S:     Maintained
 
index da97882..785fff5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 6
-SUBLEVEL = 6
+SUBLEVEL = 7
 EXTRAVERSION = -prep
 NAME=Zonked Quokka
 
@@ -1062,6 +1062,7 @@ versioncheck:
 
 buildcheck:
        $(PERL) scripts/reference_discarded.pl
+       $(PERL) scripts/reference_init.pl
 
 endif #ifeq ($(config-targets),1)
 endif #ifeq ($(mixed-targets),1)
index 60722f0..835d09a 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/init.h>
 #include <linux/init_task.h>
 #include <linux/fs.h>
+#include <linux/mqueue.h>
 #include <asm/uaccess.h>
 
 
index 2cb8fa4..91f5f37 100644 (file)
@@ -279,8 +279,8 @@ setup_memory(void *kernel_end)
                                       initrd_end,
                                       phys_to_virt(PFN_PHYS(max_low_pfn)));
                } else {
-                       nid = NODE_DATA(kvaddr_to_nid(initrd_start));
-                       reserve_bootmem_node(nid,
+                       nid = kvaddr_to_nid(initrd_start);
+                       reserve_bootmem_node(NODE_DATA(nid),
                                             virt_to_phys((void *)initrd_start),
                                             INITRD_SIZE);
                }
index 03b9d5b..ff2a826 100644 (file)
@@ -246,10 +246,10 @@ menu "General setup"
 # Select various configuration options depending on the machine type
 config DISCONTIGMEM
        bool
-       depends on ARCH_EDB7211 || ARCH_SA1100 || ARCH_LH7A40X
+       depends on ARCH_EDB7211 || ARCH_SA1100 || (ARCH_LH7A40X && !LH7A40X_SROMLL)
        default y
        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.
@@ -421,6 +421,17 @@ config FPE_FASTFPE
          If you do not feel you need a faster FP emulation you should better
          choose NWFPE.
 
+config VFP
+       bool "VFP-format floating point maths"
+       help
+         Say Y to include VFP support code in the kernel. This is needed
+         if your hardware includes a VFP unit.
+
+         Please see <file:Documentation/arm/VFP/release-notes.txt> for
+         release notes and additional status information.
+
+         Say N if your target does not have VFP hardware.
+
 source "fs/Kconfig.binfmt"
 
 source "drivers/base/Kconfig"
@@ -581,7 +592,7 @@ config LEDS_CPU
 config ALIGNMENT_TRAP
        bool
        depends on CPU_32
-       default y
+       default y if !ARCH_EBSA110
        help
          ARM processors can not fetch/store information which is not
          naturally aligned on the bus, i.e., a 4 byte fetch must start at an
index 85eeb2b..598a521 100644 (file)
@@ -119,6 +119,7 @@ core-y                              += arch/arm/mach-$(machine-y)/
 endif
 core-$(CONFIG_FPE_NWFPE)       += arch/arm/nwfpe/
 core-$(CONFIG_FPE_FASTFPE)     += $(FASTFPE_OBJ)
+core-$(CONFIG_VFP)             += arch/arm/vfp/
 
 drivers-$(CONFIG_OPROFILE)      += arch/arm/oprofile/
 drivers-$(CONFIG_ARCH_CLPS7500)        += drivers/acorn/char/
index c7e5439..4803446 100644 (file)
                .macro  writeb, rb
                strb    \rb, [r3, #0]
                .endm
+#elif defined(CONFIG_ARCH_OMAP)
+               .macro  loadsp, rb
+               mov     \rb, #0xff000000        @ physical base address
+               add     \rb, \rb, #0x00fb0000
+#if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3)
+               add     \rb, \rb, #0x00000800
+#endif
+#ifdef CONFIG_OMAP_LL_DEBUG_UART3
+               add     \rb, \rb, #0x00009000
+#endif
+               .endm
+               .macro  writeb, rb
+               strb    \rb, [r3]
+               .endm
 #else
 #error no serial architecture defined
 #endif
index 1def9c7..6f1dac2 100644 (file)
 # Automatically generated make config: don't edit
 #
 CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
+CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
+CONFIG_CLEAN_COMPILE=y
+CONFIG_STANDALONE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 CONFIG_KMOD=y
 
 #
 # System Type
 #
-# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_ADIFCC is not set
 # CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 CONFIG_ARCH_EBSA110=y
-# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE_PB is not set
 
 #
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_BITSY is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-
-#
-# CLPS711X/EP721X Implementations
+# Processor Type
 #
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
 CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
+CONFIG_CPU_SA110=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4=y
+CONFIG_CPU_CACHE_V4WB=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WB=y
 
 #
-# Processor Type
+# Processor Features
 #
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM1020 is not set
-CONFIG_CPU_SA110=y
-# CONFIG_CPU_SA1100 is not set
-# CONFIG_DISCONTIGMEM is not set
 
 #
 # General setup
 #
-# CONFIG_PCI is not set
 CONFIG_ISA=y
-# CONFIG_ISA_DMA is not set
-CONFIG_HOTPLUG=y
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
 
 #
 # PCMCIA/CardBus support
 #
 CONFIG_PCMCIA=m
-CONFIG_I82365=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_I82365=m
 # CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-# CONFIG_PCMCIA_SA1100 is not set
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_SYSCTL=y
+CONFIG_PCMCIA_PROBE=y
+
+#
+# At least one math emulation must be selected
+#
 CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
 CONFIG_FPE_FASTFPE=y
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
 CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=y
 # CONFIG_BINFMT_MISC is not set
+
+#
+# Generic Driver Options
+#
+# CONFIG_FW_LOADER is not set
 # CONFIG_PM is not set
+# CONFIG_PREEMPT is not set
 # CONFIG_ARTHUR is not set
 CONFIG_CMDLINE="root=/dev/nfs rw mem=16M console=ttyS1,38400n8"
 CONFIG_LEDS=y
@@ -143,22 +126,18 @@ CONFIG_LEDS_TIMER=y
 #
 CONFIG_PARPORT=y
 CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_PC_CML1=y
 CONFIG_PARPORT_PC_FIFO=y
 # CONFIG_PARPORT_PC_SUPERIO is not set
 # CONFIG_PARPORT_PC_PCMCIA is not set
 # CONFIG_PARPORT_ARC is not set
-# CONFIG_PARPORT_AMIGA is not set
-# CONFIG_PARPORT_MFC3 is not set
-# CONFIG_PARPORT_ATARI is not set
-# CONFIG_PARPORT_SUNBPP is not set
 # CONFIG_PARPORT_OTHER is not set
 CONFIG_PARPORT_1284=y
 
 #
-# Plug and Play configuration
+# Plug and Play support
 #
 # CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
 
 #
 # Block devices
@@ -166,9 +145,6 @@ CONFIG_PARPORT_1284=y
 # CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE 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_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -179,37 +155,29 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK=y
-CONFIG_RTNETLINK=y
 # CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-# CONFIG_FILTER is not set
 CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_RTNETLINK=y
-CONFIG_NETLINK=y
 CONFIG_IP_MULTIPLE_TABLES=y
 CONFIG_IP_ROUTE_FWMARK=y
 CONFIG_IP_ROUTE_NAT=y
 # CONFIG_IP_ROUTE_MULTIPATH is not set
 # CONFIG_IP_ROUTE_TOS is not set
 CONFIG_IP_ROUTE_VERBOSE=y
-# CONFIG_IP_ROUTE_LARGE_TABLES is not set
 CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_DHCP is not set
 CONFIG_IP_PNP_BOOTP=y
@@ -218,64 +186,113 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
-CONFIG_INET_ECN=y
 CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
 
 #
-#   IP: Netfilter Configuration
+# IP: Netfilter Configuration
 #
 CONFIG_IP_NF_CONNTRACK=y
 CONFIG_IP_NF_FTP=y
 CONFIG_IP_NF_IRC=y
+# CONFIG_IP_NF_TFTP is not set
+# CONFIG_IP_NF_AMANDA is not set
 # CONFIG_IP_NF_QUEUE is not set
 CONFIG_IP_NF_IPTABLES=y
 CONFIG_IP_NF_MATCH_LIMIT=y
-# CONFIG_IP_NF_MATCH_MAC is not set
+CONFIG_IP_NF_MATCH_IPRANGE=y
+CONFIG_IP_NF_MATCH_MAC=y
+CONFIG_IP_NF_MATCH_PKTTYPE=y
 CONFIG_IP_NF_MATCH_MARK=y
 CONFIG_IP_NF_MATCH_MULTIPORT=y
 CONFIG_IP_NF_MATCH_TOS=y
-# CONFIG_IP_NF_MATCH_TCPMSS is not set
+CONFIG_IP_NF_MATCH_RECENT=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_DSCP=y
+CONFIG_IP_NF_MATCH_AH_ESP=y
+CONFIG_IP_NF_MATCH_LENGTH=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_MATCH_TCPMSS=y
+CONFIG_IP_NF_MATCH_HELPER=y
 CONFIG_IP_NF_MATCH_STATE=y
-CONFIG_IP_NF_MATCH_UNCLEAN=y
+CONFIG_IP_NF_MATCH_CONNTRACK=y
 # CONFIG_IP_NF_MATCH_OWNER is not set
 CONFIG_IP_NF_FILTER=y
 CONFIG_IP_NF_TARGET_REJECT=y
-# CONFIG_IP_NF_TARGET_MIRROR is not set
 CONFIG_IP_NF_NAT=y
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=y
 CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_SAME=y
+# CONFIG_IP_NF_NAT_LOCAL is not set
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_NAT_IRC=y
 CONFIG_IP_NF_NAT_FTP=y
 CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_TARGET_TOS=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_DSCP=y
 CONFIG_IP_NF_TARGET_MARK=y
+CONFIG_IP_NF_TARGET_CLASSIFY=y
 CONFIG_IP_NF_TARGET_LOG=y
-# CONFIG_IP_NF_TARGET_TCPMSS is not set
-CONFIG_IPV6=y
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_IP_NF_TARGET_TCPMSS=y
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_RAW is not set
 
 #
-#   IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration
 #
+# CONFIG_IP6_NF_QUEUE is not set
 CONFIG_IP6_NF_IPTABLES=y
 CONFIG_IP6_NF_MATCH_LIMIT=y
+CONFIG_IP6_NF_MATCH_MAC=y
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_HL=y
+CONFIG_IP6_NF_MATCH_MULTIPORT=y
+# CONFIG_IP6_NF_MATCH_OWNER is not set
 CONFIG_IP6_NF_MATCH_MARK=y
+# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
+CONFIG_IP6_NF_MATCH_AHESP=y
+CONFIG_IP6_NF_MATCH_LENGTH=y
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
 CONFIG_IP6_NF_FILTER=y
+# CONFIG_IP6_NF_TARGET_LOG is not set
 CONFIG_IP6_NF_MANGLE=y
 CONFIG_IP6_NF_TARGET_MARK=y
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
+# CONFIG_IP6_NF_RAW 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_DECNET is not set
-# CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_LLC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -288,25 +305,30 @@ CONFIG_IP6_NF_TARGET_MARK=y
 # CONFIG_NET_SCHED is not set
 
 #
-# Network device support
+# 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
 
 #
 # ARCnet devices
 #
 # CONFIG_ARCNET is not set
-# 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
-# CONFIG_NET_SB1000 is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
 CONFIG_ARM_AM79C961A=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -322,40 +344,20 @@ CONFIG_ARM_AM79C961A=y
 #
 # Ethernet (1000 Mbit)
 #
-# CONFIG_ACENIC is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
 
 #
-# Wireless LAN (non-hamradio)
+# Ethernet (10000 Mbit)
 #
-# CONFIG_NET_RADIO is not set
 
 #
 # Token Ring devices
 #
 # CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
 
 #
-# Wan interfaces
+# Wireless LAN (non-hamradio)
 #
-# CONFIG_WAN is not set
+# CONFIG_NET_RADIO is not set
 
 #
 # PCMCIA network device support
@@ -368,39 +370,42 @@ CONFIG_PCMCIA_PCNET=m
 # CONFIG_PCMCIA_NMCLAN is not set
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-# CONFIG_NET_PCMCIA_RADIO is not set
+# CONFIG_PCMCIA_AXNET is not set
 
 #
-# Amateur Radio support
+# Wan interfaces
 #
-# CONFIG_HAMRADIO is not set
+# CONFIG_WAN is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
 
 #
-# IrDA (infrared) support
+# SCSI device support
 #
-# CONFIG_IRDA is not set
+# CONFIG_SCSI is not set
 
 #
-# ATA/IDE/MFM/RLL support
+# Fusion MPT device support
 #
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
-# SCSI support
+# IEEE 1394 (FireWire) support
 #
-# CONFIG_SCSI is not set
+# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
 #
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
 
 #
 # ISDN subsystem
@@ -408,76 +413,80 @@ CONFIG_PCMCIA_PCNET=m
 # CONFIG_ISDN is not set
 
 #
-# Input core support
+# Input device support
 #
 # CONFIG_INPUT is not set
 
 #
-# Character devices
+# Userland interfaces
 #
-# CONFIG_VT is not set
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-CONFIG_SERIAL_EXTENDED=y
-# CONFIG_SERIAL_MANY_PORTS is not set
-# CONFIG_SERIAL_SHARE_IRQ is not set
-# CONFIG_SERIAL_DETECT_IRQ is not set
-# CONFIG_SERIAL_MULTIPORT is not set
-# CONFIG_HUB6 is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-CONFIG_PRINTER=m
-# CONFIG_LP_CONSOLE is not set
-# CONFIG_PPDEV is not set
 
 #
-# I2C support
+# Input I/O drivers
 #
-# CONFIG_I2C is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_SERIO is not set
+# CONFIG_SERIO_I8042 is not set
 
 #
-# Mice
+# Input Device Drivers
 #
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
 
 #
-# Joysticks
+# Character devices
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
 
 #
-# Input core support is needed for joysticks
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
 #
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+# CONFIG_TIPAR is not set
 # CONFIG_QIC02_TAPE is not set
 
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
 #
 # Watchdog Cards
 #
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
 CONFIG_SOFT_WATCHDOG=y
-# CONFIG_WDT is not set
-# CONFIG_WDTPCI is not set
+
+#
+# ISA-based Watchdog Cards
+#
 # CONFIG_PCWATCHDOG is not set
-# CONFIG_ACQUIRE_WDT is not set
-# CONFIG_ADVANTECH_WDT is not set
-# CONFIG_60XX_WDT is not set
 # CONFIG_MIXCOMWD is not set
-# CONFIG_MACHZ_WDT is not set
-# CONFIG_INTEL_RNG is not set
+# CONFIG_WDT is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -492,81 +501,97 @@ CONFIG_SOFT_WATCHDOG=y
 #
 # PCMCIA character devices
 #
-# CONFIG_PCMCIA_SERIAL_CS is not set
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
 
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
 #
 # 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
+# CONFIG_XFS_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_ROMFS_FS is not set
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_FAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVPTS_FS_XATTR is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
 # CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW 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_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_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_TMPFS is not set
-# CONFIG_RAMFS is not set
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-CONFIG_MINIX_FS=y
 # CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_EXT2_FS is not set
 # CONFIG_SYSV_FS is not set
-# CONFIG_SYSV_FS_WRITE is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
 
 #
 # Network File Systems
 #
-# CONFIG_CODA_FS is not set
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-CONFIG_ROOT_NFS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-CONFIG_SUNRPC=y
+CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
+# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
 
 #
 # Partition Types
@@ -578,26 +603,68 @@ CONFIG_PARTITION_ADVANCED=y
 # 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_NEC98_PARTITION is not set
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
-# CONFIG_SMB_NLS is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
 # CONFIG_NLS is not set
 
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Misc devices
+#
+
 #
 # USB support
 #
-# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
 
 #
 # Kernel hacking
 #
 CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_NO_PGT_CACHE is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
+# CONFIG_DEBUG_KERNEL is not set
+
+#
+# Security options
+#
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
index 2fd8da9..7bbb718 100644 (file)
@@ -19,19 +19,23 @@ CONFIG_BROKEN_ON_SMP=y
 #
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE 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_IKCONFIG=y
 # CONFIG_IKCONFIG_PROC is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
 CONFIG_FUTEX=y
 # CONFIG_EPOLL is not set
 CONFIG_IOSCHED_NOOP=y
 # CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 
 #
@@ -43,21 +47,24 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # System Type
 #
 # CONFIG_ARCH_ADIFCC is not set
-# CONFIG_ARCH_ANAKIN is not set
 # CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_SHARK is not set
 CONFIG_ARCH_LH7A40X=y
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE_PB is not set
 
 #
 # CLPS711X/EP721X Implementations
@@ -82,13 +89,45 @@ CONFIG_ARCH_LH7A40X=y
 #
 
 #
-# Intel PXA250/210 Implementations
+# Intel IXP4xx Implementation Options
+#
+
+#
+# IXP4xx Platforms
+#
+
+#
+# IXP4xx Options
+#
+
+#
+# Intel PXA2xx Implementations
 #
 
 #
 # SA11x0 Implementations
 #
 
+#
+# TI OMAP Implementations
+#
+
+#
+# OMAP Core Type
+#
+
+#
+# OMAP Board Type
+#
+
+#
+# OMAP Feature Selections
+#
+
+#
+# S3C2410 Implementations
+#
+
 #
 # LH7A40X Implementations
 #
@@ -254,23 +293,21 @@ CONFIG_IP_PNP_RARP=y
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_ARPD is not set
-# CONFIG_INET_ECN 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_IPV6 is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
 # CONFIG_NETFILTER is not set
 
 #
 # SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # 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
@@ -291,6 +328,11 @@ CONFIG_IPV6_SCTP__=y
 # 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
@@ -311,38 +353,24 @@ CONFIG_SMC91X=y
 #
 # Ethernet (10000 Mbit)
 #
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
 
 #
-# Wireless LAN (non-hamradio)
+# Token Ring devices
 #
-# CONFIG_NET_RADIO is not set
 
 #
-# Token Ring devices
+# Wireless LAN (non-hamradio)
 #
-# CONFIG_SHAPER is not set
+# CONFIG_NET_RADIO is not set
 
 #
 # Wan interfaces
 #
 # CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BT is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -367,9 +395,9 @@ CONFIG_IDE_POLL=y
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
+CONFIG_IDE_ARM=y
 # CONFIG_BLK_DEV_IDEDMA is not set
 # CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
 # CONFIG_BLK_DEV_HD is not set
 
 #
@@ -452,11 +480,6 @@ CONFIG_SERIAL_LH7A40X_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -536,6 +559,7 @@ CONFIG_VFAT_FS=y
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
@@ -576,7 +600,7 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 # CONFIG_EXPORTFS is not set
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_GSS is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
@@ -664,6 +688,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
 #
 # Misc devices
 #
@@ -706,5 +735,6 @@ CONFIG_DEBUG_ERRORS=y
 # Library routines
 #
 CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
index a13b522..517f486 100644 (file)
@@ -19,19 +19,23 @@ CONFIG_BROKEN_ON_SMP=y
 #
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE 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_IKCONFIG=y
 # CONFIG_IKCONFIG_PROC is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
 CONFIG_FUTEX=y
 # CONFIG_EPOLL is not set
 CONFIG_IOSCHED_NOOP=y
 # CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 
 #
@@ -46,19 +50,21 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_SHARK is not set
 CONFIG_ARCH_LH7A40X=y
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE_PB is not set
 
 #
 # CLPS711X/EP721X Implementations
@@ -83,7 +89,19 @@ CONFIG_ARCH_LH7A40X=y
 #
 
 #
-# Intel PXA250/210 Implementations
+# Intel IXP4xx Implementation Options
+#
+
+#
+# IXP4xx Platforms
+#
+
+#
+# IXP4xx Options
+#
+
+#
+# Intel PXA2xx Implementations
 #
 
 #
@@ -94,6 +112,14 @@ CONFIG_ARCH_LH7A40X=y
 # TI OMAP Implementations
 #
 
+#
+# OMAP Core Type
+#
+
+#
+# OMAP Board Type
+#
+
 #
 # OMAP Feature Selections
 #
@@ -271,8 +297,6 @@ CONFIG_IP_PNP_RARP=y
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_IPV6 is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -280,7 +304,9 @@ CONFIG_IP_PNP_RARP=y
 #
 # 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
@@ -301,6 +327,11 @@ CONFIG_IP_PNP_RARP=y
 # 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
@@ -321,41 +352,24 @@ CONFIG_SMC91X=y
 #
 # Ethernet (10000 Mbit)
 #
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
 
 #
-# Wireless LAN (non-hamradio)
+# Token Ring devices
 #
-# CONFIG_NET_RADIO is not set
 
 #
-# Token Ring devices
+# Wireless LAN (non-hamradio)
 #
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
+# CONFIG_NET_RADIO is not set
 
 #
 # Wan interfaces
 #
 # CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BT is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -381,6 +395,7 @@ CONFIG_IDE_POLL=y
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
+CONFIG_IDE_ARM=y
 # CONFIG_BLK_DEV_IDEDMA is not set
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_BLK_DEV_HD is not set
@@ -404,7 +419,6 @@ CONFIG_SCSI=y
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
 # CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_REPORT_LUNS is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
 
@@ -418,6 +432,7 @@ CONFIG_SCSI=y
 # SCSI low-level drivers
 #
 # CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -573,6 +588,7 @@ CONFIG_VFAT_FS=y
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
@@ -618,7 +634,6 @@ CONFIG_SUNRPC=y
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -761,6 +776,7 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_EGALAX is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
 
@@ -809,6 +825,8 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -845,5 +863,6 @@ CONFIG_DEBUG_ERRORS=y
 # Library routines
 #
 CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
index 2ae6eae..22b7836 100644 (file)
                .macro  addruart,rx
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
-               ldr     \rx, =0x80000700        @ physical base address
+               mov     \rx, #0x00000700        @ offset from base
+               orreq   \rx, \rx, #0x80000000   @ physical base
                orrne   \rx, \rx, #0xf8000000   @ virtual base
                .endm
 
index 4005817..c8a5e0f 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/thread_info.h>
 #include <asm/glue.h>
 #include <asm/ptrace.h>
+#include <asm/vfpmacros.h>
 
 #include "entry-header.S"
 
@@ -679,19 +680,19 @@ ENTRY(soft_irq_mask)
 
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
                ldr     \base, =IO_ADDRESS(OMAP_IH1_BASE)
-               ldr     \irqnr, [\base, #IRQ_ITR]
-               ldr     \tmp, [\base, #IRQ_MIR]
+               ldr     \irqnr, [\base, #IRQ_ITR_REG_OFFSET]
+               ldr     \tmp, [\base, #IRQ_MIR_REG_OFFSET]
                mov     \irqstat, #0xffffffff
                bic     \tmp, \irqstat, \tmp
                tst     \irqnr, \tmp
                beq     1510f
 
-               ldr     \irqnr, [\base, #IRQ_SIR_FIQ]
+               ldr     \irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
                cmp     \irqnr, #0
-               ldreq   \irqnr, [\base, #IRQ_SIR_IRQ]
+               ldreq   \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
                cmpeq   \irqnr, #INT_IH2_IRQ
                ldreq   \base, =IO_ADDRESS(OMAP_IH2_BASE)
-               ldreq   \irqnr, [\base, #IRQ_SIR_IRQ]
+               ldreq   \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
                addeqs  \irqnr, \irqnr, #32
 1510:
                .endm
@@ -1198,8 +1199,13 @@ call_fpe:        enable_irq r10                          @ Enable interrupts
                mov     pc, lr                          @ CP#7
                mov     pc, lr                          @ CP#8
                mov     pc, lr                          @ CP#9
+#ifdef CONFIG_VFP
+               b       do_vfp                          @ CP#10 (VFP)
+               b       do_vfp                          @ CP#11 (VFP)
+#else
                mov     pc, lr                          @ CP#10 (VFP)
                mov     pc, lr                          @ CP#11 (VFP)
+#endif
                mov     pc, lr                          @ CP#12
                mov     pc, lr                          @ CP#13
                mov     pc, lr                          @ CP#14 (Debug)
@@ -1260,6 +1266,13 @@ ENTRY(__switch_to)
                ldr     r3, [r2, #TI_CPU_DOMAIN]!
                stmia   ip, {r4 - sl, fp, sp, lr}       @ Store most regs on stack
                mcr     p15, 0, r3, c3, c0, 0           @ Set domain register
+#ifdef CONFIG_VFP
+               @ Always disable VFP so we can lazily save/restore the old
+               @ state. This occurs in the context of the previous thread.
+               VFPFMRX r4, FPEXC
+               bic     r4, r4, #FPEXC_ENABLE
+               VFPFMXR FPEXC, r4
+#endif
                ldmib   r2, {r4 - sl, fp, sp, pc}       @ Load all regs saved previously
 
                __INIT
index d7c3f26..a00cca0 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/init_task.h>
+#include <linux/mqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
index 8d9db74..56498db 100644 (file)
@@ -314,10 +314,16 @@ void flush_thread(void)
        memset(thread->used_cp, 0, sizeof(thread->used_cp));
        memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
        fp_init(&thread->fpstate);
+#if defined(CONFIG_VFP)
+       vfp_flush_thread(&thread->vfpstate);
+#endif
 }
 
 void release_thread(struct task_struct *dead_task)
 {
+#if defined(CONFIG_VFP)
+       vfp_release_thread(&dead_task->thread_info->vfpstate);
+#endif
 }
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
index 9cb5cb9..4aef808 100644 (file)
@@ -253,6 +253,9 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
        if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
                goto badframe;
 
+       if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT)
+               goto badframe;
+
        /* Send SIGTRAP if we're single-stepping */
        if (current->ptrace & PT_SINGLESTEP) {
                ptrace_cancel_bpt(current);
@@ -402,6 +405,7 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
               sigset_t *set, struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame));
+       stack_t stack;
        int err = 0;
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
@@ -411,8 +415,14 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
        __put_user_error(&frame->uc, &frame->puc, err);
        err |= copy_siginfo_to_user(&frame->info, info);
 
-       /* Clear all the bits of the ucontext we don't use.  */
-       err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
+       __put_user_error(0, &frame->uc.uc_flags, err);
+       __put_user_error(NULL, &frame->uc.uc_link, err);
+
+       memset(&stack, 0, sizeof(stack));
+       stack.ss_sp = (void *)current->sas_ss_sp;
+       stack.ss_flags = sas_ss_flags(regs->ARM_sp);
+       stack.ss_size = current->sas_ss_size;
+       err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack));
 
        err |= setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/
                                regs, set->sig[0]);
index b419d0b..007a5a0 100644 (file)
@@ -24,7 +24,6 @@ lib-$(CONFIG_ARCH_RPC)                += ecard.o io-acorn.o floppydma.o
 lib-$(CONFIG_ARCH_CLPS7500)    += io-acorn.o
 lib-$(CONFIG_ARCH_L7200)       += io-acorn.o
 lib-$(CONFIG_ARCH_SHARK)       += io-shark.o
-lib-$(CONFIG_ARCH_CLPS711X)    += io-acorn.o
 
 $(obj)/csumpartialcopy.o:      $(obj)/csumpartialcopygeneric.S
 $(obj)/csumpartialcopyuser.o:  $(obj)/csumpartialcopygeneric.S
index 99378ec..3aacd01 100644 (file)
                .text
                .align
 
-               .equ    diff_pcio_base, PCIO_BASE - IO_BASE
-
-               .macro  outw2   rd
-               mov     r8, \rd, lsl #16
-               orr     r8, r8, r8, lsr #16
-               str     r8, [r3, r0, lsl #2]
-               mov     r8, \rd, lsr #16
-               orr     r8, r8, r8, lsl #16
-               str     r8, [r3, r0, lsl #2]
-               .endm
-
-               .macro  inw2    rd, mask, temp
-               ldr     \rd, [r0]
-               and     \rd, \rd, \mask
-               ldr     \temp, [r0]
-               orr     \rd, \rd, \temp, lsl #16
-               .endm
-
-               .macro  addr    rd
-               tst     \rd, #0x80000000
-               mov     \rd, \rd, lsl #2
-               add     \rd, \rd, #IO_BASE
-               addeq   \rd, \rd, #diff_pcio_base
-               .endm
-
 .iosl_warning:
                .ascii  "<4>insl/outsl not implemented, called from %08lX\0"
                .align
index 4e2278f..f6e6763 100644 (file)
@@ -1,16 +1,15 @@
+if ARCH_CLPS711X
 
 menu "CLPS711X/EP721X Implementations"
 
 config ARCH_AUTCPU12
        bool "AUTCPU12"
-       depends on ARCH_CLPS711X
        help
          Say Y if you intend to run the kernel on the autronix autcpu12
          board. This board is based on a Cirrus Logic CS89712.
 
 config ARCH_CDB89712
        bool "CDB89712"
-       depends on ARCH_CLPS711X
        help
          This is an evaluation board from Cirrus for the CS89712 processor.
          The board includes 2 serial ports, Ethernet, IRDA, and expansion
@@ -18,32 +17,27 @@ config ARCH_CDB89712
 
 config ARCH_CEIVA
        bool "CEIVA"
-       depends on ARCH_CLPS711X
        help
          Say Y here if you intend to run this kernel on the Ceiva/Polaroid
          PhotoMax Digital Picture Frame.
 
 config ARCH_CLEP7312
        bool "CLEP7312"
-       depends on ARCH_CLPS711X
 
 config ARCH_EDB7211
        bool "EDB7211"
-       depends on ARCH_CLPS711X
        help
          Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211
          evaluation board.
 
 config ARCH_P720T
        bool "P720T"
-       depends on ARCH_CLPS711X
        help
          Say Y here if you intend to run this kernel on the ARM Prospector
          720T.
 
 config ARCH_FORTUNET
        bool "FORTUNET"
-       depends on ARCH_CLPS711X
 
 # XXX Maybe these should indicate register compatibility
 # instead of being mutually exclusive.
@@ -74,3 +68,4 @@ config EP72XX_ROM_BOOT
 
 endmenu
 
+endif
index c948ddf..6556818 100644 (file)
@@ -67,9 +67,9 @@ u8 __readb(void *addr)
        u32 ret, a = __isamem_convert_addr(addr);
 
        if ((int)addr & 1)
-               ret = __raw_getl(a);
+               ret = __raw_readl(a);
        else
-               ret = __raw_getb(a);
+               ret = __raw_readb(a);
        return ret;
 }
 
@@ -80,7 +80,7 @@ u16 __readw(void *addr)
        if ((int)addr & 1)
                BUG();
 
-       return __raw_getw(a);
+       return __raw_readw(a);
 }
 
 u32 __readl(void *addr)
@@ -90,8 +90,8 @@ u32 __readl(void *addr)
        if ((int)addr & 3)
                BUG();
 
-       ret = __raw_getw(a);
-       ret |= __raw_getw(a + 4) << 16;
+       ret = __raw_readw(a);
+       ret |= __raw_readw(a + 4) << 16;
        return ret;
 }
 
@@ -104,9 +104,9 @@ void __writeb(u8 val, void *addr)
        u32 a = __isamem_convert_addr(addr);
 
        if ((int)addr & 1)
-               __raw_putl(val, a);
+               __raw_writel(val, a);
        else
-               __raw_putb(val, a);
+               __raw_writeb(val, a);
 }
 
 void __writew(u16 val, void *addr)
@@ -116,7 +116,7 @@ void __writew(u16 val, void *addr)
        if ((int)addr & 1)
                BUG();
 
-       __raw_putw(val, a);
+       __raw_writew(val, a);
 }
 
 void __writel(u32 val, void *addr)
@@ -126,8 +126,8 @@ void __writel(u32 val, void *addr)
        if ((int)addr & 3)
                BUG();
 
-       __raw_putw(val, a);
-       __raw_putw(val >> 16, a + 4);
+       __raw_writew(val, a);
+       __raw_writew(val >> 16, a + 4);
 }
 
 EXPORT_SYMBOL(__writeb);
@@ -147,7 +147,7 @@ u8 __inb(int port)
         * The SuperIO registers use sane addressing techniques...
         */
        if (SUPERIO_PORT(port))
-               ret = __raw_getb(ISAIO_BASE + (port << 2));
+               ret = __raw_readb(ISAIO_BASE + (port << 2));
        else {
                u32 a = ISAIO_BASE + ((port & ~1) << 1);
 
@@ -155,9 +155,9 @@ u8 __inb(int port)
                 * Shame nothing else does
                 */
                if (port & 1)
-                       ret = __raw_getl(a);
+                       ret = __raw_readl(a);
                else
-                       ret = __raw_getb(a);
+                       ret = __raw_readb(a);
        }
        return ret;
 }
@@ -170,7 +170,7 @@ u16 __inw(int port)
         * The SuperIO registers use sane addressing techniques...
         */
        if (SUPERIO_PORT(port))
-               ret = __raw_getw(ISAIO_BASE + (port << 2));
+               ret = __raw_readw(ISAIO_BASE + (port << 2));
        else {
                u32 a = ISAIO_BASE + ((port & ~1) << 1);
 
@@ -180,7 +180,7 @@ u16 __inw(int port)
                if (port & 1)
                        BUG();
 
-               ret = __raw_getw(a);
+               ret = __raw_readw(a);
        }
        return ret;
 }
@@ -201,7 +201,7 @@ void __outb(u8 val, int port)
         * The SuperIO registers use sane addressing techniques...
         */
        if (SUPERIO_PORT(port))
-               __raw_putb(val, ISAIO_BASE + (port << 2));
+               __raw_writeb(val, ISAIO_BASE + (port << 2));
        else {
                u32 a = ISAIO_BASE + ((port & ~1) << 1);
 
@@ -209,9 +209,9 @@ void __outb(u8 val, int port)
                 * Shame nothing else does
                 */
                if (port & 1)
-                       __raw_putl(val, a);
+                       __raw_writel(val, a);
                else
-                       __raw_putb(val, a);
+                       __raw_writeb(val, a);
        }
 }
 
@@ -230,7 +230,7 @@ void __outw(u16 val, int port)
                        BUG();
 
        }
-       __raw_putw(val, ISAIO_BASE + off);
+       __raw_writew(val, ISAIO_BASE + off);
 }
 
 void __outl(u32 val, int port)
index e88d914..55d896d 100644 (file)
@@ -1,17 +1,16 @@
+if ARCH_CAMELOT
 
 menu "Epxa10db"
 
 comment "PLD hotswap support"
-       depends on ARCH_CAMELOT
 
 config PLD
        bool
-       depends on ARCH_CAMELOT
        default y
 
 config PLD_HOTSWAP
        bool "Support for PLD device hotplugging (experimental)"
-       depends on ARCH_CAMELOT && EXPERIMENTAL
+       depends on EXPERIMENTAL
        help
          This enables support for the dynamic loading and configuration of
          compatible drivers when the contents of the PLD are changed. This
@@ -21,3 +20,4 @@ config PLD_HOTSWAP
 
 endmenu
 
+endif
index 510f896..1eaea0b 100644 (file)
@@ -1,9 +1,9 @@
+if ARCH_FOOTBRIDGE
 
 menu "Footbridge Implementations"
 
 config ARCH_CATS
        bool "CATS"
-       depends on ARCH_FOOTBRIDGE
        help
          Say Y here if you intend to run this kernel on the CATS.
 
@@ -11,7 +11,6 @@ config ARCH_CATS
 
 config ARCH_PERSONAL_SERVER
        bool "Compaq Personal Server"
-       depends on ARCH_FOOTBRIDGE
        ---help---
          Say Y here if you intend to run this kernel on the Compaq
          Personal Server.
@@ -29,7 +28,6 @@ config ARCH_PERSONAL_SERVER
 
 config ARCH_EBSA285_ADDIN
        bool "EBSA285 (addin mode)"
-       depends on ARCH_FOOTBRIDGE
        help
          Say Y here if you intend to run this kernel on the EBSA285 card
          in addin mode.
@@ -38,7 +36,6 @@ config ARCH_EBSA285_ADDIN
 
 config ARCH_EBSA285_HOST
        bool "EBSA285 (host mode)"
-       depends on ARCH_FOOTBRIDGE
        help
          Say Y here if you intend to run this kernel on the EBSA285 card
          in host ("central function") mode.
@@ -47,7 +44,6 @@ config ARCH_EBSA285_HOST
 
 config ARCH_NETWINDER
        bool "NetWinder"
-       depends on ARCH_FOOTBRIDGE
        help
          Say Y here if you intend to run this kernel on the Rebel.COM
          NetWinder.  Information about this machine can be found at:
@@ -58,3 +54,4 @@ config ARCH_NETWINDER
 
 endmenu
 
+endif
index 47f67a2..df97d16 100644 (file)
@@ -1,5 +1,6 @@
+if ARCH_INTEGRATOR
+
 menu "Integrator Options"
-       depends on ARCH_INTEGRATOR
 
 config ARCH_INTEGRATOR_AP
        bool "Support Integrator/AP and Integrator/PP2 platforms"
@@ -28,3 +29,5 @@ config INTEGRATOR_IMPD1
          module will be called impd1.
 
 endmenu
+
+endif
index 34726a4..158daaf 100644 (file)
@@ -4,7 +4,7 @@
 
 # Object file lists.
 
-obj-y                                  := core.o lm.o time.o
+obj-y                                  := clock.o core.o lm.o time.o
 obj-$(CONFIG_ARCH_INTEGRATOR_AP)       += integrator_ap.o
 obj-$(CONFIG_ARCH_INTEGRATOR_CP)       += integrator_cp.o
 
index dfdd5ec..e776e8a 100644 (file)
 #include <asm/arch/impd1.h>
 #include <asm/sizes.h>
 
+#include "clock.h"
+
 static int module_id;
 
 module_param_named(lmid, module_id, int, 0444);
 MODULE_PARM_DESC(lmid, "logic module stack position");
 
 struct impd1_module {
-       void    *base;
+       void            *base;
+       struct clk      vcos[2];
 };
 
 static const struct icst525_params impd1_vco_params = {
@@ -43,25 +46,20 @@ static const struct icst525_params impd1_vco_params = {
        .rd_max         = 120,
 };
 
-void impd1_set_vco(struct device *dev, int vconr, unsigned long period)
+static void impd1_setvco(struct clk *clk, struct icst525_vco vco)
 {
-       struct impd1_module *impd1 = dev_get_drvdata(dev);
-       struct icst525_vco vco;
+       struct impd1_module *impd1 = clk->data;
+       int vconr = clk - impd1->vcos;
        u32 val;
 
-       vco = icst525_ps_to_vco(&impd1_vco_params, period);
-
-       pr_debug("Guessed VCO reg params: S=%d R=%d V=%d\n",
-               vco.s, vco.r, vco.v);
-
        val = vco.v | (vco.r << 9) | (vco.s << 16);
 
        writel(0xa05f, impd1->base + IMPD1_LOCK);
        switch (vconr) {
-       case 1:
+       case 0:
                writel(val, impd1->base + IMPD1_OSC1);
                break;
-       case 2:
+       case 1:
                writel(val, impd1->base + IMPD1_OSC2);
                break;
        }
@@ -77,8 +75,6 @@ void impd1_set_vco(struct device *dev, int vconr, unsigned long period)
 #endif
 }
 
-EXPORT_SYMBOL(impd1_set_vco);
-
 void impd1_tweak_control(struct device *dev, u32 mask, u32 val)
 {
        struct impd1_module *impd1 = dev_get_drvdata(dev);
@@ -140,6 +136,11 @@ static struct impd1_device impd1_devs[] = {
        }
 };
 
+static const char *impd1_vconames[2] = {
+       "CLCDCLK",
+       "AUXVCO2",
+};
+
 static int impd1_probe(struct lm_device *dev)
 {
        struct impd1_module *impd1;
@@ -168,6 +169,16 @@ static int impd1_probe(struct lm_device *dev)
 
        printk("IM-PD1 found at 0x%08lx\n", dev->resource.start);
 
+       for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) {
+               impd1->vcos[i].owner = THIS_MODULE,
+               impd1->vcos[i].name = impd1_vconames[i],
+               impd1->vcos[i].params = &impd1_vco_params,
+               impd1->vcos[i].data = impd1,
+               impd1->vcos[i].setvco = impd1_setvco;
+
+               clk_register(&impd1->vcos[i]);
+       }
+
        for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
                struct impd1_device *idev = impd1_devs + i;
                struct amba_device *d;
@@ -216,6 +227,7 @@ static void impd1_remove(struct lm_device *dev)
 {
        struct impd1_module *impd1 = lm_get_drvdata(dev);
        struct list_head *l, *n;
+       int i;
 
        list_for_each_safe(l, n, &dev->dev.children) {
                struct device *d = list_to_dev(l);
@@ -223,6 +235,9 @@ static void impd1_remove(struct lm_device *dev)
                device_unregister(d);
        }
 
+       for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++)
+               clk_unregister(&impd1->vcos[i]);
+
        lm_set_drvdata(dev, NULL);
 
        iounmap(impd1->base);
index 7519410..f63e45c 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/mach-types.h>
 #include <asm/hardware/amba.h>
 #include <asm/hardware/amba_kmi.h>
+#include <asm/hardware/icst525.h>
 
 #include <asm/arch/lm.h>
 
 #include <asm/mach/mmc.h>
 #include <asm/mach/map.h>
 
+#include "clock.h"
+
 #define INTCP_PA_MMC_BASE              0x1c000000
 #define INTCP_PA_AACI_BASE             0x1d000000
 
 #define INTCP_PA_FLASH_BASE            0x24000000
 #define INTCP_FLASH_SIZE               SZ_32M
 
+#define INTCP_PA_CLCD_BASE             0xc0000000
+
 #define INTCP_VA_CIC_BASE              0xf1000040
 #define INTCP_VA_PIC_BASE              0xf1400000
 #define INTCP_VA_SIC_BASE              0xfca00000
@@ -209,6 +214,44 @@ static void __init intcp_init_irq(void)
        pic_unmask_irq(IRQ_CP_CPPLDINT);
 }
 
+/*
+ * Clock handling
+ */
+#define CM_LOCK (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
+#define CM_AUXOSC (IO_ADDRESS(INTEGRATOR_HDR_BASE)+0x1c)
+
+static const struct icst525_params cp_auxvco_params = {
+       .ref            = 24000,
+       .vco_max        = 320000,
+       .vd_min         = 8,
+       .vd_max         = 263,
+       .rd_min         = 3,
+       .rd_max         = 65,
+};
+
+static void cp_auxvco_set(struct clk *clk, struct icst525_vco vco)
+{
+       u32 val;
+
+       val = readl(CM_AUXOSC) & ~0x7ffff;
+       val |= vco.v | (vco.r << 9) | (vco.s << 16);
+
+       writel(0xa05f, CM_LOCK);
+       writel(val, CM_AUXOSC);
+       writel(0, CM_LOCK);
+}
+
+static struct clk cp_clcd_clk = {
+       .name   = "CLCDCLK",
+       .params = &cp_auxvco_params,
+       .setvco = cp_auxvco_set,
+};
+
+static struct clk cp_mmci_clk = {
+       .name   = "MCLK",
+       .rate   = 33000000,
+};
+
 /*
  * Flash handling.
  */
@@ -340,15 +383,34 @@ static struct amba_device aaci_device = {
        .periphid       = 0,
 };
 
+static struct amba_device clcd_device = {
+       .dev            = {
+               .bus_id = "mb:c0",
+               .coherent_dma_mask = ~0,
+       },
+       .res            = {
+               .start  = INTCP_PA_CLCD_BASE,
+               .end    = INTCP_PA_CLCD_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       .dma_mask       = ~0,
+       .irq            = { IRQ_CP_CLCDCINT, NO_IRQ },
+       .periphid       = 0,
+};
+
 static struct amba_device *amba_devs[] __initdata = {
        &mmc_device,
        &aaci_device,
+       &clcd_device,
 };
 
 static void __init intcp_init(void)
 {
        int i;
 
+       clk_register(&cp_clcd_clk);
+       clk_register(&cp_mmci_clk);
+
        platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
 
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
index a253ad4..6a388e2 100644 (file)
@@ -1,10 +1,10 @@
+if ARCH_IOP3XX
 
 menu "IOP3xx Implementation Options"
 
 choice
        prompt "IOP3xx System Type"
        default ARCH_IQ80310
-       depends on ARCH_IOP3XX
 
 config ARCH_IQ80310
        bool "IQ80310"
@@ -36,19 +36,20 @@ comment "IOP3xx Chipset Features"
 
 config IOP3XX_AAU
        bool "Support Intel IOP3xx Application Accelerator Unit (EXPERIMENTAL)"
-       depends on ARCH_IOP3XX && EXPERIMENTAL
+       depends on EXPERIMENTAL
 
 config IOP3XX_DMA
        bool "Support Intel IOP3xx DMA (EXPERIMENTAL)"
-       depends on ARCH_IOP3XX && EXPERIMENTAL
+       depends on EXPERIMENTAL
 
 config IOP3XX_MU
        bool "Support Intel IOP3xx Messaging Unit (EXPERIMENTAL)"
-       depends on ARCH_IOP3XX && EXPERIMENTAL
+       depends on EXPERIMENTAL
 
 config IOP3XX_PMON
        bool "Support Intel IOP3xx Performance Monitor (EXPERIMENTAL)"
-       depends on ARCH_IOP3XX && EXPERIMENTAL
+       depends on EXPERIMENTAL
 
 endmenu
 
+endif
index 3377f88..46b72e1 100644 (file)
@@ -1,7 +1,7 @@
+if ARCH_IXP4XX
 
 config ARCH_SUPPORTS_BIG_ENDIAN
        bool
-       depends on ARCH_IXP4XX
        default y
 
 menu "Intel IXP4xx Implementation Options"
@@ -10,7 +10,6 @@ comment "IXP4xx Platforms"
 
 config ARCH_AVILA
        bool "Avila"
-       depends on ARCH_IXP4XX
        help
          Say 'Y' here if you want your kernel to support the Gateworks
          Avila Network Platform. For more information on this platform,
@@ -18,7 +17,6 @@ config ARCH_AVILA
 
 config ARCH_ADI_COYOTE
        bool "Coyote"
-       depends on ARCH_IXP4XX
        help
          Say 'Y' here if you want your kernel to support the ADI 
          Engineering Coyote Gateway Reference Platform. For more
@@ -26,7 +24,6 @@ config ARCH_ADI_COYOTE
 
 config ARCH_IXDP425
        bool "IXDP425"
-       depends on ARCH_IXP4XX
        help
          Say 'Y' here if you want your kernel to support Intel's 
          IXDP425 Development Platform (Also known as Richfield).  
@@ -44,7 +41,6 @@ config ARCH_IXCDP1100
 
 config ARCH_PRPMC1100
        bool "PrPMC1100"
-       depends on ARCH_IXP4XX
        help
          Say 'Y' here if you want your kernel to support the Motorola
          PrPCM1100 Processor Mezanine Module. For more information on
@@ -62,7 +58,6 @@ comment "IXP4xx Options"
 
 config IXP4XX_INDIRECT_PCI
        bool "Use indirect PCI memory access"
-       depends on ARCH_IXP4XX
        help
           IXP4xx provides two methods of accessing PCI memory space:
 
@@ -87,3 +82,5 @@ config IXP4XX_INDIRECT_PCI
          what you need, leave this option unselected.
 
 endmenu
+
+endif
index 4475dba..8a17867 100644 (file)
@@ -1,9 +1,9 @@
+if ARCH_LH7A40X
 
 menu "LH7A40X Implementations"
 
 config MACH_KEV7A400
        bool "KEV7A400"
-       depends on ARCH_LH7A40X
        select ARCH_LH7A400
        help
          Say Y here if you are using the Sharp KEV7A400 development
@@ -12,9 +12,8 @@ config MACH_KEV7A400
 
 config MACH_LPD7A400
        bool "LPD7A400 Card Engine"
-       depends on ARCH_LH7A40X
        select ARCH_LH7A400
-       select IDE_POLL
+#      select IDE_POLL
        help
          Say Y here if you are using Logic Product Development's
          LPD7A400 CardEngine.  For the time being, the LPD7A400 and
@@ -22,9 +21,8 @@ config MACH_LPD7A400
 
 config MACH_LPD7A404
        bool "LPD7A404 Card Engine"
-       depends on ARCH_LH7A40X
        select ARCH_LH7A404
-       select IDE_POLL
+#      select IDE_POLL
        help
          Say Y here if you are using Logic Product Development's
          LPD7A404 CardEngine. For the time being, the LPD7A400 and
@@ -36,4 +34,37 @@ config ARCH_LH7A400
 config ARCH_LH7A404
        bool
 
+config LH7A40X_CONTIGMEM
+       bool "Disable NUMA Support"
+       depends on ARCH_LH7A40X
+       help
+         Say Y here if your bootloader sets the SROMLL bit(s) in
+         the SDRAM controller, organizing memory as a contiguous
+         array.  This option will disable CONFIG_DISCONTIGMEM and
+          force the kernel to manage all memory in one node.
+
+         Setting this option incorrectly may prevent the kernel from
+         booting.  It is OK to leave it N.
+
+         For more information, consult
+           <file:Documentation/arm/Sharp-LH/SDRAM>.
+
+config LH7A40X_ONE_BANK_PER_NODE
+       bool "Optimize NUMA Node Tables for Size"
+       depends on ARCH_LH7A40X && !LH7A40X_CONTIGMEM
+       help
+         Say Y here to produce compact memory node tables.  By
+         default pairs of adjacent physical RAM banks are managed
+         together in a single node, incurring some wasted overhead
+         in the node tables, however also maintaining compatibility
+         with systems where physical memory is truly contiguous.
+
+         Setting this option incorrectly may prevent the kernel from
+         booting.  It is OK to leave it N.
+
+         For more information, consult
+           <file:Documentation/arm/Sharp-LH/SDRAM>.
+
 endmenu
+
+endif
index 734cc75..75dba98 100644 (file)
@@ -116,7 +116,12 @@ extern void lpd7a400_map_io (void);
 
 static void __init lpd7a40x_init (void)
 {
-       CPLD_CONTROL = 0x0;     /* Enable LAN (Disable LCD) */
+       CPLD_CONTROL |=     (1<<6); /* Mask USB1 connection IRQ */
+       CPLD_CONTROL &= ~(0
+                         | (1<<1) /* Disable LCD */
+                         | (1<<0) /* Enable WLAN */
+               );
+
        platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs));
 }
 
@@ -191,7 +196,7 @@ void __init lh7a40x_init_board_irq (void)
        int pinCPLD = (cpld_version == 0x28) ? 7 : 3;
 
 #if defined CONFIG_MACH_LPD7A404
-       cpld_version = 0x34;    /* Override, for now */
+       cpld_version = 0x34;    /* Coerce LPD7A404 to RevB */
 #endif
 
                /* First, configure user controlled GPIOF interrupts  */
@@ -204,7 +209,7 @@ void __init lh7a40x_init_board_irq (void)
 
                /* Then, configure CPLD interrupt */
 
-       CPLD_INTERRUPTS =   0x0c; /* Disable all CPLD interrupts */
+       CPLD_INTERRUPTS =   0x9c; /* Disable all CPLD interrupts */
        GPIO_PFDD       &= ~(1 << pinCPLD); /* Make input */
        GPIO_INTTYPE1   |=  (1 << pinCPLD); /* Edge triggered */
        GPIO_INTTYPE2   &= ~(1 << pinCPLD); /* Active low */
index 30bc6df..9fb70d5 100644 (file)
@@ -1,27 +1,24 @@
+if ARCH_OMAP
 
 menu "TI OMAP Implementations"
 
 comment "OMAP Core Type"
 
 config ARCH_OMAP730
-       depends on ARCH_OMAP
        bool "OMAP730 Based System"
        select CPU_ARM926T
 
 config ARCH_OMAP1510
-       depends on ARCH_OMAP
        default y
        bool "OMAP1510 Based System"
        select CPU_ARM925T
        select CPU_DCACHE_WRITETHROUGH
 
 config ARCH_OMAP1610
-       depends on ARCH_OMAP
        bool "OMAP1610 Based System"
        select CPU_ARM926T
 
 config ARCH_OMAP5912
-       depends on ARCH_OMAP
        bool "OMAP5912 Based System"
        select CPU_ARM926T
 
@@ -87,7 +84,6 @@ comment "OMAP Feature Selections"
 
 #config OMAP_BOOT_TAG
 #      bool "OMAP bootloader information passing"
-#        depends on ARCH_OMAP
 #        default n
 #        help
 #          Say Y, if you have a bootloader which passes information
@@ -95,7 +91,6 @@ comment "OMAP Feature Selections"
 
 config OMAP_MUX
        bool "OMAP multiplexing support"
-        depends on ARCH_OMAP
        default y
         help
           Pin multiplexing support for OMAP boards. If your bootloader
@@ -113,7 +108,6 @@ config OMAP_MUX_DEBUG
 
 choice
        prompt "Low-level debug console UART"
-       depends on ARCH_OMAP
        default OMAP_LL_DEBUG_UART1
 
 config OMAP_LL_DEBUG_UART1
@@ -171,3 +165,5 @@ config OMAP_ARM_30MHZ
           Enable 30MHz clock for OMAP CPU. If unsure, say N.
 
 endmenu
+
+endif
index bf739b5..e0b09f8 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/device.h>
 
 #include <asm/hardware.h>
+#include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
@@ -64,7 +65,7 @@ static void __init omap_generic_map_io(void)
        omap_map_io();
 }
 
-MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610")
+MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610/1710")
        MAINTAINER("Tony Lindgren <tony@atomide.com>")
        BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
        BOOT_PARAMS(0x10000100)
index c118801..c65f38f 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/delay.h>
 
 #include <asm/hardware.h>
+#include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
@@ -36,14 +38,14 @@ extern int omap_gpio_init(void);
 
 /* Only FPGA needs to be mapped here. All others are done with ioremap */
 static struct map_desc innovator1510_io_desc[] __initdata = {
-{ OMAP1510P1_FPGA_BASE, OMAP1510P1_FPGA_START, OMAP1510P1_FPGA_SIZE,
+{ OMAP1510_FPGA_BASE, OMAP1510_FPGA_START, OMAP1510_FPGA_SIZE,
        MT_DEVICE },
 };
 
 static struct resource innovator1510_smc91x_resources[] = {
        [0] = {
-               .start  = OMAP1510P1_FPGA_ETHR_START,   /* Physical */
-               .end    = OMAP1510P1_FPGA_ETHR_START + 16,
+               .start  = OMAP1510_FPGA_ETHR_START,     /* Physical */
+               .end    = OMAP1510_FPGA_ETHR_START + 16,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -132,12 +134,13 @@ static void __init innovator_map_io(void)
 #ifdef CONFIG_ARCH_OMAP1510
        if (cpu_is_omap1510()) {
                iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc));
+               udelay(10);     /* Delay needed for FPGA */
 
                /* Dump the Innovator FPGA rev early - useful info for support. */
                printk("Innovator FPGA Rev %d.%d Board Rev %d\n",
-                      fpga_read(OMAP1510P1_FPGA_REV_HIGH),
-                      fpga_read(OMAP1510P1_FPGA_REV_LOW),
-                      fpga_read(OMAP1510P1_FPGA_BOARD_REV));
+                      fpga_read(OMAP1510_FPGA_REV_HIGH),
+                      fpga_read(OMAP1510_FPGA_REV_LOW),
+                      fpga_read(OMAP1510_FPGA_BOARD_REV));
        }
 #endif
 #ifdef CONFIG_ARCH_OMAP1610
index 5216834..8044dd1 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/device.h>
 
 #include <asm/hardware.h>
+#include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
index 3843d6a..e938ea4 100644 (file)
@@ -3,6 +3,9 @@
  *
  * Modified from board-generic.c
  *
+ * Original OMAP730 support by Jean Pihet <j-pihet@ti.com>
+ * Updated for 2.6 by Kevin Hilman <kjh@hilman.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.
@@ -13,6 +16,7 @@
 #include <linux/device.h>
 
 #include <asm/hardware.h>
+#include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
@@ -102,7 +106,7 @@ static void __init omap_perseus2_map_io(void)
 }
 
 MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
-       MAINTAINER("Kevin Hilman <k-hilman@ti.com>")
+       MAINTAINER("Kevin Hilman <kjh@hilman.org>")
        BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
        BOOT_PARAMS(0x10000100)
        MAPIO(omap_perseus2_map_io)
index ba5dd2a..07da30d 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/spinlock.h>
 
 #include <asm/hardware.h>
+#include <asm/mach-types.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
@@ -265,7 +266,7 @@ static void __exit omap_bus_exit(void)
        }
 }
 
-module_init(omap_bus_init);
+postcore_initcall(omap_bus_init);
 module_exit(omap_bus_exit);
 
 MODULE_DESCRIPTION("Virtual bus for OMAP");
index 382baee..bda7c6f 100644 (file)
@@ -84,7 +84,7 @@ static ck_info_t ck_info_table[] = {
        }, {
                .name           = "ck_gen1",
                .flags          = CK_RATEF | CK_IDLEF,
-               .rate_reg       = CK_DPLL1,
+               .rate_reg       = DPLL_CTL,
                .idle_reg       = ARM_IDLECT1,
                .idle_shift     = IDLDPLL_ARM,
                .parent         = OMAP_CLKIN,
@@ -629,39 +629,39 @@ init_ck(void)
        omap_writew(0x1000, ARM_SYSST);
 #if defined(CONFIG_OMAP_ARM_30MHZ)
        omap_writew(0x1555, ARM_CKCTL);
-       omap_writew(0x2290, DPLL_CTL_REG);
+       omap_writew(0x2290, DPLL_CTL);
 #elif defined(CONFIG_OMAP_ARM_60MHZ)
        omap_writew(0x1005, ARM_CKCTL);
-       omap_writew(0x2290, DPLL_CTL_REG);
+       omap_writew(0x2290, DPLL_CTL);
 #elif defined(CONFIG_OMAP_ARM_96MHZ)
        omap_writew(0x1005, ARM_CKCTL);
-       omap_writew(0x2410, DPLL_CTL_REG);
+       omap_writew(0x2410, DPLL_CTL);
 #elif defined(CONFIG_OMAP_ARM_120MHZ)
        omap_writew(0x110a, ARM_CKCTL);
-       omap_writew(0x2510, DPLL_CTL_REG);
+       omap_writew(0x2510, DPLL_CTL);
 #elif defined(CONFIG_OMAP_ARM_168MHZ)
        omap_writew(0x110f, ARM_CKCTL);
-       omap_writew(0x2710, DPLL_CTL_REG);
+       omap_writew(0x2710, DPLL_CTL);
 #elif defined(CONFIG_OMAP_ARM_182MHZ) && defined(CONFIG_ARCH_OMAP730)
        omap_writew(0x250E, ARM_CKCTL);
-       omap_writew(0x2710, DPLL_CTL_REG);
+       omap_writew(0x2710, DPLL_CTL);
 #elif defined(CONFIG_OMAP_ARM_192MHZ) && (defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912))
        omap_writew(0x150f, ARM_CKCTL);
        if (crystal_type == 2) {
                source_clock = 13;      /* MHz */
-               omap_writew(0x2510, DPLL_CTL_REG);
+               omap_writew(0x2510, DPLL_CTL);
        } else
-               omap_writew(0x2810, DPLL_CTL_REG);
+               omap_writew(0x2810, DPLL_CTL);
 #elif defined(CONFIG_OMAP_ARM_195MHZ) && defined(CONFIG_ARCH_OMAP730)
        omap_writew(0x250E, ARM_CKCTL);
-       omap_writew(0x2790, DPLL_CTL_REG);
+       omap_writew(0x2790, DPLL_CTL);
 #else
 #error "OMAP MHZ not set, please run make xconfig"
 #endif
 
 #ifdef CONFIG_MACH_OMAP_PERSEUS2
        /* Select slicer output as OMAP input clock */
-       omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL_REG) & ~0x1, OMAP730_PCC_UPLD_CTRL_REG);
+       omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
 #endif
 
        /* Turn off some other junk the bootloader might have turned on */
index 2ff74d1..43aaa1c 100644 (file)
 #include <asm/arch/board.h>
 #include <asm/io.h>
 
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP revision check
+ *
+ * Since we use the cpu_is_omapnnnn() macros, there's a chance that a board
+ * switches to an updated core. We want to print out the OMAP revision early.
+ *
+ * We use the system_serial registers for the revision information so we
+ * can see it in /proc/cpuinfo.
+ *
+ * If the OMAP detection gets more complicated, we may want to expand this
+ * to store the OMAP version and replace the current cpu_is_omapnnnn() macros.
+ *
+ * ----------------------------------------------------------------------------
+ */
+static void __init omap_check_revision(void)
+{
+       system_serial_high = omap_readl(OMAP_ID_BASE);
+       system_serial_low = OMAP_ID_REG;
+       system_rev = (OMAP_ID_REG >> ID_SHIFT) & ID_MASK;
+
+       printk("OMAP revision: %d.%d (0x%08x) id: 0x%08x detected as OMAP-",
+              (system_serial_high >> 20) & 0xf,
+              (system_serial_high >> 16) & 0xf,
+              system_serial_high, system_serial_low);
+
+       switch (system_rev) {
+       case OMAP_ID_730:
+               printk("730\n");
+               system_rev = 0x730;
+               break;
+       case OMAP_ID_1510:
+               printk("1510\n");
+               system_rev = 0x1510;
+               break;
+       case OMAP_ID_1610:
+               printk("1610\n");
+               system_rev = 0x1610;
+               break;
+       case OMAP_ID_1710:
+               printk("1710\n");
+               system_rev = 0x1710;
+               break;
+       case OMAP_ID_5912:
+               printk("5912/1611B\n");
+               system_rev = 0x5912;
+               break;
+       default:
+               printk("unknown, please add support!\n");
+       }
+}
+
 /*
  * ----------------------------------------------------------------------------
  * OMAP I/O mapping
@@ -64,7 +116,13 @@ static struct map_desc omap1610_io_desc[] __initdata = {
 static struct map_desc omap5912_io_desc[] __initdata = {
  { OMAP5912_DSP_BASE,    OMAP5912_DSP_START,    OMAP5912_DSP_SIZE,    MT_DEVICE },
  { OMAP5912_DSPREG_BASE, OMAP5912_DSPREG_START, OMAP5912_DSPREG_SIZE, MT_DEVICE },
- { OMAP5912_SRAM_BASE,   OMAP5912_SRAM_START,   OMAP5912_SRAM_SIZE,   MT_DEVICE }
+/*
+ * The OMAP5912 has 250kByte internal SRAM. Because the mapping is baseed on page
+ * size (4kByte), it seems that the last 2kByte (=0x800) of the 250kByte are not mapped.
+ * Add additional 2kByte (0x800) so that the last page is mapped and the last 2kByte
+ * can be used.
+ */
+ { OMAP5912_SRAM_BASE,   OMAP5912_SRAM_START,   OMAP5912_SRAM_SIZE + 0x800,   MT_DEVICE }
 };
 #endif
 
@@ -77,6 +135,7 @@ static void __init _omap_map_io(void)
        /* We have to initialize the IO space mapping before we can run
         * cpu_is_omapxxx() macros. */
        iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc));
+       omap_check_revision();
 
 #ifdef CONFIG_ARCH_OMAP730
        if (cpu_is_omap730()) {
@@ -102,8 +161,8 @@ static void __init _omap_map_io(void)
        /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort
         * on a Posted Write in the TIPB Bridge".
         */
-       omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL_REG);
-       omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL_REG);
+       omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL);
+       omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL);
 
        /* Must init clocks early to assure that timer interrupt works
         */
index 29c62e1..385b4d1 100644 (file)
@@ -92,45 +92,124 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
 {
        u16 w;
 
-       w = omap_readw(OMAP_DMA_CSDP_REG(lch));
+       w = omap_readw(OMAP_DMA_CSDP(lch));
        w &= ~0x03;
        w |= data_type;
-       omap_writew(w, OMAP_DMA_CSDP_REG(lch));
+       omap_writew(w, OMAP_DMA_CSDP(lch));
 
-       w = omap_readw(OMAP_DMA_CCR_REG(lch));
+       w = omap_readw(OMAP_DMA_CCR(lch));
        w &= ~(1 << 5);
        if (sync_mode == OMAP_DMA_SYNC_FRAME)
                w |= 1 << 5;
-       omap_writew(w, OMAP_DMA_CCR_REG(lch));
+       omap_writew(w, OMAP_DMA_CCR(lch));
 
-       w = omap_readw(OMAP_DMA_CCR2_REG(lch));
+       w = omap_readw(OMAP_DMA_CCR2(lch));
        w &= ~(1 << 2);
        if (sync_mode == OMAP_DMA_SYNC_BLOCK)
                w |= 1 << 2;
-       omap_writew(w, OMAP_DMA_CCR2_REG(lch));
+       omap_writew(w, OMAP_DMA_CCR2(lch));
 
-       omap_writew(elem_count, OMAP_DMA_CEN_REG(lch));
-       omap_writew(frame_count, OMAP_DMA_CFN_REG(lch));
+       omap_writew(elem_count, OMAP_DMA_CEN(lch));
+       omap_writew(frame_count, OMAP_DMA_CFN(lch));
 
 }
+void omap_set_dma_constant_fill(int lch, u32 color)
+{
+       u16 w;
+
+#ifdef CONFIG_DEBUG_KERNEL
+       if (omap_dma_in_1510_mode) {
+               printk(KERN_ERR "OMAP DMA constant fill not available in 1510 mode.");
+               BUG();
+               return;
+       }
+#endif
+       w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03;
+       w |= 0x01;
+       omap_writew(w, OMAP_DMA_CCR2(lch));
+
+       omap_writew((u16)color, OMAP_DMA_COLOR_L(lch));
+       omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch));
+
+       w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f;
+       w |= 1;         /* Channel type G */
+       omap_writew(w, OMAP_DMA_LCH_CTRL(lch));
+}
+
+void omap_set_dma_transparent_copy(int lch, u32 color)
+{
+       u16 w;
+
+#ifdef CONFIG_DEBUG_KERNEL
+       if (omap_dma_in_1510_mode) {
+               printk(KERN_ERR "OMAP DMA transparent copy not available in 1510 mode.");
+               BUG();
+       }
+#endif
+       w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03;
+       w |= 0x02;
+       omap_writew(w, OMAP_DMA_CCR2(lch));
+
+       omap_writew((u16)color, OMAP_DMA_COLOR_L(lch));
+       omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch));
+
+       w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f;
+       w |= 1;         /* Channel type G */
+       omap_writew(w, OMAP_DMA_LCH_CTRL(lch));
+}
 
 void omap_set_dma_src_params(int lch, int src_port, int src_amode,
                             unsigned long src_start)
 {
        u16 w;
 
-       w = omap_readw(OMAP_DMA_CSDP_REG(lch));
+       w = omap_readw(OMAP_DMA_CSDP(lch));
        w &= ~(0x1f << 2);
        w |= src_port << 2;
-       omap_writew(w, OMAP_DMA_CSDP_REG(lch));
+       omap_writew(w, OMAP_DMA_CSDP(lch));
 
-       w = omap_readw(OMAP_DMA_CCR_REG(lch));
+       w = omap_readw(OMAP_DMA_CCR(lch));
        w &= ~(0x03 << 12);
        w |= src_amode << 12;
-       omap_writew(w, OMAP_DMA_CCR_REG(lch));
+       omap_writew(w, OMAP_DMA_CCR(lch));
+
+       omap_writew(src_start >> 16, OMAP_DMA_CSSA_U(lch));
+       omap_writew(src_start, OMAP_DMA_CSSA_L(lch));
+}
+
+void omap_set_dma_src_index(int lch, int eidx, int fidx)
+{
+       omap_writew(eidx, OMAP_DMA_CSEI(lch));
+       omap_writew(fidx, OMAP_DMA_CSFI(lch));
+}
+
+void omap_set_dma_src_data_pack(int lch, int enable)
+{
+       u16 w;
+
+       w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 6);
+       w |= enable ? (1 << 6) : 0;
+       omap_writew(w, OMAP_DMA_CSDP(lch));
+}
+
+void omap_set_dma_src_burst_mode(int lch, int burst_mode)
+{
+       u16 w;
 
-       omap_writew(src_start >> 16, OMAP_DMA_CSSA_U_REG(lch));
-       omap_writew(src_start, OMAP_DMA_CSSA_L_REG(lch));
+       w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 7);
+       switch (burst_mode) {
+       case OMAP_DMA_DATA_BURST_4:
+               w |= (0x01 << 7);
+               break;
+       case OMAP_DMA_DATA_BURST_8:
+               w |= (0x03 << 7);
+               break;
+       default:
+               printk(KERN_ERR "Invalid DMA burst mode\n");
+               BUG();
+               return;
+       }
+       omap_writew(w, OMAP_DMA_CSDP(lch));
 }
 
 void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
@@ -138,18 +217,53 @@ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
 {
        u16 w;
 
-       w = omap_readw(OMAP_DMA_CSDP_REG(lch));
+       w = omap_readw(OMAP_DMA_CSDP(lch));
        w &= ~(0x1f << 9);
        w |= dest_port << 9;
-       omap_writew(w, OMAP_DMA_CSDP_REG(lch));
+       omap_writew(w, OMAP_DMA_CSDP(lch));
 
-       w = omap_readw(OMAP_DMA_CCR_REG(lch));
+       w = omap_readw(OMAP_DMA_CCR(lch));
        w &= ~(0x03 << 14);
        w |= dest_amode << 14;
-       omap_writew(w, OMAP_DMA_CCR_REG(lch));
+       omap_writew(w, OMAP_DMA_CCR(lch));
+
+       omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U(lch));
+       omap_writew(dest_start, OMAP_DMA_CDSA_L(lch));
+}
+
+void omap_set_dma_dest_index(int lch, int eidx, int fidx)
+{
+       omap_writew(eidx, OMAP_DMA_CDEI(lch));
+       omap_writew(fidx, OMAP_DMA_CDFI(lch));
+}
+
+void omap_set_dma_dest_data_pack(int lch, int enable)
+{
+       u16 w;
 
-       omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U_REG(lch));
-       omap_writew(dest_start, OMAP_DMA_CDSA_L_REG(lch));
+       w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 13);
+       w |= enable ? (1 << 13) : 0;
+       omap_writew(w, OMAP_DMA_CSDP(lch));
+}
+
+void omap_set_dma_dest_burst_mode(int lch, int burst_mode)
+{
+       u16 w;
+
+       w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 14);
+       switch (burst_mode) {
+       case OMAP_DMA_DATA_BURST_4:
+               w |= (0x01 << 14);
+               break;
+       case OMAP_DMA_DATA_BURST_8:
+               w |= (0x03 << 14);
+               break;
+       default:
+               printk(KERN_ERR "Invalid DMA burst mode\n");
+               BUG();
+               return;
+       }
+       omap_writew(w, OMAP_DMA_CSDP(lch));
 }
 
 void omap_start_dma(int lch)
@@ -164,38 +278,38 @@ void omap_start_dma(int lch)
                /* Enable the queue, if needed so. */
                if (next_lch != -1) {
                        /* Clear the STOP_LNK bits */
-                       w = omap_readw(OMAP_DMA_CLNK_CTRL_REG(lch));
+                       w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
                        w &= ~(1 << 14);
-                       omap_writew(w, OMAP_DMA_CLNK_CTRL_REG(lch));
-                       w = omap_readw(OMAP_DMA_CLNK_CTRL_REG(next_lch));
+                       omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
+                       w = omap_readw(OMAP_DMA_CLNK_CTRL(next_lch));
                        w &= ~(1 << 14);
-                       omap_writew(w, OMAP_DMA_CLNK_CTRL_REG(next_lch));
+                       omap_writew(w, OMAP_DMA_CLNK_CTRL(next_lch));
 
                        /* And set the ENABLE_LNK bits */
                        omap_writew(next_lch | (1 << 15),
-                                   OMAP_DMA_CLNK_CTRL_REG(lch));
+                                   OMAP_DMA_CLNK_CTRL(lch));
                        /* The loop case */
                        if (dma_chan[next_lch].next_lch == lch)
                                omap_writew(lch | (1 << 15),
-                                           OMAP_DMA_CLNK_CTRL_REG(next_lch));
+                                           OMAP_DMA_CLNK_CTRL(next_lch));
 
                        /* Read CSR to make sure it's cleared. */
-                       w = omap_readw(OMAP_DMA_CSR_REG(next_lch));
+                       w = omap_readw(OMAP_DMA_CSR(next_lch));
                        /* Enable some nice interrupts. */
                        omap_writew(dma_chan[next_lch].enabled_irqs,
-                                   OMAP_DMA_CICR_REG(next_lch));
+                                   OMAP_DMA_CICR(next_lch));
                        dma_chan[next_lch].flags |= OMAP_DMA_ACTIVE;
                }
        }
 
        /* Read CSR to make sure it's cleared. */
-       w = omap_readw(OMAP_DMA_CSR_REG(lch));
+       w = omap_readw(OMAP_DMA_CSR(lch));
        /* Enable some nice interrupts. */
-       omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR_REG(lch));
+       omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR(lch));
 
-       w = omap_readw(OMAP_DMA_CCR_REG(lch));
+       w = omap_readw(OMAP_DMA_CCR(lch));
        w |= OMAP_DMA_CCR_EN;
-       omap_writew(w, OMAP_DMA_CCR_REG(lch));
+       omap_writew(w, OMAP_DMA_CCR(lch));
        dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
 }
 
@@ -205,12 +319,12 @@ void omap_stop_dma(int lch)
        int next_lch;
 
        /* Disable all interrupts on the channel */
-       omap_writew(0, OMAP_DMA_CICR_REG(lch));
+       omap_writew(0, OMAP_DMA_CICR(lch));
 
        if (omap_dma_in_1510_mode()) {
-               w = omap_readw(OMAP_DMA_CCR_REG(lch));
+               w = omap_readw(OMAP_DMA_CCR(lch));
                w &= ~OMAP_DMA_CCR_EN;
-               omap_writew(w, OMAP_DMA_CCR_REG(lch));
+               omap_writew(w, OMAP_DMA_CCR(lch));
                dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
                return;
        }
@@ -221,16 +335,16 @@ void omap_stop_dma(int lch)
         * According to thw HW spec, enabling the STOP_LNK bit
         * resets the CCR_EN bit at the same time.
         */
-       w = omap_readw(OMAP_DMA_CLNK_CTRL_REG(lch));
+       w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
        w |= (1 << 14);
-       w = omap_writew(w, OMAP_DMA_CLNK_CTRL_REG(lch));
+       w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
        dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
 
        if (next_lch != -1) {
-               omap_writew(0, OMAP_DMA_CICR_REG(next_lch));
-               w = omap_readw(OMAP_DMA_CLNK_CTRL_REG(next_lch));
+               omap_writew(0, OMAP_DMA_CICR(next_lch));
+               w = omap_readw(OMAP_DMA_CLNK_CTRL(next_lch));
                w |= (1 << 14);
-               w = omap_writew(w, OMAP_DMA_CLNK_CTRL_REG(next_lch));
+               w = omap_writew(w, OMAP_DMA_CLNK_CTRL(next_lch));
                dma_chan[next_lch].flags &= ~OMAP_DMA_ACTIVE;
        }
 }
@@ -253,7 +367,7 @@ static int dma_handle_ch(int ch)
                csr = dma_chan[ch].saved_csr;
                dma_chan[ch].saved_csr = 0;
        } else
-               csr = omap_readw(OMAP_DMA_CSR_REG(ch));
+               csr = omap_readw(OMAP_DMA_CSR(ch));
        if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
                dma_chan[ch + 6].saved_csr = csr >> 7;
                csr &= 0x7f;
@@ -339,9 +453,9 @@ int omap_request_dma(int dev_id, const char *dev_name,
                }
                /* Disable the 1510 compatibility mode and set the sync device
                 * id. */
-               omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR_REG(free_ch));
+               omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR(free_ch));
        } else {
-               omap_writew(dev_id, OMAP_DMA_CCR_REG(free_ch));
+               omap_writew(dev_id, OMAP_DMA_CCR(free_ch));
        }
        *dma_ch_out = free_ch;
 
@@ -362,9 +476,9 @@ void omap_free_dma(int ch)
        spin_unlock_irqrestore(&dma_chan_lock, flags);
 
        /* Disable all DMA interrupts for the channel. */
-       omap_writew(0, OMAP_DMA_CICR_REG(ch));
+       omap_writew(0, OMAP_DMA_CICR(ch));
        /* Make sure the DMA transfer is stopped. */
-       omap_writew(0, OMAP_DMA_CCR_REG(ch));
+       omap_writew(0, OMAP_DMA_CCR(ch));
 }
 
 int omap_dma_in_1510_mode(void)
@@ -601,19 +715,19 @@ static int __init omap_init_dma(void)
                enable_1510_mode = 1;
        } else if (cpu_is_omap1610() || cpu_is_omap5912()) {
                printk(KERN_INFO "OMAP DMA hardware version %d\n",
-                      omap_readw(OMAP_DMA_HW_ID_REG));
+                      omap_readw(OMAP_DMA_HW_ID));
                printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
-                      (omap_readw(OMAP_DMA_CAPS_0_U_REG) << 16) | omap_readw(OMAP_DMA_CAPS_0_L_REG),
-                      (omap_readw(OMAP_DMA_CAPS_1_U_REG) << 16) | omap_readw(OMAP_DMA_CAPS_1_L_REG),
-                      omap_readw(OMAP_DMA_CAPS_2_REG), omap_readw(OMAP_DMA_CAPS_3_REG),
-                      omap_readw(OMAP_DMA_CAPS_4_REG));
+                      (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | omap_readw(OMAP_DMA_CAPS_0_L),
+                      (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | omap_readw(OMAP_DMA_CAPS_1_L),
+                      omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3),
+                      omap_readw(OMAP_DMA_CAPS_4));
                if (!enable_1510_mode) {
                        u16 w;
 
                        /* Disable OMAP 3.0/3.1 compatibility mode. */
-                       w = omap_readw(OMAP_DMA_GSCR_REG);
+                       w = omap_readw(OMAP_DMA_GSCR);
                        w |= 1 << 3;
-                       omap_writew(w, OMAP_DMA_GSCR_REG);
+                       omap_writew(w, OMAP_DMA_GSCR);
                        dma_chan_count = OMAP_LOGICAL_DMA_CH_COUNT;
                } else
                        dma_chan_count = 9;
@@ -657,9 +771,21 @@ EXPORT_SYMBOL(omap_request_dma);
 EXPORT_SYMBOL(omap_free_dma);
 EXPORT_SYMBOL(omap_start_dma);
 EXPORT_SYMBOL(omap_stop_dma);
+
 EXPORT_SYMBOL(omap_set_dma_transfer_params);
+EXPORT_SYMBOL(omap_set_dma_constant_fill);
+EXPORT_SYMBOL(omap_set_dma_transparent_copy);
+
 EXPORT_SYMBOL(omap_set_dma_src_params);
+EXPORT_SYMBOL(omap_set_dma_src_index);
+EXPORT_SYMBOL(omap_set_dma_src_data_pack);
+EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
+
 EXPORT_SYMBOL(omap_set_dma_dest_params);
+EXPORT_SYMBOL(omap_set_dma_dest_index);
+EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
+EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
+
 EXPORT_SYMBOL(omap_dma_link_lch);
 EXPORT_SYMBOL(omap_dma_unlink_lch);
 
index 95b21e2..d9246b1 100644 (file)
@@ -46,11 +46,11 @@ static void fpga_mask_irq(unsigned int irq)
        irq -= IH_FPGA_BASE;
 
        if (irq < 8)
-               __raw_writeb((__raw_readb(OMAP1510P1_FPGA_IMR_LO)
-                             & ~(1 << irq)), OMAP1510P1_FPGA_IMR_LO);
+               __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO)
+                             & ~(1 << irq)), OMAP1510_FPGA_IMR_LO);
        else if (irq < 16)
-               __raw_writeb((__raw_readb(OMAP1510P1_FPGA_IMR_HI)
-                             & ~(1 << (irq - 8))), OMAP1510P1_FPGA_IMR_HI);
+               __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI)
+                             & ~(1 << (irq - 8))), OMAP1510_FPGA_IMR_HI);
        else
                __raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2)
                              & ~(1 << (irq - 16))), INNOVATOR_FPGA_IMR2);
@@ -60,10 +60,10 @@ static void fpga_mask_irq(unsigned int irq)
 static inline u32 get_fpga_unmasked_irqs(void)
 {
        return
-               ((__raw_readb(OMAP1510P1_FPGA_ISR_LO) &
-                 __raw_readb(OMAP1510P1_FPGA_IMR_LO))) |
-               ((__raw_readb(OMAP1510P1_FPGA_ISR_HI) &
-                 __raw_readb(OMAP1510P1_FPGA_IMR_HI)) << 8) |
+               ((__raw_readb(OMAP1510_FPGA_ISR_LO) &
+                 __raw_readb(OMAP1510_FPGA_IMR_LO))) |
+               ((__raw_readb(OMAP1510_FPGA_ISR_HI) &
+                 __raw_readb(OMAP1510_FPGA_IMR_HI)) << 8) |
                ((__raw_readb(INNOVATOR_FPGA_ISR2) &
                  __raw_readb(INNOVATOR_FPGA_IMR2)) << 16);
 }
@@ -79,11 +79,11 @@ static void fpga_unmask_irq(unsigned int irq)
        irq -= IH_FPGA_BASE;
 
        if (irq < 8)
-               __raw_writeb((__raw_readb(OMAP1510P1_FPGA_IMR_LO) | (1 << irq)),
-                    OMAP1510P1_FPGA_IMR_LO);
+               __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) | (1 << irq)),
+                    OMAP1510_FPGA_IMR_LO);
        else if (irq < 16)
-               __raw_writeb((__raw_readb(OMAP1510P1_FPGA_IMR_HI)
-                             | (1 << (irq - 8))), OMAP1510P1_FPGA_IMR_HI);
+               __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI)
+                             | (1 << (irq - 8))), OMAP1510_FPGA_IMR_HI);
        else
                __raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2)
                              | (1 << (irq - 16))), INNOVATOR_FPGA_IMR2);
@@ -166,8 +166,8 @@ void fpga_init_irq(void)
 {
        int i;
 
-       __raw_writeb(0, OMAP1510P1_FPGA_IMR_LO);
-       __raw_writeb(0, OMAP1510P1_FPGA_IMR_HI);
+       __raw_writeb(0, OMAP1510_FPGA_IMR_LO);
+       __raw_writeb(0, OMAP1510_FPGA_IMR_HI);
        __raw_writeb(0, INNOVATOR_FPGA_IMR2);
 
        for (i = IH_FPGA_BASE; i < (IH_FPGA_BASE + NR_FPGA_IRQS); i++) {
index fce61a1..2f052a9 100644 (file)
@@ -22,7 +22,6 @@
 #include <asm/irq.h>
 #include <asm/arch/irqs.h>
 #include <asm/arch/gpio.h>
-#include <asm/arch/pm.h>
 #include <asm/mach/irq.h>
 
 #include <asm/io.h>
@@ -79,7 +78,7 @@
 #define OMAP730_GPIO_INT_MASK          0x10
 #define OMAP730_GPIO_INT_STATUS                0x14
 
-#define OMAP_MPUIO_MASK         (~OMAP_MAX_GPIO_LINES & 0xff)
+#define OMAP_MPUIO_MASK                (~OMAP_MAX_GPIO_LINES & 0xff)
 
 struct gpio_bank {
        u32 base;
@@ -213,12 +212,12 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
                reg += OMAP730_GPIO_DIR_CONTROL;
                break;
        }
-       l = omap_readl(reg);
+       l = __raw_readl(reg);
        if (is_input)
                l |= 1 << gpio;
        else
                l &= ~(1 << gpio);
-       omap_writel(l, reg);
+       __raw_writel(l, reg);
 }
 
 void omap_set_gpio_direction(int gpio, int is_input)
@@ -240,8 +239,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 
        switch (bank->method) {
        case METHOD_MPUIO:
-               reg += OMAP_MPUIO_OUTPUT_REG;
-               l = omap_readl(reg);
+               reg += OMAP_MPUIO_OUTPUT;
+               l = __raw_readl(reg);
                if (enable)
                        l |= 1 << gpio;
                else
@@ -249,7 +248,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
                break;
        case METHOD_GPIO_1510:
                reg += OMAP1510_GPIO_DATA_OUTPUT;
-               l = omap_readl(reg);
+               l = __raw_readl(reg);
                if (enable)
                        l |= 1 << gpio;
                else
@@ -264,7 +263,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
                break;
        case METHOD_GPIO_730:
                reg += OMAP730_GPIO_DATA_OUTPUT;
-               l = omap_readl(reg);
+               l = __raw_readl(reg);
                if (enable)
                        l |= 1 << gpio;
                else
@@ -274,7 +273,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
                BUG();
                return;
        }
-       omap_writel(l, reg);
+       __raw_writel(l, reg);
 }
 
 void omap_set_gpio_dataout(int gpio, int enable)
@@ -312,7 +311,7 @@ int omap_get_gpio_datain(int gpio)
                BUG();
                return -1;
        }
-       return (omap_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
+       return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
 }
 
 static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge)
@@ -322,22 +321,22 @@ static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge)
 
        switch (bank->method) {
        case METHOD_MPUIO:
-               reg += OMAP_MPUIO_GPIO_INT_EDGE_REG;
-               l = omap_readl(reg);
+               reg += OMAP_MPUIO_GPIO_INT_EDGE;
+               l = __raw_readl(reg);
                if (edge == OMAP_GPIO_RISING_EDGE)
                        l |= 1 << gpio;
                else
                        l &= ~(1 << gpio);
-               omap_writel(l, reg);
+               __raw_writel(l, reg);
                break;
        case METHOD_GPIO_1510:
                reg += OMAP1510_GPIO_INT_CONTROL;
-               l = omap_readl(reg);
+               l = __raw_readl(reg);
                if (edge == OMAP_GPIO_RISING_EDGE)
                        l |= 1 << gpio;
                else
                        l &= ~(1 << gpio);
-               omap_writel(l, reg);
+               __raw_writel(l, reg);
                break;
        case METHOD_GPIO_1610:
                edge &= 0x03;
@@ -346,19 +345,19 @@ static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge)
                else
                        reg += OMAP1610_GPIO_EDGE_CTRL1;
                gpio &= 0x07;
-               l = omap_readl(reg);
+               l = __raw_readl(reg);
                l &= ~(3 << (gpio << 1));
                l |= edge << (gpio << 1);
-               omap_writel(l, reg);
+               __raw_writel(l, reg);
                break;
        case METHOD_GPIO_730:
                reg += OMAP730_GPIO_INT_CONTROL;
-               l = omap_readl(reg);
+               l = __raw_readl(reg);
                if (edge == OMAP_GPIO_RISING_EDGE)
                        l |= 1 << gpio;
                else
                        l &= ~(1 << gpio);
-               omap_writel(l, reg);
+               __raw_writel(l, reg);
                break;
        default:
                BUG();
@@ -385,11 +384,11 @@ static int _get_gpio_edge_ctrl(struct gpio_bank *bank, int gpio)
 
        switch (bank->method) {
        case METHOD_MPUIO:
-               l = omap_readl(reg + OMAP_MPUIO_GPIO_INT_EDGE_REG);
+               l = __raw_readl(reg + OMAP_MPUIO_GPIO_INT_EDGE);
                return (l & (1 << gpio)) ?
                        OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
        case METHOD_GPIO_1510:
-               l = omap_readl(reg + OMAP1510_GPIO_INT_CONTROL);
+               l = __raw_readl(reg + OMAP1510_GPIO_INT_CONTROL);
                return (l & (1 << gpio)) ?
                        OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
        case METHOD_GPIO_1610:
@@ -397,9 +396,9 @@ static int _get_gpio_edge_ctrl(struct gpio_bank *bank, int gpio)
                        reg += OMAP1610_GPIO_EDGE_CTRL2;
                else
                        reg += OMAP1610_GPIO_EDGE_CTRL1;
-               return (omap_readl(reg) >> ((gpio & 0x07) << 1)) & 0x03;
+               return (__raw_readl(reg) >> ((gpio & 0x07) << 1)) & 0x03;
        case METHOD_GPIO_730:
-               l = omap_readl(reg + OMAP730_GPIO_INT_CONTROL);
+               l = __raw_readl(reg + OMAP730_GPIO_INT_CONTROL);
                return (l & (1 << gpio)) ?
                        OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
        default:
@@ -430,7 +429,7 @@ static void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
                BUG();
                return;
        }
-       omap_writel(1 << get_gpio_index(gpio), reg);
+       __raw_writel(1 << get_gpio_index(gpio), reg);
 }
 
 static void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
@@ -441,7 +440,7 @@ static void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
        switch (bank->method) {
        case METHOD_MPUIO:
                reg += OMAP_MPUIO_GPIO_MASKIT;
-               l = omap_readl(reg);
+               l = __raw_readl(reg);
                if (enable)
                        l &= ~(1 << gpio);
                else
@@ -449,7 +448,7 @@ static void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
                break;
        case METHOD_GPIO_1510:
                reg += OMAP1510_GPIO_INT_MASK;
-               l = omap_readl(reg);
+               l = __raw_readl(reg);
                if (enable)
                        l &= ~(1 << gpio);
                else
@@ -465,7 +464,7 @@ static void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
                break;
        case METHOD_GPIO_730:
                reg += OMAP730_GPIO_INT_MASK;
-               l = omap_readl(reg);
+               l = __raw_readl(reg);
                if (enable)
                        l &= ~(1 << gpio);
                else
@@ -475,7 +474,7 @@ static void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
                BUG();
                return;
        }
-       omap_writel(l, reg);
+       __raw_writel(l, reg);
 }
 
 int omap_request_gpio(int gpio)
@@ -500,7 +499,7 @@ int omap_request_gpio(int gpio)
 
                /* Claim the pin for the ARM */
                reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
-               omap_writel(omap_readl(reg) | (1 << get_gpio_index(gpio)), reg);
+               __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg);
        }
 #endif
        spin_unlock(&bank->lock);
@@ -564,7 +563,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
                isr_reg = bank->base + OMAP730_GPIO_INT_STATUS;
 #endif
        for (;;) {
-               u32 isr = omap_readl(isr_reg);
+               u32 isr = __raw_readl(isr_reg);
                unsigned int gpio_irq;
 
                if (!isr)
@@ -587,15 +586,15 @@ static void gpio_ack_irq(unsigned int irq)
 
 #ifdef CONFIG_ARCH_OMAP1510
        if (bank->method == METHOD_GPIO_1510)
-               omap_writew(1 << (gpio & 0x0f), bank->base + OMAP1510_GPIO_INT_STATUS);
+               __raw_writew(1 << (gpio & 0x0f), bank->base + OMAP1510_GPIO_INT_STATUS);
 #endif
 #if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
        if (bank->method == METHOD_GPIO_1610)
-               omap_writew(1 << (gpio & 0x0f), bank->base + OMAP1610_GPIO_IRQSTATUS1);
+               __raw_writew(1 << (gpio & 0x0f), bank->base + OMAP1610_GPIO_IRQSTATUS1);
 #endif
 #ifdef CONFIG_ARCH_OMAP730
        if (bank->method == METHOD_GPIO_730)
-               omap_writel(1 << (gpio & 0x1f), bank->base + OMAP730_GPIO_INT_STATUS);
+               __raw_writel(1 << (gpio & 0x1f), bank->base + OMAP730_GPIO_INT_STATUS);
 #endif
 }
 
@@ -692,26 +691,27 @@ static int __init _omap_gpio_init(void)
 
                bank = &gpio_bank[i];
                bank->reserved_map = 0;
+               bank->base = IO_ADDRESS(bank->base);
                spin_lock_init(&bank->lock);
                if (bank->method == METHOD_MPUIO) {
                        omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
                }
 #ifdef CONFIG_ARCH_OMAP1510
                if (bank->method == METHOD_GPIO_1510) {
-                       omap_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
-                       omap_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
+                       __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
+                       __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
                }
 #endif
 #if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
                if (bank->method == METHOD_GPIO_1610) {
-                       omap_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
-                       omap_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
+                       __raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
+                       __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
                }
 #endif
 #ifdef CONFIG_ARCH_OMAP730
                if (bank->method == METHOD_GPIO_730) {
-                       omap_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK);
-                       omap_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS);
+                       __raw_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK);
+                       __raw_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS);
 
                        gpio_count = 32; /* 730 has 32-bit GPIOs */
                }
@@ -730,9 +730,9 @@ static int __init _omap_gpio_init(void)
        }
 
        /* Enable system clock for GPIO module.
-        * The CAM_CLK_CTRL_REG *is* really the right place. */
+        * The CAM_CLK_CTRL *is* really the right place. */
        if (cpu_is_omap1610())
-               omap_writel(omap_readl(ULPD_CAM_CLK_CTRL_REG) | 0x04, ULPD_CAM_CLK_CTRL_REG);
+               omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
 
        return 0;
 }
@@ -748,8 +748,11 @@ int omap_gpio_init(void)
                return 0;
 }
 
-EXPORT_SYMBOL(omap_gpio_init);
 EXPORT_SYMBOL(omap_request_gpio);
 EXPORT_SYMBOL(omap_free_gpio);
+EXPORT_SYMBOL(omap_set_gpio_direction);
+EXPORT_SYMBOL(omap_set_gpio_dataout);
+EXPORT_SYMBOL(omap_get_gpio_datain);
+EXPORT_SYMBOL(omap_set_gpio_edge_ctrl);
 
 arch_initcall(omap_gpio_init);
index 3c7cefc..18da117 100644 (file)
@@ -74,9 +74,9 @@ static inline void irq_bank_writel(unsigned long value, int bank, int offset)
 static void omap_ack_irq(unsigned int irq)
 {
        if (irq > 31)
-               omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG);
+               omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG_OFFSET);
 
-       omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG);
+       omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG_OFFSET);
 }
 
 static void omap_mask_irq(unsigned int irq)
@@ -84,9 +84,9 @@ static void omap_mask_irq(unsigned int irq)
        int bank = IRQ_BANK(irq);
        u32 l;
 
-       l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR);
+       l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
        l |= 1 << IRQ_BIT(irq);
-       omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR);
+       omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
 }
 
 static void omap_unmask_irq(unsigned int irq)
@@ -94,9 +94,9 @@ static void omap_unmask_irq(unsigned int irq)
        int bank = IRQ_BANK(irq);
        u32 l;
 
-       l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR);
+       l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
        l &= ~(1 << IRQ_BIT(irq));
-       omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR);
+       omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
 }
 
 static void omap_mask_ack_irq(unsigned int irq)
@@ -121,7 +121,7 @@ static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger)
        /* FIQ is only available on bank 0 interrupts */
        fiq = bank ? 0 : (fiq & 0x1);
        val = fiq | ((priority & 0x1f) << 2) | ((trigger & 0x1) << 1);
-       offset = IRQ_ILR0 + IRQ_BIT(irq) * 0x4;
+       offset = IRQ_ILR0_REG_OFFSET + IRQ_BIT(irq) * 0x4;
        irq_bank_writel(val, bank, offset);
 }
 
@@ -182,13 +182,13 @@ void __init omap_init_irq(void)
 
        /* Mask and clear all interrupts */
        for (i = 0; i < irq_bank_count; i++) {
-               irq_bank_writel(~0x0, i, IRQ_MIR);
-               irq_bank_writel(0x0, i, IRQ_ITR);
+               irq_bank_writel(~0x0, i, IRQ_MIR_REG_OFFSET);
+               irq_bank_writel(0x0, i, IRQ_ITR_REG_OFFSET);
        }
 
        /* Clear any pending interrupts */
-       irq_bank_writel(0x03, 0, IRQ_CONTROL_REG);
-       irq_bank_writel(0x03, 1, IRQ_CONTROL_REG);
+       irq_bank_writel(0x03, 0, IRQ_CONTROL_REG_OFFSET);
+       irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET);
 
        /* Install the interrupt handlers for each bank */
        for (i = 0; i < irq_bank_count; i++) {
index e7087bc..944c294 100644 (file)
@@ -85,14 +85,6 @@ int ocpi_enable(void)
        val &= ~0xff;
        omap_writel(val, OCPI_SEC);
 
-       val = omap_readl(OCPI_SEC);
-       val |= 0;
-       omap_writel(val, OCPI_SEC);
-
-       val = omap_readl(OCPI_SINT0);
-       val |= 0;
-       omap_writel(val, OCPI_SINT1);
-
        return 0;
 }
 EXPORT_SYMBOL(ocpi_enable);
index a9648c8..d394f69 100644 (file)
@@ -1,9 +1,9 @@
+if ARCH_PXA
 
 menu "Intel PXA2xx Implementations"
 
 choice
        prompt "Select target board"
-       depends on ARCH_PXA
 
 config ARCH_LUBBOCK
        bool "Intel DBPXA250 Development Platform"
@@ -32,3 +32,4 @@ config PXA27x
        help
          Select code specific to PXA27x variants
 
+endif
index 5e6468a..706858e 100644 (file)
@@ -27,6 +27,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
+#include <asm/arch/idp.h>
+
 #include "generic.h"
 
 #ifndef PXA_IDP_REV02
index 8f9d2c3..adb108c 100644 (file)
@@ -19,6 +19,8 @@
 #include <asm/leds.h>
 #include <asm/system.h>
 
+#include <asm/arch/idp.h>
+
 #include "leds.h"
 
 #define LED_STATE_ENABLED      1
index 6d1de79..0e083b3 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/hardware.h>
 #include <asm/leds.h>
 #include <asm/system.h>
+#include <asm/arch/lubbock.h>
 
 #include "leds.h"
 
index cb6f6dd..8403f67 100644 (file)
@@ -17,6 +17,8 @@
 #include <asm/leds.h>
 #include <asm/system.h>
 
+#include <asm/arch/mainstone.h>
+
 #include "leds.h"
 
 
index da026d4..023c5e9 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <asm/arch/lubbock.h>
 #include <asm/arch/udc.h>
 #include <asm/arch/pxafb.h>
 #include <asm/hardware/sa1111.h>
index cd7da1d..663c1ee 100644 (file)
@@ -30,6 +30,8 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <asm/arch/mainstone.h>
+
 #include "generic.h"
 
 
index de6b7e2..245e25b 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/hardware.h>
 #include <asm/memory.h>
 #include <asm/system.h>
+#include <asm/arch/lubbock.h>
 
 
 /*
index 2eff139..b71f89e 100644 (file)
@@ -1,8 +1,9 @@
+if ARCH_S3C2410
+
 menu "S3C2410 Implementations"
 
 config ARCH_BAST
        bool "Simtec Electronics BAST (EB2410ITX)"
-       depends on ARCH_S3C2410
        help
          Say Y here if you are using the Simtec Electronics EB2410ITX
          development board (also known as BAST)
@@ -11,22 +12,21 @@ config ARCH_BAST
 
 config ARCH_H1940
        bool "IPAQ H1940"
-       depends on ARCH_S3C2410
        help
          Say Y here if you are using the HP IPAQ H1940
          <http://www.handhelds.org/projects/h1940.html>.
 
 config ARCH_SMDK2410
        bool "SMDK2410/A9M2410"
-       depends on ARCH_S3C2410
        help
           Say Y here if you are using the SMDK2410 or the derived module A9M2410
            <http://www.fsforth.de>
 
 config MACH_VR1000
        bool "Simtec VR1000"
-       depends on ARCH_S3C2410
        help
          Say Y here if you are using the Simtec VR1000 board.
 
 endmenu
+
+endif
index 6d9249b..ce21b98 100644 (file)
@@ -1,9 +1,9 @@
+if ARCH_SA1100
 
 menu "SA11x0 Implementations"
 
 config SA1100_ASSABET
        bool "Assabet"
-       depends on ARCH_SA1100
        help
          Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
          Microprocessor Development Board (also known as the Assabet).
@@ -18,7 +18,6 @@ config ASSABET_NEPONSET
 
 config SA1100_ADSBITSY
        bool "ADS Bitsy"
-       depends on ARCH_SA1100
        help
          Say Y here if you are using Applied Data Systems Intel(R)
          StrongARM(R) 1110 based Bitsy, 3 x 5 inches in size, Compaq - IPAQ -
@@ -28,14 +27,12 @@ config SA1100_ADSBITSY
 
 config SA1100_BRUTUS
        bool "Brutus"
-       depends on ARCH_SA1100
        help
          Say Y here if you are using the Intel(R) StrongARM(R) SA-1100
          Microprocessor Development Board (also known as the Brutus).
 
 config SA1100_CERF
        bool "CerfBoard"
-       depends on ARCH_SA1100
        help
          The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued).
          More information is available at:
@@ -62,7 +59,6 @@ endchoice
 
 config SA1100_H3100
        bool "Compaq iPAQ H3100"
-       depends on ARCH_SA1100
        help
          Say Y here if you intend to run this kernel on the Compaq iPAQ
          H3100 handheld computer.  Information about this machine and the
@@ -73,7 +69,6 @@ config SA1100_H3100
 
 config SA1100_H3600
        bool "Compaq iPAQ H3600/H3700"
-       depends on ARCH_SA1100
        help
          Say Y here if you intend to run this kernel on the Compaq iPAQ
          H3600 handheld computer.  Information about this machine and the
@@ -84,7 +79,6 @@ config SA1100_H3600
 
 config SA1100_H3800
        bool "Compaq iPAQ H3800"
-       depends on ARCH_SA1100
        help
          Say Y here if you intend to run this kernel on the Compaq iPAQ H3800
          series handheld computer.  Information about this machine and the
@@ -102,7 +96,6 @@ config SA1100_H3XXX
 #dep_bool '  Empeg' CONFIG_SA1100_EMPEG $CONFIG_ARCH_SA1100
 config SA1100_EXTENEX1
        bool "Extenex HandHeld Theater (Squashtail)"
-       depends on ARCH_SA1100
 
 config SA1100_EXTENEX1_16MB
        bool "Support 16 MB of DRAM (not just 8)"
@@ -110,7 +103,6 @@ config SA1100_EXTENEX1_16MB
 
 config SA1100_FLEXANET
        bool "FlexaNet"
-       depends on ARCH_SA1100
        help
          Say Y here if you intend to run this kernel on the FlexaNet
          handheld instruments. Information about this machine can be
@@ -118,14 +110,12 @@ config SA1100_FLEXANET
 
 config SA1100_FREEBIRD
        bool "FreeBird-v1.1"
-       depends on ARCH_SA1100
        help
          Support the FreeBird board used in Coventive embedded products.  See
          Documentation/arm/SA1100/Freebird for more.
 
 config SA1100_GRAPHICSCLIENT
        bool "GraphicsClient Plus"
-       depends on ARCH_SA1100
        help
          Say Y here if you are using an Applied Data Systems Intel(R)
          StrongARM(R) SA-1100 based Graphics Client SBC.  See
@@ -133,7 +123,6 @@ config SA1100_GRAPHICSCLIENT
 
 config SA1100_GRAPHICSMASTER
        bool "GraphicsMaster"
-       depends on ARCH_SA1100
        help
          Say Y here if you are using an Applied Data Systems Intel(R)
          StrongARM(R) SA-1100 based Graphics Master SBC with SA-1111
@@ -143,14 +132,12 @@ config SA1100_GRAPHICSMASTER
 
 config SA1100_BADGE4
        bool "HP Labs BadgePAD 4"
-       depends on ARCH_SA1100
        help
          Say Y here if you want to build a kernel for the HP Laboratories
          BadgePAD 4.
 
 config SA1100_JORNADA720
        bool "HP Jornada 720"
-       depends on ARCH_SA1100
        help
          Say Y here if you want to build a kernel for the HP Jornada 720
          handheld computer.  See <http://www.hp.com/jornada/products/720>
@@ -158,14 +145,12 @@ config SA1100_JORNADA720
 
 config SA1100_HACKKIT
        bool "HackKit Core CPU Board"
-       depends on ARCH_SA1100
        help
          Say Y here to support the HackKit Core CPU Board
          <http://hackkit.eletztrick.de>;
 
 config SA1100_HUW_WEBPANEL
        bool "HuW WebPanel"
-       depends on ARCH_SA1100
        help
          Say Y here to support the HuW Webpanel produced by Hoeft & Wessel
          AG.  English-language website is at
@@ -174,7 +159,6 @@ config SA1100_HUW_WEBPANEL
 
 config SA1100_ITSY
        bool "Itsy"
-       depends on ARCH_SA1100
        help
          Say Y here if you are using the Compaq Itsy experimental pocket
          computer. See <http://research.compaq.com/wrl/projects/itsy/> for
@@ -182,7 +166,6 @@ config SA1100_ITSY
 
 config SA1100_LART
        bool "LART"
-       depends on ARCH_SA1100
        help
          Say Y here if you are using the Linux Advanced Radio Terminal
          (also known as the LART).  See <http://www.lart.tudelft.nl/> for
@@ -190,7 +173,6 @@ config SA1100_LART
 
 config SA1100_NANOENGINE
        bool "nanoEngine"
-       depends on ARCH_SA1100
        help
          The nanoEngine is a StrongARM 1110-based single board computer
          from Bright Star Engineering. More information is available at:
@@ -201,14 +183,12 @@ config SA1100_NANOENGINE
 
 config SA1100_OMNIMETER
        bool "OmniMeter"
-       depends on ARCH_SA1100
        help
          Say Y here if you are using the inhand electronics OmniMeter.  See
          <http://www.inhandelectronics.com/omnimeter.asp> for details.
 
 config SA1100_PANGOLIN
        bool "Pangolin"
-       depends on ARCH_SA1100
        help
          Pangolin is a StrongARM 1110-based evaluation platform produced
          by Dialogue Technology.  It has EISA slots for ease of configuration
@@ -220,7 +200,6 @@ config SA1100_PANGOLIN
 
 config SA1100_PLEB
        bool "PLEB"
-       depends on ARCH_SA1100
        help
          Say Y here if you are using a Portable Linux Embedded Board
          (also known as PLEB). See <http://www.cse.unsw.edu.au/~pleb/>
@@ -228,7 +207,6 @@ config SA1100_PLEB
 
 config SA1100_PT_SYSTEM3
        bool "PT System 3"
-       depends on ARCH_SA1100
        help
          Say Y here if you intend to build a kernel suitable to run on
          a Pruftechnik Digital Board. For more information see
@@ -236,7 +214,6 @@ config SA1100_PT_SYSTEM3
 
 config SA1100_SHANNON
        bool "Shannon"
-       depends on ARCH_SA1100
        help
          The Shannon (also known as a Tuxscreen, and also as a IS2630) was a
          limited edition webphone produced by Philips. The Shannon is a SA1100
@@ -245,7 +222,6 @@ config SA1100_SHANNON
 
 config SA1100_SHERMAN
        bool "Sherman"
-       depends on ARCH_SA1100
        help
          Say Y here to support the Blazie Engineering `Sherman' StrongARM
          1110-based SBC, used primarily in assistance products for the
@@ -255,7 +231,6 @@ config SA1100_SHERMAN
 
 config SA1100_SIMPAD
        bool "Simpad"
-       depends on ARCH_SA1100
        help
          The SIEMENS webpad SIMpad is based on the StrongARM 1110. There
          are two different versions CL4 and SL4. CL4 has 32MB RAM and 16MB
@@ -266,7 +241,6 @@ config SA1100_SIMPAD
 
 config SA1100_PFS168
        bool "Tulsa"
-       depends on ARCH_SA1100
        help
          The Radisys Corp. PFS-168 (aka Tulsa) is an Intel® StrongArm® SA-1110 based
          computer which includes the SA-1111 Microprocessor Companion Chip and other
@@ -276,7 +250,6 @@ config SA1100_PFS168
 
 config SA1100_VICTOR
        bool "Victor"
-       depends on ARCH_SA1100
        help
          Say Y here if you are using a Visu Aide Intel(R) StrongARM(R)
          SA-1100 based Victor Digital Talking Book Reader.  See
@@ -285,14 +258,12 @@ config SA1100_VICTOR
 
 config SA1100_XP860
        bool "XP860"
-       depends on ARCH_SA1100
        help
          :: Config help missing ::
          :: 06 August 2002 ::
 
 config SA1100_YOPY
        bool "Yopy"
-       depends on ARCH_SA1100
        help
          Say Y here to support the Yopy PDA.  Product information at
          <http://www.yopy.com/>.  See Documentation/arm/SA1100/Yopy
@@ -300,14 +271,12 @@ config SA1100_YOPY
 
 config SA1100_STORK
        bool "Stork"
-       depends on ARCH_SA1100
        help
          Say Y here if you intend to run this kernel on the Stork
          handheld computer.
 
 #config SA1100_TRIZEPS
 #      bool "Trizeps"
-#      depends on ARCH_SA1100
 #      help
 #        :: write me ::
 
@@ -319,7 +288,6 @@ config SA1100_STORK
 
 config SA1100_SSP
        tristate "Generic PIO SSP"
-       depends on ARCH_SA1100
        help
          Say Y here to enable support for the generic PIO SSP driver.
          This isn't for audio support, but for attached sensors and
@@ -328,7 +296,6 @@ config SA1100_SSP
 
 config SA1100_USB
        tristate "SA1100 USB function support"
-       depends on ARCH_SA1100
 
 config SA1100_USB_NETLINK
        tristate "Support for SA11x0 USB network link function"
@@ -349,3 +316,4 @@ config H3600_SLEEVE
 
 endmenu
 
+endif
index 6648d46..be5dd86 100644 (file)
@@ -230,8 +230,9 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy)
 }
 
 static struct cpufreq_driver sa1100_driver = {
-       .flags          = (CPUFREQ_PANIC_OUTOFSYNC | 
-                          CPUFREQ_PANIC_RESUME_OUTOFSYNC),
+       .flags          = CPUFREQ_STICKY |
+                         CPUFREQ_PANIC_OUTOFSYNC | 
+                         CPUFREQ_PANIC_RESUME_OUTOFSYNC,
        .verify         = sa11x0_verify_speed,
        .target         = sa1100_target,
        .get            = sa11x0_getspeed,
index b17ca12..62a4dbc 100644 (file)
@@ -329,8 +329,9 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy)
 }
 
 static struct cpufreq_driver sa1110_driver = {
-       .flags          = (CPUFREQ_PANIC_OUTOFSYNC | 
-                          CPUFREQ_PANIC_RESUME_OUTOFSYNC),
+       .flags          = CPUFREQ_STICKY |
+                         CPUFREQ_PANIC_OUTOFSYNC | 
+                         CPUFREQ_PANIC_RESUME_OUTOFSYNC,
        .verify         = sa11x0_verify_speed,
        .target         = sa1110_target,
        .get            = sa11x0_getspeed,
index fbf6db8..ff886e3 100644 (file)
@@ -2,4 +2,4 @@
 # Makefile for the linux kernel.
 #
 
-obj-y                                  := core.o
+obj-y                                  := core.o clock.o
index 81485b5..d03940c 100644 (file)
@@ -8,6 +8,7 @@
  * 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/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -75,7 +76,7 @@ no_pmd:
        return 0;
 }
 
-void __flush_dcache_page(struct page *page)
+static void __flush_dcache_page(struct page *page)
 {
        struct address_space *mapping = page_mapping(page);
        struct mm_struct *mm = current->active_mm;
@@ -111,6 +112,17 @@ void __flush_dcache_page(struct page *page)
        flush_dcache_mmap_unlock(mapping);
 }
 
+void flush_dcache_page(struct page *page)
+{
+       struct address_space *mapping = page_mapping(page);
+
+       if (mapping && !mapping_mapped(mapping))
+               set_bit(PG_dcache_dirty, &page->flags);
+       else
+               __flush_dcache_page(page);
+}
+EXPORT_SYMBOL(flush_dcache_page);
+
 static void
 make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, int dirty)
 {
index c306fc4..c000617 100644 (file)
@@ -348,7 +348,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
        if (pmd_none(*pmd_k))
                goto bad_area;
 
-       set_pmd(pmd, *pmd_k);
+       copy_pmd(pmd, pmd_k);
        return 0;
 
 bad_area:
index eec9d7b..32c4b0e 100644 (file)
@@ -40,7 +40,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
         */
        cache_type = read_cpuid(CPUID_CACHETYPE);
        if (cache_type != read_cpuid(CPUID_ID)) {
-               aliasing = (cache_type | cache_type >> 12) & (1 << 9);
+               aliasing = (cache_type | cache_type >> 12) & (1 << 11);
                if (aliasing)
                        do_align = filp || flags & MAP_SHARED;
        }
index e73c748..8df666f 100644 (file)
@@ -14,8 +14,6 @@
 #include <asm/proc-fns.h>
 #include <asm/tlbflush.h>
 
-EXPORT_SYMBOL(__flush_dcache_page);
-
 #ifndef MULTI_CPU
 EXPORT_SYMBOL(cpu_dcache_clean_area);
 EXPORT_SYMBOL(cpu_set_pte);
@@ -28,7 +26,6 @@ EXPORT_SYMBOL_NOVERS(__cpuc_flush_kern_all);
 EXPORT_SYMBOL_NOVERS(__cpuc_flush_user_all);
 EXPORT_SYMBOL_NOVERS(__cpuc_flush_user_range);
 EXPORT_SYMBOL_NOVERS(__cpuc_coherent_kern_range);
-EXPORT_SYMBOL_NOVERS(__cpuc_flush_dcache_page);
 #else
 EXPORT_SYMBOL(cpu_cache);
 #endif
index 2a594d2..2ecfdfd 100644 (file)
@@ -6,7 +6,7 @@
 # To add an entry into this database, please see Documentation/arm/README,
 # or contact rmk@arm.linux.org.uk
 #
-# Last update: Thu Apr 29 19:06:33 2004
+# Last update: Fri May 28 13:17:46 2004
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -509,7 +509,7 @@ s3c5500                     MACH_S3C5500            S3C5500                 498
 smdk5500               MACH_SMDK5500           SMDK5500                499
 signalsync             MACH_SIGNALSYNC         SIGNALSYNC              500
 nbc                    MACH_NBC                NBC                     501
-er4525                 MACH_ER4525             ER4525                  502
+kodiak                 MACH_KODIAK             KODIAK                  502
 netbookpro             MACH_NETBOOKPRO         NETBOOKPRO              503
 hw90200                        MACH_HW90200            HW90200                 504
 condor                 MACH_CONDOR             CONDOR                  505
@@ -533,3 +533,16 @@ emc1000                    MACH_EMC1000            EMC1000                 522
 tidsc25                        MACH_TIDSC25            TIDSC25                 523
 akcpmxl                        MACH_AKCPMXL            AKCPMXL                 524
 av3xx                  MACH_AV3XX              AV3XX                   525
+avila                  MACH_AVILA              AVILA                   526
+pxa_mpm10              MACH_PXA_MPM10          PXA_MPM10               527
+pxa_kyanite            MACH_PXA_KYANITE        PXA_KYANITE             528
+sgold                  MACH_SGOLD              SGOLD                   529
+oscar                  MACH_OSCAR              OSCAR                   530
+epxa4usb2              MACH_EPXA4USB2          EPXA4USB2               531
+xsengine               MACH_XSENGINE           XSENGINE                532
+ip600                  MACH_IP600              IP600                   533
+mcan2                  MACH_MCAN2              MCAN2                   534
+ddi_blueridge          MACH_DDI_BLUERIDGE      DDI_BLUERIDGE           535
+skyminder              MACH_SKYMINDER          SKYMINDER               536
+lpd79520               MACH_LPD79520           LPD79520                537
+edb9302                        MACH_EDB9302            EDB9302                 538
index d40e768..5b51023 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/init_task.h>
+#include <linux/mqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
index e13b754..f258c00 100644 (file)
@@ -1396,8 +1396,8 @@ e100_close(struct net_device *dev)
 static int
 e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
-       struct net_local *np = (struct net_local *)dev->priv;
+       struct mii_ioctl_data *data = if_mii(ifr);
+       struct net_local *np = netdev_priv(dev);
 
        spin_lock(&np->lock); /* Preempt protection */
        switch (cmd) {
index c4992bf..9f7cad7 100644 (file)
 #include <linux/fs.h>
 #include <linux/user.h>
 #include <linux/elfcore.h>
+#include <linux/mqueue.h>
 
 //#define DEBUG
 
index 072192a..8497cfb 100644 (file)
@@ -223,7 +223,7 @@ config GDB_DEBUG
 
 config CONFIG_SH_STANDARD_BIOS
        bool "Use gdb protocol serial console"
-       depends on (!H8300H_SIM && H8S_SIM)
+       depends on (!H8300H_SIM && !H8S_SIM)
        help
          serial console output using GDB protocol.
          Require eCos/RedBoot
index 6a8e747..19272c2 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/init_task.h>
 #include <linux/fs.h>
+#include <linux/mqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
index 0843013..5905cee 100644 (file)
@@ -116,18 +116,36 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                case PTRACE_PEEKUSR: {
                        unsigned long tmp;
                        
-                       if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
+                       if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) {
                                ret = -EIO;
+                               break ;
+                       }
                        
-                       tmp = 0;  /* Default return condition */
+                       ret = 0;  /* Default return condition */
                        addr = addr >> 2; /* temporary hack. */
+
                        if (addr < H8300_REGS_NO)
                                tmp = h8300_get_reg(child, addr);
                        else {
-                               ret = -EIO;
-                               break ;
+                               switch(addr) {
+                               case 49:
+                                       tmp = child->mm->start_code;
+                                       break ;
+                               case 50:
+                                       tmp = child->mm->start_data;
+                                       break ;
+                               case 51:
+                                       tmp = child->mm->end_code;
+                                       break ;
+                               case 52:
+                                       tmp = child->mm->end_data;
+                                       break ;
+                               default:
+                                       ret = -EIO;
+                               }
                        }
-                       ret = put_user(tmp,(unsigned long *) data);
+                       if (!ret)
+                               ret = put_user(tmp,(unsigned long *) data);
                        break ;
                }
 
index 9df1201..68e5cae 100644 (file)
@@ -83,6 +83,7 @@
        mov.l   @(LER0-LER1:16,sp),er1          /* restore ER0 */
        mov.l   er1,@er0
        mov.w   @(LEXR-LER1:16,sp),r1           /* restore EXR */
+       mov.b   r1l,r1h
        mov.w   r1,@(8:16,er0)
        mov.w   @(LCCR-LER1:16,sp),r1           /* restore the RET addr */
        mov.b   r1l,r1h
@@ -214,7 +215,6 @@ SYMBOL_NAME_LABEL(system_call)
        jsr     @SYMBOL_NAME(syscall_trace)
        bra     SYMBOL_NAME(ret_from_exception):8
 
-
 SYMBOL_NAME_LABEL(ret_from_fork)
        mov.l   er2,er0
        jsr     @SYMBOL_NAME(schedule_tail)
index dc04954..e8cd46f 100644 (file)
@@ -23,7 +23,7 @@
 static const int h8300_register_offset[] = {
        PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4),
        PT_REG(er5), PT_REG(er6), PT_REG(er0), PT_REG(orig_er0),
-       PT_REG(ccr), PT_REG(pc), PT_REG(exr)
+       PT_REG(ccr), PT_REG(pc),  0,           PT_REG(exr)
 };
 
 /* read register */
index c46596c..afd6c26 100644 (file)
@@ -65,6 +65,8 @@ config X86_VOYAGER
 
 config X86_NUMAQ
        bool "NUMAQ (IBM/Sequent)"
+       select DISCONTIGMEM
+       select NUMA
        help
          This option is used for getting Linux to run on a (IBM/Sequent) NUMA 
          multiquad box. This changes the way that processors are bootstrapped,
@@ -482,7 +484,8 @@ config HPET_TIMER
          Choose N to continue using the legacy 8254 timer.
 
 config HPET_EMULATE_RTC
-       def_bool HPET_TIMER && RTC=y
+       bool "Provide RTC interrupt"
+       depends on HPET_TIMER && RTC=y
 
 config SMP
        bool "Symmetric multi-processing support"
@@ -596,6 +599,7 @@ config X86_TSC
 
 config X86_MCE
        bool "Machine Check Exception"
+       depends on !X86_VOYAGER
        ---help---
          Machine Check Exception support allows the processor to notify the
          kernel if it detects a problem (e.g. overheating, component failure).
@@ -871,7 +875,7 @@ config EFI
        This option is only useful on systems that have EFI firmware
        and will result in a kernel image that is ~8k larger.  In addition,
        you must use the latest ELILO loader available at
-       <ftp://ftp.hpl.hp.com/pub/linux-ia64/> in order to take advantage of
+       <http://elilo.sourceforge.net> in order to take advantage of
        kernel initialization using EFI information (neither GRUB nor LILO know
        anything about EFI).  However, even with this option, the resultant
        kernel should continue to boot on existing non-EFI platforms.
@@ -1371,12 +1375,6 @@ config X86_TRAMPOLINE
        depends on X86_SMP || (X86_VOYAGER && SMP)
        default y
 
-# std_resources is overridden for pc9800, but that's not
-# a currently selectable arch choice
-config X86_STD_RESOURCES
-       bool
-       default y
-
 config PC
        bool
        depends on X86 && !EMBEDDED
index c2a9ab0..7257696 100644 (file)
@@ -18,8 +18,11 @@ CONFIG_STANDALONE=y
 #
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
 CONFIG_LOG_BUF_SHIFT=15
 CONFIG_HOTPLUG=y
 # CONFIG_IKCONFIG is not set
@@ -30,6 +33,7 @@ CONFIG_EPOLL=y
 CONFIG_IOSCHED_NOOP=y
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 
 #
@@ -88,6 +92,7 @@ CONFIG_X86_USE_PPRO_CHECKSUM=y
 # CONFIG_HPET_EMULATE_RTC is not set
 CONFIG_SMP=y
 CONFIG_NR_CPUS=8
+CONFIG_SCHED_SMT=y
 CONFIG_PREEMPT=y
 CONFIG_X86_LOCAL_APIC=y
 CONFIG_X86_IO_APIC=y
@@ -200,7 +205,7 @@ CONFIG_BINFMT_MISC=y
 #
 # Generic Driver Options
 #
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
 
 #
 # Memory Technology Devices (MTD)
@@ -259,7 +264,6 @@ CONFIG_BLK_DEV_IDE=y
 # CONFIG_BLK_DEV_HD_IDE is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -307,6 +311,7 @@ CONFIG_BLK_DEV_PIIX=y
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
 # CONFIG_IDE_CHIPSETS is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -332,7 +337,6 @@ CONFIG_CHR_DEV_SG=y
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
 # CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_REPORT_LUNS=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
 
@@ -354,6 +358,7 @@ CONFIG_SCSI_REPORT_LUNS=y
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+CONFIG_SCSI_DPT_I2O=m
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_MEGARAID is not set
@@ -361,7 +366,9 @@ CONFIG_SCSI_SATA=y
 # CONFIG_SCSI_SATA_SVW is not set
 CONFIG_SCSI_ATA_PIIX=y
 # CONFIG_SCSI_SATA_PROMISE is not set
+CONFIG_SCSI_SATA_SX4=m
 # CONFIG_SCSI_SATA_SIL is not set
+CONFIG_SCSI_SATA_SIS=m
 # CONFIG_SCSI_SATA_VIA is not set
 # CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
@@ -380,6 +387,9 @@ CONFIG_SCSI_ATA_PIIX=y
 # CONFIG_SCSI_IMM is not set
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
+CONFIG_SCSI_IPR=m
+# CONFIG_SCSI_IPR_TRACE is not set
+# CONFIG_SCSI_IPR_DUMP is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
@@ -484,8 +494,6 @@ CONFIG_IP_MULTICAST=y
 #
 # CONFIG_IP_VS is not set
 # CONFIG_IPV6 is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 
@@ -539,13 +547,17 @@ CONFIG_IP_NF_TARGET_TCPMSS=y
 CONFIG_IP_NF_ARPTABLES=y
 CONFIG_IP_NF_ARPFILTER=y
 CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_RAW=m
 
 #
 # 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
@@ -566,18 +578,23 @@ CONFIG_IP_NF_ARP_MANGLE=y
 # 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
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_NET_SB1000 is not set
 
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -619,7 +636,6 @@ CONFIG_8139TOO_PIO=y
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
 # CONFIG_8139_OLD_RX_RESET is not set
-CONFIG_8139_RXBUF_IDX=2
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
@@ -637,7 +653,6 @@ CONFIG_8139_RXBUF_IDX=2
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 
@@ -645,47 +660,31 @@ CONFIG_8139_RXBUF_IDX=2
 # Ethernet (10000 Mbit)
 #
 # CONFIG_IXGB is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
+CONFIG_S2IO=m
+# CONFIG_S2IO_NAPI is not set
 
 #
 # Token Ring devices
 #
 # CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
 
 #
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
+# Wireless LAN (non-hamradio)
 #
-# CONFIG_IRDA is not set
+# CONFIG_NET_RADIO is not set
 
 #
-# Bluetooth support
+# Wan interfaces
 #
-# CONFIG_BT is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP 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
 
 #
 # ISDN subsystem
@@ -803,6 +802,7 @@ CONFIG_AGP=y
 # CONFIG_AGP_AMD is not set
 # CONFIG_AGP_AMD64 is not set
 CONFIG_AGP_INTEL=y
+CONFIG_AGP_INTEL_MCH=m
 # CONFIG_AGP_NVIDIA is not set
 # CONFIG_AGP_SIS is not set
 # CONFIG_AGP_SWORKS is not set
@@ -978,6 +978,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_OHCI_HCD is not set
 CONFIG_USB_UHCI_HCD=y
 
@@ -1012,6 +1013,7 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
+CONFIG_USB_EGALAX=m
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
 
@@ -1061,6 +1063,8 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGETSERVO=m
 # CONFIG_USB_TEST is not set
 
 #
@@ -1110,6 +1114,7 @@ CONFIG_VFAT_FS=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
@@ -1152,7 +1157,6 @@ CONFIG_SUNRPC=y
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -1217,6 +1221,7 @@ CONFIG_OPROFILE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_FRAME_POINTER is not set
+CONFIG_4KSTACKS=y
 CONFIG_X86_FIND_SMP_CONFIG=y
 CONFIG_X86_MPPARSE=y
 
@@ -1234,8 +1239,10 @@ CONFIG_X86_MPPARSE=y
 # Library routines
 #
 CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
 CONFIG_X86_SMP=y
 CONFIG_X86_HT=y
 CONFIG_X86_BIOS_REBOOT=y
 CONFIG_X86_TRAMPOLINE=y
+CONFIG_X86_STD_RESOURCES=y
 CONFIG_PC=y
index 577be17..a056d50 100644 (file)
@@ -31,7 +31,6 @@ obj-$(CONFIG_ACPI_SRAT)       += srat.o
 obj-$(CONFIG_HPET_TIMER)       += time_hpet.o
 obj-$(CONFIG_EFI)              += efi.o efi_stub.o
 obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
-obj-$(CONFIG_X86_STD_RESOURCES)        += std_resources.o
 
 EXTRA_AFLAGS   := -traditional -m32
 
index fdb9b6c..7311327 100644 (file)
@@ -28,7 +28,9 @@
 #include <linux/acpi.h>
 #include <linux/efi.h>
 #include <linux/irq.h>
-#include <asm/pgalloc.h>
+#include <linux/module.h>
+
+#include <asm/pgtable.h>
 #include <asm/io_apic.h>
 #include <asm/apic.h>
 #include <asm/io.h>
@@ -437,6 +439,38 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
        return 0;
 }
 
+unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
+{
+       unsigned int irq;
+
+#ifdef CONFIG_PCI
+       /*
+        * Make sure all (legacy) PCI IRQs are set as level-triggered.
+        */
+       if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
+               static u16 irq_mask;
+               extern void eisa_set_level_irq(unsigned int irq);
+
+               if (edge_level == ACPI_LEVEL_SENSITIVE) {
+                       if ((gsi < 16) && !((1 << gsi) & irq_mask)) {
+                               Dprintk(KERN_DEBUG PREFIX "Setting GSI %u as level-triggered\n", gsi);
+                               irq_mask |= (1 << gsi);
+                               eisa_set_level_irq(gsi);
+                       }
+               }
+       }
+#endif
+
+#ifdef CONFIG_X86_IO_APIC
+       if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
+               mp_register_gsi(gsi, edge_level, active_high_low);
+       }
+#endif
+       acpi_gsi_to_irq(gsi, &irq);
+       return irq;
+}
+EXPORT_SYMBOL(acpi_register_gsi);
+
 static unsigned long __init
 acpi_scan_rsdp (
        unsigned long           start,
index 1df49f7..ecf2b63 100644 (file)
@@ -31,7 +31,6 @@
 #include <asm/smp.h>
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
-#include <asm/pgalloc.h>
 #include <asm/desc.h>
 #include <asm/arch_hooks.h>
 #include <asm/hpet.h>
@@ -81,6 +80,17 @@ void enable_NMI_through_LVT0 (void * dummy)
        apic_write_around(APIC_LVT0, v);
 }
 
+int get_physical_broadcast(void)
+{
+       unsigned int lvr, version;
+       lvr = apic_read(APIC_LVR);
+       version = GET_APIC_VERSION(lvr);
+       if (version >= 0x14)
+               return 0xff;
+       else
+               return 0xf;
+}
+
 int get_maxlvt(void)
 {
        unsigned int v, ver, maxlvt;
index 0b0237e..3f7caa4 100644 (file)
@@ -254,6 +254,7 @@ static int elanfreq_cpu_exit(struct cpufreq_policy *policy)
 static int __init elanfreq_setup(char *str)
 {
        max_freq = simple_strtoul(str, &str, 0);
+       printk(KERN_WARNING "You're using the deprecated elanfreq command line option. Use elanfreq.max_freq instead, please!\n");
        return 1;
 }
 __setup("elanfreq=", elanfreq_setup);
@@ -300,7 +301,7 @@ static void __exit elanfreq_exit(void)
 }
 
 
-MODULE_PARM (max_freq, "i");
+module_param (max_freq, int, 0444);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, Sven Geggus <sven@geggus.net>");
index 000aac1..fefaf45 100644 (file)
@@ -124,7 +124,7 @@ static int stock_freq;
 
 /* PCI bus clock - defaults to 30.000 if cpu_khz is not available */
 static int pci_busclk = 0;
-MODULE_PARM(pci_busclk, "i");
+module_param (pci_busclk, int, 0444);
 
 /* maximum duration for which the cpu may be suspended
  * (32us * MAX_DURATION). If no parameter is given, this defaults
@@ -133,7 +133,7 @@ MODULE_PARM(pci_busclk, "i");
  * is suspended -- processing power is just 0.39% of what it used to be,
  * though. 781.25 kHz(!) for a 200 MHz processor -- wow. */
 static int max_duration = 255;
-MODULE_PARM(max_duration, "i");
+module_param (max_duration, int, 0444);
 
 /* For the default policy, we want at least some processing power
  * - let's say 5%. (min = maxfreq / POLICY_MIN_DIV)
index 53145bb..57c0377 100644 (file)
 static unsigned int numscales=16, numvscales;
 static unsigned int fsb;
 static int minvid, maxvid;
+static unsigned int minmult, maxmult;
 static int can_scale_voltage;
 static int vrmrev;
 
 /* Module parameters */
 static int dont_scale_voltage;
 static int debug;
-static int debug;
 
-static void dprintk(const char *msg, ...)
+static void dprintk(const char *fmt, ...)
 {
-       if (debug == 1)
-               printk(msg);
+       char s[256];
+       va_list args;
+
+       if (debug == 0)
+               return;
+
+       va_start(args, fmt);
+       vsprintf(s, fmt, args);
+       printk(s);
+       va_end(args);
 }
 
 
@@ -62,7 +70,7 @@ static int longhaul_version;
 static struct cpufreq_frequency_table *longhaul_table;
 
 
-static unsigned int calc_speed (int mult, int fsb)
+static unsigned int calc_speed(int mult, int fsb)
 {
        int khz;
        khz = (mult/10)*fsb;
@@ -73,17 +81,13 @@ static unsigned int calc_speed (int mult, int fsb)
 }
 
 
-static int longhaul_get_cpu_mult (void)
+static int longhaul_get_cpu_mult(void)
 {
        unsigned long invalue=0,lo, hi;
 
        rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
        invalue = (lo & (1<<22|1<<23|1<<24|1<<25)) >>22;
-       if (longhaul_version==2) {
-               if (lo & (1<<27))
-                       invalue+=16;
-       }
-       if (longhaul_version==4) {
+       if (longhaul_version==2 || longhaul_version==3) {
                if (lo & (1<<27))
                        invalue+=16;
        }
@@ -98,7 +102,7 @@ static int longhaul_get_cpu_mult (void)
  * Sets a new clock ratio, and -if applicable- a new Front Side Bus
  */
 
-static void longhaul_setstate (unsigned int clock_ratio_index)
+static void longhaul_setstate(unsigned int clock_ratio_index)
 {
        int speed, mult;
        struct cpufreq_freqs freqs;
@@ -162,7 +166,7 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
                longhaul.bits.RevisionKey = 3;
                wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
                break;
-       case 4:
+       case 3:
                rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
                longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
                longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
@@ -194,7 +198,7 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
 
 #define ROUNDING       0xf
 
-static int _guess (int guess, int maxmult)
+static int _guess(int guess)
 {
        int target;
 
@@ -207,7 +211,7 @@ static int _guess (int guess, int maxmult)
 }
 
 
-static int guess_fsb(int maxmult)
+static int guess_fsb(void)
 {
        int speed = (cpu_khz/1000);
        int i;
@@ -217,25 +221,25 @@ static int guess_fsb(int maxmult)
        speed &= ~ROUNDING;
 
        for (i=0; i<3; i++) {
-               if (_guess(speeds[i],maxmult) == speed)
+               if (_guess(speeds[i]) == speed)
                        return speeds[i];
        }
        return 0;
 }
 
 
-static int __init longhaul_get_ranges (void)
+static int __init longhaul_get_ranges(void)
 {
        struct cpuinfo_x86 *c = cpu_data;
-       unsigned long invalue,invalue2;
-       unsigned int minmult=0, maxmult=0;
+       unsigned long invalue;
        unsigned int multipliers[32]= {
                50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65,
                -1,110,120,-1,135,115,125,105,130,150,160,140,-1,155,-1,145 };
        unsigned int j, k = 0;
        union msr_longhaul longhaul;
        unsigned long lo, hi;
-       unsigned int eblcr_fsb_table[] = { 66, 133, 100, -1 };
+       unsigned int eblcr_fsb_table_v1[] = { 66, 133, 100, -1 };
+       unsigned int eblcr_fsb_table_v2[] = { 133, 100, -1, 66 };
 
        switch (longhaul_version) {
        case 1:
@@ -246,9 +250,9 @@ static int __init longhaul_get_ranges (void)
                rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
                invalue = (lo & (1<<18|1<<19)) >>18;
                if (c->x86_model==6)
-                       fsb = eblcr_fsb_table[invalue];
+                       fsb = eblcr_fsb_table_v1[invalue];
                else
-                       fsb = guess_fsb(maxmult);
+                       fsb = guess_fsb();
                break;
 
        case 2:
@@ -265,53 +269,38 @@ static int __init longhaul_get_ranges (void)
                else
                        minmult = multipliers[invalue];
 
-               switch (longhaul.bits.MaxMHzFSB) {
-               case 0x0:       fsb=133;
-                               break;
-               case 0x1:       fsb=100;
-                               break;
-               case 0x2:       printk (KERN_INFO PFX "Invalid (reserved) FSB!\n");
-                       return -EINVAL;
-               case 0x3:       fsb=66;
-                               break;
-               }
+               fsb = eblcr_fsb_table_v2[longhaul.bits.MaxMHzFSB];
                break;
 
-       case 4:
+       case 3:
                rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
 
-               //TODO: Nehemiah may have borken MaxMHzBR.
-               // need to extrapolate from FSB.
-
-               invalue2 = longhaul.bits.MinMHzBR;
-               invalue = longhaul.bits.MaxMHzBR;
-               if (longhaul.bits.MaxMHzBR4)
-                       invalue += 16;
-               maxmult=multipliers[invalue];
-
-               maxmult=longhaul_get_cpu_mult();
-
-               printk(KERN_INFO PFX " invalue: %ld  maxmult: %d \n", invalue, maxmult);
-               printk(KERN_INFO PFX " invalue2: %ld \n", invalue2);
-
+               /*
+                * TODO: This code works, but raises a lot of questions.
+                * - Some Nehemiah's seem to have broken Min/MaxMHzBR's.
+                *   We get around this by using a hardcoded multiplier of 5.0x
+                *   for the minimimum speed, and the speed we booted up at for the max.
+                *   This is done in longhaul_get_cpu_mult() by reading the EBLCR register.
+                * - According to some VIA documentation EBLCR is only
+                *   in pre-Nehemiah C3s. How this still works is a mystery.
+                *   We're possibly using something undocumented and unsupported,
+                *   But it works, so we don't grumble.
+                */
                minmult=50;
+               maxmult=longhaul_get_cpu_mult();
 
-               switch (longhaul.bits.MaxMHzFSB) {
-               case 0x0:       fsb=133;
-                               break;
-               case 0x1:       fsb=100;
-                               break;
-               case 0x2:       printk (KERN_INFO PFX "Invalid (reserved) FSB!\n");
-                       return -EINVAL;
-               case 0x3:       fsb=66;
-                               break;
-               }
-
+               fsb = eblcr_fsb_table_v2[longhaul.bits.MaxMHzFSB];
                break;
        }
 
        dprintk (KERN_INFO PFX "MinMult=%d.%dx MaxMult=%d.%dx\n",
                 minmult/10, minmult%10, maxmult/10, maxmult%10);
+
+       if (fsb == -1) {
+               printk (KERN_INFO PFX "Invalid (reserved) FSB!\n");
+               return -EINVAL;
+       }
+
        highest_speed = calc_speed (maxmult, fsb);
        lowest_speed = calc_speed (minmult,fsb);
        dprintk (KERN_INFO PFX "FSB: %dMHz Lowestspeed=%dMHz Highestspeed=%dMHz\n",
@@ -413,7 +402,7 @@ static int longhaul_verify(struct cpufreq_policy *policy)
 }
 
 
-static int longhaul_target (struct cpufreq_policy *policy,
+static int longhaul_target(struct cpufreq_policy *policy,
                            unsigned int target_freq,
                            unsigned int relation)
 {
@@ -437,7 +426,7 @@ static unsigned int longhaul_get(unsigned int cpu)
        return (calc_speed (longhaul_get_cpu_mult(), fsb));
 }
 
-static int __init longhaul_cpu_init (struct cpufreq_policy *policy)
+static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
 {
        struct cpuinfo_x86 *c = cpu_data;
        char *cpuname=NULL;
@@ -480,7 +469,7 @@ static int __init longhaul_cpu_init (struct cpufreq_policy *policy)
                break;
 
        case 9:
-               longhaul_version=4;
+               longhaul_version=3;
                numscales=32;
                switch (c->x86_mask) {
                case 0 ... 1:
@@ -551,7 +540,7 @@ static struct cpufreq_driver longhaul_driver = {
        .attr   = longhaul_attr,
 };
 
-static int __init longhaul_init (void)
+static int __init longhaul_init(void)
 {
        struct cpuinfo_x86 *c = cpu_data;
 
@@ -568,8 +557,17 @@ static int __init longhaul_init (void)
        return -ENODEV;
 }
 
-static void __exit longhaul_exit (void)
+static void __exit longhaul_exit(void)
 {
+       int i=0;
+       unsigned int new_clock_ratio;
+
+       while (clock_ratio[i] != maxmult)
+               i++;
+
+       new_clock_ratio = longhaul_table[i].index & 0xFF;
+       longhaul_setstate(new_clock_ratio);
+
        cpufreq_unregister_driver(&longhaul_driver);
        kfree(longhaul_table);
 }
index b5daecc..fa01a95 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/smp.h>
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
+#include <linux/cpumask.h>
 
 #include <asm/processor.h> 
 #include <asm/msr.h>
@@ -132,34 +133,28 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy,
 #endif
 
        /* notifiers */
-       for_each_cpu(i) {
-               if (cpu_isset(i, affected_cpu_map)) {
-                       freqs.cpu = i;
-                       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-               }
+       for_each_cpu_mask(i, affected_cpu_map) {
+               freqs.cpu = i;
+               cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
        }
 
        /* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software
         * Developer's Manual, Volume 3 
         */
-       for_each_cpu(i) {
-               if (cpu_isset(i, affected_cpu_map)) {
-                       cpumask_t this_cpu = cpumask_of_cpu(i);
+       for_each_cpu_mask(i, affected_cpu_map) {
+               cpumask_t this_cpu = cpumask_of_cpu(i);
 
-                       set_cpus_allowed(current, this_cpu);
-                       BUG_ON(smp_processor_id() != i);
+               set_cpus_allowed(current, this_cpu);
+               BUG_ON(smp_processor_id() != i);
 
-                       cpufreq_p4_setdc(i, p4clockmod_table[newstate].index);
-               }
+               cpufreq_p4_setdc(i, p4clockmod_table[newstate].index);
        }
        set_cpus_allowed(current, cpus_allowed);
 
        /* notifiers */
-       for_each_cpu(i) {
-               if (cpu_isset(i, affected_cpu_map)) {
-                       freqs.cpu = i;
-                       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-               }
+       for_each_cpu_mask(i, affected_cpu_map) {
+               freqs.cpu = i;
+               cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
        }
 
        return 0;
index cf008b4..7aefc67 100644 (file)
@@ -28,7 +28,7 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#ifdef CONFIG_ACPI_PROCESSOR
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
 #include <linux/acpi.h>
 #include <acpi/processor.h>
 #endif
@@ -63,7 +63,7 @@ struct pst_s {
        u8 numpstates;
 };
 
-#ifdef CONFIG_ACPI_PROCESSOR
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
 union powernow_acpi_control_t {
        struct {
                unsigned long fid:5,
@@ -293,7 +293,7 @@ static void change_speed (unsigned int index)
 }
 
 
-#ifdef CONFIG_ACPI_PROCESSOR
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
 
 struct acpi_processor_performance *acpi_processor_perf;
 
@@ -642,7 +642,7 @@ static int __init powernow_init (void)
 
 static void __exit powernow_exit (void)
 {
-#ifdef CONFIG_ACPI_PROCESSOR
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
        if (acpi_processor_perf) {
                acpi_processor_unregister_performance(acpi_processor_perf, 0);
                kfree(acpi_processor_perf);
index 63737e8..20d875d 100644 (file)
@@ -733,10 +733,22 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
                        continue;
                }
 
-               /* verify only 1 entry from the lo frequency table */
-               if ((fid < HI_FID_TABLE_BOTTOM) && (cntlofreq++)) {
-                       printk(KERN_ERR PFX "Too many lo freq table entries\n");
-                       goto err_out_mem;
+               if (fid < HI_FID_TABLE_BOTTOM) {
+                       if (cntlofreq) {
+                               /* if both entries are the same, ignore this
+                                * one... 
+                                */
+                               if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) ||
+                                   (powernow_table[i].index != powernow_table[cntlofreq].index)) {
+                                       printk(KERN_ERR PFX "Too many lo freq table entries\n");
+                                       goto err_out_mem;
+                               }
+                               
+                               dprintk(KERN_INFO PFX "double low frequency table entry, ignoring it.\n");
+                               powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+                               continue;
+                       } else
+                               cntlofreq = i;
                }
 
                if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
@@ -857,12 +869,9 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
 
        if (smp_processor_id() != pol->cpu) {
                printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
-               goto sched_out;
+               goto err_out;
        }
 
-       /* from this point, do not exit without restoring preempt and cpu */
-       preempt_disable();
-
        if (pending_bit_stuck()) {
                printk(KERN_ERR PFX "failing targ, change pending bit set\n");
                goto err_out;
@@ -900,8 +909,6 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
        ret = 0;
 
 err_out:
-       preempt_enable_no_resched();
-sched_out:
        set_cpus_allowed(current, oldmask);
        schedule();
 
@@ -1017,7 +1024,7 @@ err_out:
        return -ENODEV;
 }
 
-static int __exit powernowk8_cpu_exit (struct cpufreq_policy *pol)
+static int powernowk8_cpu_exit (struct cpufreq_policy *pol)
 {
        struct powernow_k8_data *data = powernow_data[pol->cpu];
 
@@ -1069,7 +1076,7 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
        .verify = powernowk8_verify,
        .target = powernowk8_target,
        .init = powernowk8_cpu_init,
-       .exit = powernowk8_cpu_exit,
+       .exit = __devexit_p(powernowk8_cpu_exit),
        .get = powernowk8_get,
        .name = "powernow-k8",
        .owner = THIS_MODULE,
@@ -1098,7 +1105,7 @@ static int __init powernowk8_init(void)
 }
 
 /* driver entry point for term */
-static void __exit powernowk8_exit(void)
+static void powernowk8_exit(void)
 {
        dprintk(KERN_INFO PFX "exit\n");
 
index 466fc65..93b70f0 100644 (file)
@@ -67,28 +67,19 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
 /**
  * speedstep_set_state - set the SpeedStep state
  * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
- * @notify: whether to call cpufreq_notify_transition for CPU speed changes
  *
  *   Tries to change the SpeedStep state. 
  */
-static void speedstep_set_state (unsigned int state, unsigned int notify)
+static void speedstep_set_state (unsigned int state)
 {
        u32                     pmbase;
        u8                      pm2_blk;
        u8                      value;
        unsigned long           flags;
-       struct cpufreq_freqs    freqs;
 
        if (!speedstep_chipset_dev || (state > 0x1))
                return;
 
-       freqs.old = speedstep_get_processor_frequency(speedstep_processor);
-       freqs.new = speedstep_freqs[state].frequency;
-       freqs.cpu = 0; /* speedstep.c is UP only driver */
-       
-       if (notify)
-               cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
        /* get PMBASE */
        pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
        if (!(pmbase & 0x01))
@@ -143,9 +134,6 @@ static void speedstep_set_state (unsigned int state, unsigned int notify)
                printk (KERN_ERR "cpufreq: change failed - I/O error\n");
        }
 
-       if (notify)
-               cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
        return;
 }
 
@@ -252,11 +240,47 @@ static int speedstep_target (struct cpufreq_policy *policy,
                             unsigned int relation)
 {
        unsigned int    newstate = 0;
+       struct cpufreq_freqs freqs;
+       cpumask_t cpus_allowed, affected_cpu_map;
+       int i;
 
        if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate))
                return -EINVAL;
 
-       speedstep_set_state(newstate, 1);
+       /* no transition necessary */
+       if (freqs.old == freqs.new)
+               return 0;
+
+       freqs.old = speedstep_get_processor_frequency(speedstep_processor);
+       freqs.new = speedstep_freqs[newstate].frequency;
+       freqs.cpu = policy->cpu;
+
+       cpus_allowed = current->cpus_allowed;
+
+       /* only run on CPU to be set, or on its sibling */
+#ifdef CONFIG_SMP
+       affected_cpu_map = cpu_sibling_map[policy->cpu];
+#else
+       affected_cpu_map = cpumask_of_cpu(policy->cpu);
+#endif
+
+       for_each_cpu_mask(i, affected_cpu_map) {
+               freqs.cpu = i;
+               cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+       }
+
+       /* switch to physical CPU where state is to be changed */
+       set_cpus_allowed(current, affected_cpu_map);
+
+       speedstep_set_state(newstate);
+
+       /* allow to be run on all CPUs */
+       set_cpus_allowed(current, cpus_allowed);
+
+       for_each_cpu_mask(i, affected_cpu_map) {
+               freqs.cpu = i;
+               cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+       }
 
        return 0;
 }
@@ -279,21 +303,35 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
 {
        int             result = 0;
        unsigned int    speed;
+       cpumask_t       cpus_allowed,affected_cpu_map;
+
 
        /* capability check */
-       if (policy->cpu != 0)
+       if (policy->cpu != 0) /* FIXME: better support for SMT in cpufreq core. Up until then, it's better to register only one CPU */
                return -ENODEV;
 
+       /* only run on CPU to be set, or on its sibling */
+       cpus_allowed = current->cpus_allowed;
+#ifdef CONFIG_SMP
+       affected_cpu_map = cpu_sibling_map[policy->cpu];
+#else
+       affected_cpu_map = cpumask_of_cpu(policy->cpu);
+#endif
+       set_cpus_allowed(current, affected_cpu_map);
+
        /* detect low and high frequency */
        result = speedstep_get_freqs(speedstep_processor,
                                     &speedstep_freqs[SPEEDSTEP_LOW].frequency,
                                     &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
                                     &speedstep_set_state);
-       if (result)
+       if (result) {
+               set_cpus_allowed(current, cpus_allowed);
                return result;
+       }
 
        /* get current speed setting */
        speed = speedstep_get_processor_frequency(speedstep_processor);
+       set_cpus_allowed(current, cpus_allowed);
        if (!speed)
                return -EIO;
 
index 3305a84..82f7c02 100644 (file)
@@ -252,11 +252,10 @@ unsigned int speedstep_detect_processor (void)
                         * specific.
                         * M-P4-Ms may have either ebx=0xe or 0xf [see above]
                         * M-P4/533 have either ebx=0xe or 0xf. [25317607.pdf]
-                        * So, how to distinguish all those processors with
-                        * ebx=0xf? I don't know. Sort them out, and wait
-                        * for someone to complain.
+                        * also, M-P4M HTs have ebx=0x8, too
+                        * For now, they are distinguished by the model_id string
                         */
-                       if (ebx == 0x0e)
+                       if ((ebx == 0x0e) || (strstr(c->x86_model_id,"Mobile Intel(R) Pentium(R) 4") != NULL)) 
                                return SPEEDSTEP_PROCESSOR_P4M;
                        break;
                default:
@@ -321,9 +320,7 @@ EXPORT_SYMBOL_GPL(speedstep_detect_processor);
 unsigned int speedstep_get_freqs(unsigned int processor,
                                  unsigned int *low_speed,
                                  unsigned int *high_speed,
-                                 void (*set_state) (unsigned int state,
-                                                    unsigned int notify)
-                                )
+                                 void (*set_state) (unsigned int state))
 {
        unsigned int prev_speed;
        unsigned int ret = 0;
@@ -340,7 +337,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
        local_irq_save(flags);
 
        /* switch to low state */
-       set_state(SPEEDSTEP_LOW, 0);
+       set_state(SPEEDSTEP_LOW);
        *low_speed = speedstep_get_processor_frequency(processor);
        if (!*low_speed) {
                ret = -EIO;
@@ -348,7 +345,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
        }
 
        /* switch to high state */
-       set_state(SPEEDSTEP_HIGH, 0);
+       set_state(SPEEDSTEP_HIGH);
        *high_speed = speedstep_get_processor_frequency(processor);
        if (!*high_speed) {
                ret = -EIO;
@@ -362,7 +359,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
 
        /* switch to previous state, if necessary */
        if (*high_speed != prev_speed)
-               set_state(SPEEDSTEP_LOW, 0);
+               set_state(SPEEDSTEP_LOW);
 
  out:
        local_irq_restore(flags);
index 851926d..261a2c9 100644 (file)
@@ -44,4 +44,4 @@ extern unsigned int speedstep_get_processor_frequency(unsigned int processor);
 extern unsigned int speedstep_get_freqs(unsigned int processor,
          unsigned int *low_speed,
          unsigned int *high_speed,
-         void (*set_state) (unsigned int state, unsigned int notify));
+         void (*set_state) (unsigned int state));
index 2b1f2fb..6aa31cd 100644 (file)
@@ -139,37 +139,24 @@ static int speedstep_get_state (void)
                : "a" (command), "b" (function), "c" (0), "d" (smi_port), "S" (0)
        );
 
-       return state;
+       return (state & 1);
 }
 
 /**
  * speedstep_set_state - set the SpeedStep state
  * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
- * @notify: whether to call cpufreq_notify_transition
  *
  */
-static void speedstep_set_state (unsigned int state, unsigned int notify)
+static void speedstep_set_state (unsigned int state)
 {
-       unsigned int old_state, result = 0, command, new_state;
+       unsigned int result = 0, command, new_state;
        unsigned long flags;
-       struct cpufreq_freqs freqs;
        unsigned int function=SET_SPEEDSTEP_STATE;
        unsigned int retry = 0;
 
        if (state > 0x1)
                return;
 
-       old_state = speedstep_get_state();
-       freqs.old = speedstep_freqs[old_state].frequency;
-       freqs.new = speedstep_freqs[state].frequency;
-       freqs.cpu = 0; /* speedstep.c is UP only driver */
-
-       if (old_state == state)
-               return;
-
-       if (notify)
-               cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
        /* Disable IRQs */
        local_irq_save(flags);
 
@@ -198,9 +185,6 @@ static void speedstep_set_state (unsigned int state, unsigned int notify)
                printk(KERN_ERR "cpufreq: change failed with new_state %u and result %u\n", new_state, result);
        }
 
-       if (notify)
-               cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
        return;
 }
 
@@ -217,11 +201,21 @@ static int speedstep_target (struct cpufreq_policy *policy,
                        unsigned int target_freq, unsigned int relation)
 {
        unsigned int newstate = 0;
+       struct cpufreq_freqs freqs;
 
        if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate))
                return -EINVAL;
 
-       speedstep_set_state(newstate, 1);
+       freqs.old = speedstep_freqs[speedstep_get_state()].frequency;
+       freqs.new = speedstep_freqs[newstate].frequency;
+       freqs.cpu = 0; /* speedstep.c is UP only driver */
+
+       if (freqs.old == freqs.new)
+               return 0;
+
+       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+       speedstep_set_state(newstate);
+       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
        return 0;
 }
index d9c97da..aafc788 100644 (file)
@@ -546,15 +546,21 @@ static __init int ignore_timer_override(struct dmi_blacklist *d)
 
 #ifdef CONFIG_ACPI_PCI
 static __init int disable_acpi_irq(struct dmi_blacklist *d) 
-{ 
-       printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n", d->ident);         
-       acpi_noirq_set();
+{
+       if (!acpi_force) {
+               printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n",
+                      d->ident);       
+               acpi_noirq_set();
+       }
        return 0;
 }
 static __init int disable_acpi_pci(struct dmi_blacklist *d) 
-{ 
-       printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident);         
-       acpi_disable_pci();
+{
+       if (!acpi_force) {
+               printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n",
+                      d->ident);       
+               acpi_disable_pci();
+       }
        return 0;
 }  
 #endif
index 33bd6a3..fd4988d 100644 (file)
@@ -37,7 +37,6 @@
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/desc.h>
-#include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 
 #define EFI_DEBUG      0
index 2df68a3..2bc9aae 100644 (file)
@@ -29,7 +29,6 @@
 #include <asm/mmx.h>
 #include <asm/desc.h>
 #include <asm/pgtable.h>
-#include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/nmi.h>
 #include <asm/ist.h>
index 0be8d6b..92061fd 100644 (file)
@@ -317,16 +317,11 @@ void init_8259A(int auto_eoi)
  * be shot.
  */
  
-/*
- * =PC9800NOTE= In NEC PC-9800, we use irq8 instead of irq13!
- */
 
 static irqreturn_t math_error_irq(int cpl, void *dev_id, struct pt_regs *regs)
 {
        extern void math_error(void *);
-#ifndef CONFIG_X86_PC9800
        outb(0,0xF0);
-#endif
        if (ignore_fpu_irq || !boot_cpu_data.hard_math)
                return IRQ_NONE;
        math_error((void *)regs->eip);
index dfe1a1e..7422d73 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/init.h>
 #include <linux/init_task.h>
 #include <linux/fs.h>
+#include <linux/mqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
index 3ea997f..70f329e 100644 (file)
 
 #include "io_ports.h"
 
-#undef APIC_LOCKUP_DEBUG
-
-#define APIC_LOCKUP_DEBUG
-
 static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
 
 /*
@@ -127,83 +123,47 @@ static void __init replace_pin_at_irq(unsigned int irq,
        }
 }
 
-/* mask = 1 */
-static void __mask_IO_APIC_irq (unsigned int irq)
+static void __modify_IO_APIC_irq (unsigned int irq, unsigned long enable, unsigned long disable)
 {
-       int pin;
        struct irq_pin_list *entry = irq_2_pin + irq;
+       unsigned int pin, reg;
 
        for (;;) {
-               unsigned int reg;
                pin = entry->pin;
                if (pin == -1)
                        break;
                reg = io_apic_read(entry->apic, 0x10 + pin*2);
-               io_apic_modify(entry->apic, 0x10 + pin*2, reg |= 0x00010000);
+               reg &= ~disable;
+               reg |= enable;
+               io_apic_modify(entry->apic, 0x10 + pin*2, reg);
                if (!entry->next)
                        break;
                entry = irq_2_pin + entry->next;
        }
-       io_apic_sync(entry->apic);
+}
+
+/* mask = 1 */
+static void __mask_IO_APIC_irq (unsigned int irq)
+{
+       __modify_IO_APIC_irq(irq, 0x00010000, 0);
 }
 
 /* mask = 0 */
 static void __unmask_IO_APIC_irq (unsigned int irq)
 {
-       int pin;
-       struct irq_pin_list *entry = irq_2_pin + irq;
-
-       for (;;) {
-               unsigned int reg;
-               pin = entry->pin;
-               if (pin == -1)
-                       break;
-               reg = io_apic_read(entry->apic, 0x10 + pin*2);
-               io_apic_modify(entry->apic, 0x10 + pin*2, reg &= 0xfffeffff);
-               if (!entry->next)
-                       break;
-               entry = irq_2_pin + entry->next;
-       }
+       __modify_IO_APIC_irq(irq, 0, 0x00010000);
 }
 
 /* mask = 1, trigger = 0 */
 static void __mask_and_edge_IO_APIC_irq (unsigned int irq)
 {
-       int pin;
-       struct irq_pin_list *entry = irq_2_pin + irq;
-
-       for (;;) {
-               unsigned int reg;
-               pin = entry->pin;
-               if (pin == -1)
-                       break;
-               reg = io_apic_read(entry->apic, 0x10 + pin*2);
-               reg = (reg & 0xffff7fff) | 0x00010000;
-               io_apic_modify(entry->apic, 0x10 + pin*2, reg);
-               if (!entry->next)
-                       break;
-               entry = irq_2_pin + entry->next;
-       }
+       __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000);
 }
 
 /* mask = 0, trigger = 1 */
 static void __unmask_and_level_IO_APIC_irq (unsigned int irq)
 {
-       int pin;
-       struct irq_pin_list *entry = irq_2_pin + irq;
-
-       for (;;) {
-               unsigned int reg;
-               pin = entry->pin;
-               if (pin == -1)
-                       break;
-               reg = io_apic_read(entry->apic, 0x10 + pin*2);
-               reg = (reg & 0xfffeffff) | 0x00008000;
-               io_apic_modify(entry->apic, 0x10 + pin*2, reg);
-               if (!entry->next)
-                       break;
-               entry = irq_2_pin + entry->next;
-       }
+       __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000);
 }
 
 static void mask_IO_APIC_irq (unsigned int irq)
@@ -1366,7 +1326,7 @@ void __init print_IO_APIC(void)
        printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.bits.ID);
        printk(KERN_DEBUG ".......    : Delivery Type: %X\n", reg_00.bits.delivery_type);
        printk(KERN_DEBUG ".......    : LTS          : %X\n", reg_00.bits.LTS);
-       if (reg_00.bits.ID >= APIC_BROADCAST_ID)
+       if (reg_00.bits.ID >= get_physical_broadcast())
                UNEXPECTED_IO_APIC();
        if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2)
                UNEXPECTED_IO_APIC();
@@ -1682,7 +1642,7 @@ static void __init setup_ioapic_ids_from_mpc(void)
                
                old_id = mp_ioapics[apic].mpc_apicid;
 
-               if (mp_ioapics[apic].mpc_apicid >= APIC_BROADCAST_ID) {
+               if (mp_ioapics[apic].mpc_apicid >= get_physical_broadcast()) {
                        printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
                                apic, mp_ioapics[apic].mpc_apicid);
                        printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
@@ -1703,10 +1663,10 @@ static void __init setup_ioapic_ids_from_mpc(void)
                                        mp_ioapics[apic].mpc_apicid)) {
                        printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
                                apic, mp_ioapics[apic].mpc_apicid);
-                       for (i = 0; i < APIC_BROADCAST_ID; i++)
+                       for (i = 0; i < get_physical_broadcast(); i++)
                                if (!physid_isset(i, phys_id_present_map))
                                        break;
-                       if (i >= APIC_BROADCAST_ID)
+                       if (i >= get_physical_broadcast())
                                panic("Max APIC ID exceeded!\n");
                        printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
                                i);
@@ -1893,30 +1853,11 @@ static void end_level_ioapic_irq (unsigned int irq)
        ack_APIC_irq();
 
        if (!(v & (1 << (i & 0x1f)))) {
-#ifdef APIC_LOCKUP_DEBUG
-               struct irq_pin_list *entry;
-#endif
-
 #ifdef APIC_MISMATCH_DEBUG
                atomic_inc(&irq_mis_count);
 #endif
                spin_lock(&ioapic_lock);
                __mask_and_edge_IO_APIC_irq(irq);
-#ifdef APIC_LOCKUP_DEBUG
-               for (entry = irq_2_pin + irq;;) {
-                       unsigned int reg;
-
-                       if (entry->pin == -1)
-                               break;
-                       reg = io_apic_read(entry->apic, 0x10 + entry->pin * 2);
-                       if (reg & 0x00004000)
-                               printk(KERN_CRIT "Aieee!!!  Remote IRR"
-                                       " still set after unlock!\n");
-                       if (!entry->next)
-                               break;
-                       entry = irq_2_pin + entry->next;
-               }
-#endif
                __unmask_and_level_IO_APIC_irq(irq);
                spin_unlock(&ioapic_lock);
        }
@@ -2322,8 +2263,6 @@ late_initcall(io_apic_bug_finalize);
 
 #ifdef CONFIG_ACPI_BOOT
 
-#define IO_APIC_MAX_ID APIC_BROADCAST_ID
-
 int __init io_apic_get_unique_id (int ioapic, int apic_id)
 {
        union IO_APIC_reg_00 reg_00;
@@ -2348,7 +2287,7 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id)
        reg_00.raw = io_apic_read(ioapic, 0);
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
-       if (apic_id >= IO_APIC_MAX_ID) {
+       if (apic_id >= get_physical_broadcast()) {
                printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
                        "%d\n", ioapic, apic_id, reg_00.bits.ID);
                apic_id = reg_00.bits.ID;
@@ -2360,12 +2299,12 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id)
         */
        if (check_apicid_used(apic_id_map, apic_id)) {
 
-               for (i = 0; i < IO_APIC_MAX_ID; i++) {
+               for (i = 0; i < get_physical_broadcast(); i++) {
                        if (!check_apicid_used(apic_id_map, i))
                                break;
                }
 
-               if (i == IO_APIC_MAX_ID)
+               if (i == get_physical_broadcast())
                        panic("Max apic_id exceeded!\n");
 
                printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
index d57a137..2f49639 100644 (file)
@@ -41,7 +41,6 @@
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
-#include <asm/pgalloc.h>
 #include <asm/delay.h>
 #include <asm/desc.h>
 #include <asm/irq.h>
@@ -241,6 +240,7 @@ static void __report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
                                irq, action_ret);
        } else {
                printk(KERN_ERR "irq %d: nobody cared! (screaming interrupt?)\n", irq);
+               printk(KERN_ERR "irq %d: Please try booting with acpi=off and report a bug\n", irq);
        }
        dump_stack();
        printk(KERN_ERR "handlers:\n");
index 55e4c29..51a7508 100644 (file)
 #include <linux/smp_lock.h>
 #include <linux/kernel_stat.h>
 #include <linux/mc146818rtc.h>
+#include <linux/bitops.h>
 
 #include <asm/smp.h>
 #include <asm/acpi.h>
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
-#include <asm/pgalloc.h>
 #include <asm/io_apic.h>
 
 #include <mach_apic.h>
@@ -104,6 +104,21 @@ static int __init mpf_checksum(unsigned char *mp, int len)
 static int mpc_record; 
 static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata;
 
+#ifdef CONFIG_X86_NUMAQ
+static int MP_valid_apicid(int apicid, int version)
+{
+       return hweight_long(apicid & 0xf) == 1 && (apicid >> 4) != 0xf;
+}
+#else
+static int MP_valid_apicid(int apicid, int version)
+{
+       if (version >= 0x14)
+               return apicid < 0xff;
+       else
+               return apicid < 0xf;
+}
+#endif
+
 void __init MP_processor_info (struct mpc_config_processor *m)
 {
        int ver, apicid;
@@ -180,14 +195,14 @@ void __init MP_processor_info (struct mpc_config_processor *m)
                return;
        }
        num_processors++;
+       ver = m->mpc_apicver;
 
-       if (MAX_APICS - m->mpc_apicid <= 0) {
+       if (!MP_valid_apicid(apicid, ver)) {
                printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n",
                        m->mpc_apicid, MAX_APICS);
                --num_processors;
                return;
        }
-       ver = m->mpc_apicver;
 
        tmp = apicid_to_cpu_present(apicid);
        physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp);
@@ -844,7 +859,7 @@ void __init mp_register_lapic (
        MP_processor_info(&processor);
 }
 
-#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER)
+#if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_ACPI_BOOT))
 
 #define MP_ISA_BUS             0
 #define MP_MAX_IOAPIC_PIN      127
@@ -857,7 +872,7 @@ struct mp_ioapic_routing {
 } mp_ioapic_routing[MAX_IO_APICS];
 
 
-static int __init mp_find_ioapic (
+static int mp_find_ioapic (
        int                     gsi)
 {
        int                     i = 0;
@@ -1002,6 +1017,7 @@ void __init mp_config_acpi_legacy_irqs (void)
 
                for (idx = 0; idx < mp_irq_entries; idx++)
                        if (mp_irqs[idx].mpc_srcbus == MP_ISA_BUS &&
+                               (mp_irqs[idx].mpc_dstapic == ioapic) &&
                                (mp_irqs[idx].mpc_srcbusirq == i ||
                                mp_irqs[idx].mpc_dstirq == i))
                                        break;
@@ -1025,96 +1041,56 @@ void __init mp_config_acpi_legacy_irqs (void)
        }
 }
 
-extern FADT_DESCRIPTOR acpi_fadt;
-
-#ifdef CONFIG_ACPI_PCI
-
 int (*platform_rename_gsi)(int ioapic, int gsi);
 
-void __init mp_parse_prt (void)
+void mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
 {
-       struct list_head        *node = NULL;
-       struct acpi_prt_entry   *entry = NULL;
        int                     ioapic = -1;
        int                     ioapic_pin = 0;
-       int                     gsi = 0;
        int                     idx, bit = 0;
-       int                     edge_level = 0;
-       int                     active_high_low = 0;
 
-       /*
-        * Parsing through the PCI Interrupt Routing Table (PRT) and program
-        * routing for all entries.
-        */
-       list_for_each(node, &acpi_prt.entries) {
-               entry = list_entry(node, struct acpi_prt_entry, node);
-
-               /* Need to get gsi for dynamic entry */
-               if (entry->link.handle) {
-                       gsi = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low);
-                       if (!gsi)
-                               continue;
-               }
-               else {
-                       /* Hardwired GSI. Assume PCI standard settings */
-                       gsi = entry->link.index;
-                       edge_level = 1;
-                       active_high_low = 1;
-               }
+#ifdef CONFIG_ACPI_BUS
+       /* Don't set up the ACPI SCI because it's already set up */
+       if (acpi_fadt.sci_int == gsi)
+               return;
+#endif
 
-               /* Don't set up the ACPI SCI because it's already set up */
-                if (acpi_fadt.sci_int == gsi) {
-                       /* we still need to set entry's irq */
-                       acpi_gsi_to_irq(gsi, &entry->irq);
-                       continue;
-                }
-       
-               ioapic = mp_find_ioapic(gsi);
-               if (ioapic < 0)
-                       continue;
-               ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
-
-               if (platform_rename_gsi)
-                       gsi = platform_rename_gsi(ioapic, gsi);
-
-               /* 
-                * Avoid pin reprogramming.  PRTs typically include entries  
-                * with redundant pin->gsi mappings (but unique PCI devices);
-                * we only only program the IOAPIC on the first.
-                */
-               bit = ioapic_pin % 32;
-               idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
-               if (idx > 3) {
-                       printk(KERN_ERR "Invalid reference to IOAPIC pin "
-                               "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, 
-                               ioapic_pin);
-                       continue;
-               }
-               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);
-                       acpi_gsi_to_irq(gsi, &entry->irq);
-                       continue;
-               }
+       ioapic = mp_find_ioapic(gsi);
+       if (ioapic < 0) {
+               printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
+               return;
+       }
 
-               mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
+       ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
 
-               if (!io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, edge_level, active_high_low)) {
-                       acpi_gsi_to_irq(gsi, &entry->irq);
-               }
-               printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d %s %s\n",
-                       entry->id.segment, entry->id.bus,
-                       entry->id.device, ('A' + entry->pin),
-                       mp_ioapic_routing[ioapic].apic_id, ioapic_pin,
-                       entry->irq, edge_level ? "level" : "edge",
-                       active_high_low ? "low" : "high");
+       if (platform_rename_gsi)
+               gsi = platform_rename_gsi(ioapic, gsi);
+
+       /* 
+        * Avoid pin reprogramming.  PRTs typically include entries  
+        * with redundant pin->gsi mappings (but unique PCI devices);
+        * we only program the IOAPIC on the first.
+        */
+       bit = ioapic_pin % 32;
+       idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
+       if (idx > 3) {
+               printk(KERN_ERR "Invalid reference to IOAPIC pin "
+                       "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, 
+                       ioapic_pin);
+               return;
+       }
+       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;
        }
 
-       print_IO_APIC();
+       mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
 
-       return;
+       io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
+                   edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
+                   active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
 }
 
-#endif /*CONFIG_ACPI_PCI*/
-#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/
+#endif /*CONFIG_X86_IO_APIC && (CONFIG_ACPI_INTERPRETER || CONFIG_ACPI_BOOT)*/
 #endif /*CONFIG_ACPI_BOOT*/
index ade8066..d2f410d 100644 (file)
@@ -205,7 +205,7 @@ static int __init idle_setup (char *str)
        if (!strncmp(str, "poll", 4)) {
                printk("using polling idle threads.\n");
                pm_idle = poll_idle;
-#ifdef CONFIG_SMP
+#ifdef CONFIG_X86_SMP
                if (smp_num_siblings > 1)
                        printk("WARNING: polling idle and HT enabled, performance may degrade.\n");
 #endif
index 76f34d0..95e9fa7 100644 (file)
@@ -47,7 +47,7 @@
 #include <asm/sections.h>
 #include <asm/io_apic.h>
 #include <asm/ist.h>
-#include <asm/std_resources.h>
+#include <asm/io.h>
 #include "setup_arch_pre.h"
 
 /* This value is set up by the early boot code to point to the value
@@ -133,8 +133,203 @@ static char command_line[COMMAND_LINE_SIZE];
 
 unsigned char __initdata boot_params[PARAM_SIZE];
 
-static struct resource code_resource = { "Kernel code", 0x100000, 0 };
-static struct resource data_resource = { "Kernel data", 0, 0 };
+static struct resource data_resource = {
+       .name   = "Kernel data",
+       .start  = 0,
+       .end    = 0,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
+static struct resource code_resource = {
+       .name   = "Kernel code",
+       .start  = 0,
+       .end    = 0,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
+static struct resource system_rom_resource = {
+       .name   = "System ROM",
+       .start  = 0xf0000,
+       .end    = 0xfffff,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+};
+
+static struct resource extension_rom_resource = {
+       .name   = "Extension ROM",
+       .start  = 0xe0000,
+       .end    = 0xeffff,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+};
+
+static struct resource adapter_rom_resources[] = { {
+       .name   = "Adapter ROM",
+       .start  = 0xc8000,
+       .end    = 0,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+       .name   = "Adapter ROM",
+       .start  = 0,
+       .end    = 0,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+       .name   = "Adapter ROM",
+       .start  = 0,
+       .end    = 0,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+       .name   = "Adapter ROM",
+       .start  = 0,
+       .end    = 0,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+       .name   = "Adapter ROM",
+       .start  = 0,
+       .end    = 0,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+       .name   = "Adapter ROM",
+       .start  = 0,
+       .end    = 0,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+} };
+
+#define ADAPTER_ROM_RESOURCES \
+       (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
+
+static struct resource video_rom_resource = {
+       .name   = "Video ROM",
+       .start  = 0xc0000,
+       .end    = 0xc7fff,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+};
+
+static struct resource video_ram_resource = {
+       .name   = "Video RAM area",
+       .start  = 0xa0000,
+       .end    = 0xbffff,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
+static struct resource standard_io_resources[] = { {
+       .name   = "dma1",
+       .start  = 0x0000,
+       .end    = 0x001f,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+       .name   = "pic1",
+       .start  = 0x0020,
+       .end    = 0x0021,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+       .name   = "timer",
+       .start  = 0x0040,
+       .end    = 0x005f,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+       .name   = "keyboard",
+       .start  = 0x0060,
+       .end    = 0x006f,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+       .name   = "dma page reg",
+       .start  = 0x0080,
+       .end    = 0x008f,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+       .name   = "pic2",
+       .start  = 0x00a0,
+       .end    = 0x00a1,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+       .name   = "dma2",
+       .start  = 0x00c0,
+       .end    = 0x00df,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+       .name   = "fpu",
+       .start  = 0x00f0,
+       .end    = 0x00ff,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
+} };
+
+#define STANDARD_IO_RESOURCES \
+       (sizeof standard_io_resources / sizeof standard_io_resources[0])
+
+#define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
+
+static int __init romchecksum(unsigned char *rom, unsigned long length)
+{
+       unsigned char *p, sum = 0;
+
+       for (p = rom; p < rom + length; p++)
+               sum += *p;
+       return sum == 0;
+}
+
+static void __init probe_roms(void)
+{
+       unsigned long start, length, upper;
+       unsigned char *rom;
+       int           i;
+
+       /* video rom */
+       upper = adapter_rom_resources[0].start;
+       for (start = video_rom_resource.start; start < upper; start += 2048) {
+               rom = isa_bus_to_virt(start);
+               if (!romsignature(rom))
+                       continue;
+
+               video_rom_resource.start = start;
+
+               /* 0 < length <= 0x7f * 512, historically */
+               length = rom[2] * 512;
+
+               /* if checksum okay, trust length byte */
+               if (length && romchecksum(rom, length))
+                       video_rom_resource.end = start + length - 1;
+
+               request_resource(&iomem_resource, &video_rom_resource);
+               break;
+       }
+
+       start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
+       if (start < upper)
+               start = upper;
+
+       /* system rom */
+       request_resource(&iomem_resource, &system_rom_resource);
+       upper = system_rom_resource.start;
+
+       /* check for extension rom (ignore length byte!) */
+       rom = isa_bus_to_virt(extension_rom_resource.start);
+       if (romsignature(rom)) {
+               length = extension_rom_resource.end - extension_rom_resource.start + 1;
+               if (romchecksum(rom, length)) {
+                       request_resource(&iomem_resource, &extension_rom_resource);
+                       upper = extension_rom_resource.start;
+               }
+       }
+
+       /* check for adapter roms on 2k boundaries */
+       for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) {
+               rom = isa_bus_to_virt(start);
+               if (!romsignature(rom))
+                       continue;
+
+               /* 0 < length <= 0x7f * 512, historically */
+               length = rom[2] * 512;
+
+               /* but accept any length that fits if checksum okay */
+               if (!length || start + length > upper || !romchecksum(rom, length))
+                       continue;
+
+               adapter_rom_resources[i].start = start;
+               adapter_rom_resources[i].end = start + length - 1;
+               request_resource(&iomem_resource, &adapter_rom_resources[i]);
+
+               start = adapter_rom_resources[i++].end & ~2047UL;
+       }
+}
 
 static void __init limit_regions(unsigned long long size)
 {
@@ -948,6 +1143,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
 static void __init register_memory(unsigned long max_low_pfn)
 {
        unsigned long low_mem_size;
+       int           i;
 
        if (efi_enabled)
                efi_initialize_iomem_resources(&code_resource, &data_resource);
@@ -955,10 +1151,11 @@ static void __init register_memory(unsigned long max_low_pfn)
                legacy_init_iomem_resources(&code_resource, &data_resource);
 
        /* EFI systems may still have VGA */
-       request_graphics_resource();
+       request_resource(&iomem_resource, &video_ram_resource);
 
        /* request I/O space for devices used on all i[345]86 PCs */
-       request_standard_io_resources();
+       for (i = 0; i < STANDARD_IO_RESOURCES; i++)
+               request_resource(&ioport_resource, &standard_io_resources[i]);
 
        /* Tell the PCI layer not to allocate too close to the RAM area.. */
        low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
index 3c50ed2..1667d99 100644 (file)
@@ -56,16 +56,15 @@ sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 }
 
 asmlinkage int
-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
+sys_rt_sigsuspend(struct pt_regs regs)
 {
-       struct pt_regs * regs = (struct pt_regs *) &unewset;
        sigset_t saveset, newset;
 
        /* XXX: Don't preclude handling different sized sigset_t's.  */
-       if (sigsetsize != sizeof(sigset_t))
+       if (regs.ecx != sizeof(sigset_t))
                return -EINVAL;
 
-       if (copy_from_user(&newset, unewset, sizeof(newset)))
+       if (copy_from_user(&newset, (sigset_t __user *)regs.ebx, sizeof(newset)))
                return -EFAULT;
        sigdelsetmask(&newset, ~_BLOCKABLE);
 
@@ -75,11 +74,11 @@ sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       regs->eax = -EINTR;
+       regs.eax = -EINTR;
        while (1) {
                current->state = TASK_INTERRUPTIBLE;
                schedule();
-               if (do_signal(regs, &saveset))
+               if (do_signal(&regs, &saveset))
                        return -EINTR;
        }
 }
@@ -117,10 +116,11 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
 }
 
 asmlinkage int
-sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
+sys_sigaltstack(struct pt_regs regs)
 {
-       struct pt_regs *regs = (struct pt_regs *) &uss;
-       return do_sigaltstack(uss, uoss, regs->esp);
+       const stack_t __user *uss = (const stack_t __user *)regs.ebx;
+       stack_t __user *uoss = (stack_t __user *)regs.ecx;
+       return do_sigaltstack(uss, uoss, regs.esp);
 }
 
 
index afd9271..13c1714 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/interrupt.h>
 
 #include <asm/mtrr.h>
-#include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <mach_ipi.h>
 #include <mach_apic.h>
index 45e8fba..c3fa253 100644 (file)
@@ -47,7 +47,6 @@
 
 #include <linux/delay.h>
 #include <linux/mc146818rtc.h>
-#include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/desc.h>
 #include <asm/arch_hooks.h>
index a281711..25a6a89 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/config.h>
 
 #include <asm/hpet.h>
+#include <linux/hpet.h>
 
 unsigned long hpet_period;     /* fsecs / HPET clock */
 unsigned long hpet_tick;       /* hpet clks count per tick */
@@ -135,6 +136,51 @@ int __init hpet_enable(void)
        hpet_writel(cfg, HPET_CFG);
 
        use_hpet = 1;
+
+#ifdef CONFIG_HPET
+       {
+               struct hpet_data        hd;
+               unsigned int            ntimer;
+
+               memset(&hd, 0, sizeof (hd));
+
+               ntimer = hpet_readl(HPET_ID);
+               ntimer = (ntimer & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT;
+               ntimer++;
+
+               /*
+                * Register with driver.
+                * Timer0 and Timer1 is used by platform.
+                */
+               hd.hd_address = hpet_virt_address;
+               hd.hd_nirqs = ntimer;
+               hd.hd_flags = HPET_DATA_PLATFORM;
+#ifndef        CONFIG_HPET_EMULATE_RTC
+               hd.hd_state = 0x1;
+#else
+               hd.hd_state = 0x3;
+#endif
+               hd.hd_irq[0] = HPET_LEGACY_8254;
+               hd.hd_irq[1] = HPET_LEGACY_RTC;
+               if (ntimer > 2) {
+                       struct hpet             *hpet;
+                       struct hpet_timer       *timer;
+                       int                     i;
+
+                       hpet = (struct hpet *) hpet_virt_address;
+
+                       for (i = 2, timer = &hpet->hpet_timers[2]; i < ntimer;
+                               timer++, i++)
+                               hd.hd_irq[i] = (timer->hpet_config &
+                                       Tn_INT_ROUTE_CNF_MASK) >>
+                                       Tn_INT_ROUTE_CNF_SHIFT;
+
+               }
+
+               hpet_alloc(&hd);
+       }
+#endif
+
 #ifdef CONFIG_X86_LOCAL_APIC
        wait_timer_tick = wait_hpet_tick;
 #endif
index 9f80757..34f1f3d 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/fixmap.h>
+#include "io_ports.h"
 
 extern spinlock_t i8253_lock;
 
@@ -62,6 +63,17 @@ static void mark_offset_cyclone(void)
 
        count = inb_p(0x40);    /* read the latched count */
        count |= inb(0x40) << 8;
+
+       /*
+        * VIA686a test code... reset the latch if count > max + 1
+        * from timer_pit.c - cjb
+        */
+       if (count > LATCH) {
+               outb_p(0x34, PIT_MODE);
+               outb_p(LATCH & 0xff, PIT_CH0);
+               outb(LATCH >> 8, PIT_CH0);
+               count = LATCH - 1;
+       }
        spin_unlock(&i8253_lock);
 
        /* lost tick compensation */
index 7aa63c9..737a021 100644 (file)
 #include <asm/io.h>
 #include <asm/arch_hooks.h>
 
+#include <linux/timex.h>
+#include "mach_timer.h"
+
+/* Number of PMTMR ticks expected during calibration run */
+#define PMTMR_TICKS_PER_SEC 3579545
+#define PMTMR_EXPECTED_RATE \
+  ((CALIBRATE_LATCH * (PMTMR_TICKS_PER_SEC >> 10)) / (CLOCK_TICK_RATE>>10))
+
 
 /* The I/O port the PMTMR resides at.
  * The location is detected during setup_arch(),
@@ -57,6 +65,33 @@ static inline u32 read_pmtmr(void)
        return v2 & ACPI_PM_MASK;
 }
 
+
+/*
+ * Some boards have the PMTMR running way too fast. We check
+ * the PMTMR rate against PIT channel 2 to catch these cases.
+ */
+static int verify_pmtmr_rate(void)
+{
+       u32 value1, value2;
+       unsigned long count, delta;
+
+       mach_prepare_counter();
+       value1 = read_pmtmr();
+       mach_countup(&count);
+       value2 = read_pmtmr();
+       delta = (value2 - value1) & ACPI_PM_MASK;
+
+       /* Check that the PMTMR delta is within 5% of what we expect */
+       if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 ||
+           delta > (PMTMR_EXPECTED_RATE * 21) / 20) {
+               printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% of normal - aborting.\n", 100UL * delta / PMTMR_EXPECTED_RATE);
+               return -1;
+       }
+
+       return 0;
+}
+
+
 static int init_pmtmr(char* override)
 {
        u32 value1, value2;
@@ -89,6 +124,9 @@ static int init_pmtmr(char* override)
        return -ENODEV;
 
 pm_good:
+       if (verify_pmtmr_rate() != 0)
+               return -ENODEV;
+
        init_cpu_khz();
        return 0;
 }
index ae775d4..3d08b2d 100644 (file)
@@ -47,7 +47,6 @@
 #include <asm/nmi.h>
 
 #include <asm/smp.h>
-#include <asm/pgalloc.h>
 #include <asm/arch_hooks.h>
 
 #include <linux/irq.h>
@@ -159,7 +158,6 @@ void show_trace(struct task_struct *task, unsigned long * stack)
                        break;
                printk(" =======================\n");
        }
-       printk("\n");
 }
 
 void show_stack(struct task_struct *task, unsigned long *esp)
@@ -279,7 +277,7 @@ static void handle_BUG(struct pt_regs *regs)
                file = "<bad filename>";
 
        printk("------------[ cut here ]------------\n");
-       printk("kernel BUG at %s:%d!\n", file, line);
+       printk(KERN_ALERT "kernel BUG at %s:%d!\n", file, line);
 
 no_bug:
        return;
@@ -300,7 +298,7 @@ void die(const char * str, struct pt_regs * regs, long err)
        spin_lock_irq(&die_lock);
        bust_spinlocks(1);
        handle_BUG(regs);
-       printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
+       printk(KERN_ALERT "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
 #ifdef CONFIG_PREEMPT
        printk("PREEMPT ");
        nl = 1;
index e0e3bdf..bd8f958 100644 (file)
@@ -44,7 +44,6 @@
 #include <linux/ptrace.h>
 
 #include <asm/uaccess.h>
-#include <asm/pgalloc.h>
 #include <asm/io.h>
 #include <asm/tlbflush.h>
 #include <asm/irq.h>
@@ -178,8 +177,9 @@ out:
 static int do_vm86_irq_handling(int subfunction, int irqnumber);
 static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk);
 
-asmlinkage int sys_vm86old(struct vm86_struct __user * v86)
+asmlinkage int sys_vm86old(struct pt_regs regs)
 {
+       struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs.ebx;
        struct kernel_vm86_struct info; /* declare this _on top_,
                                         * this avoids wasting of stack space.
                                         * This remains on the stack until we
@@ -198,7 +198,7 @@ asmlinkage int sys_vm86old(struct vm86_struct __user * v86)
        if (tmp)
                goto out;
        memset(&info.vm86plus, 0, (int)&info.regs32 - (int)&info.vm86plus);
-       info.regs32 = (struct pt_regs *) &v86;
+       info.regs32 = &regs;
        tsk->thread.vm86_info = v86;
        do_sys_vm86(&info, tsk);
        ret = 0;        /* we never return here */
@@ -207,7 +207,7 @@ out:
 }
 
 
-asmlinkage int sys_vm86(unsigned long subfunction, struct vm86plus_struct __user * v86)
+asmlinkage int sys_vm86(struct pt_regs regs)
 {
        struct kernel_vm86_struct info; /* declare this _on top_,
                                         * this avoids wasting of stack space.
@@ -216,14 +216,15 @@ asmlinkage int sys_vm86(unsigned long subfunction, struct vm86plus_struct __user
                                         */
        struct task_struct *tsk;
        int tmp, ret;
+       struct vm86plus_struct __user *v86;
 
        tsk = current;
-       switch (subfunction) {
+       switch (regs.ebx) {
                case VM86_REQUEST_IRQ:
                case VM86_FREE_IRQ:
                case VM86_GET_IRQ_BITS:
                case VM86_GET_AND_RESET_IRQ:
-                       ret = do_vm86_irq_handling(subfunction,(int)v86);
+                       ret = do_vm86_irq_handling(regs.ebx, (int)regs.ecx);
                        goto out;
                case VM86_PLUS_INSTALL_CHECK:
                        /* NOTE: on old vm86 stuff this will return the error
@@ -239,13 +240,14 @@ asmlinkage int sys_vm86(unsigned long subfunction, struct vm86plus_struct __user
        ret = -EPERM;
        if (tsk->thread.saved_esp0)
                goto out;
+       v86 = (struct vm86plus_struct __user *)regs.ecx;
        tmp  = copy_from_user(&info, v86, VM86_REGS_SIZE1);
        tmp += copy_from_user(&info.regs.VM86_REGS_PART2, &v86->regs.VM86_REGS_PART2,
                (long)&info.regs32 - (long)&info.regs.VM86_REGS_PART2);
        ret = -EFAULT;
        if (tmp)
                goto out;
-       info.regs32 = (struct pt_regs *) &subfunction;
+       info.regs32 = &regs;
        info.vm86plus.is_vm86pus = 1;
        tsk->thread.vm86_info = (struct vm86_struct __user *)v86;
        do_sys_vm86(&info, tsk);
@@ -486,9 +488,10 @@ static inline int is_revectored(int nr, struct revectored_struct * bitmap)
  * in userspace is always better than an Oops anyway.) [KD]
  */
 static void do_int(struct kernel_vm86_regs *regs, int i,
-    unsigned char * ssp, unsigned short sp)
+    unsigned char __user * ssp, unsigned short sp)
 {
-       unsigned long *intr_ptr, segoffs;
+       unsigned long __user *intr_ptr;
+       unsigned long segoffs;
 
        if (regs->cs == BIOSSEG)
                goto cannot_handle;
@@ -496,7 +499,7 @@ static void do_int(struct kernel_vm86_regs *regs, int i,
                goto cannot_handle;
        if (i==0x21 && is_revectored(AH(regs),&KVM86->int21_revectored))
                goto cannot_handle;
-       intr_ptr = (unsigned long *) (i << 2);
+       intr_ptr = (unsigned long __user *) (i << 2);
        if (get_user(segoffs, intr_ptr))
                goto cannot_handle;
        if ((segoffs >> 16) == BIOSSEG)
@@ -521,7 +524,7 @@ int handle_vm86_trap(struct kernel_vm86_regs * regs, long error_code, int trapno
        if (VMPI.is_vm86pus) {
                if ( (trapno==3) || (trapno==1) )
                        return_to_32bit(regs, VM86_TRAP + (trapno << 8));
-               do_int(regs, trapno, (unsigned char *) (regs->ss << 4), SP(regs));
+               do_int(regs, trapno, (unsigned char __user *) (regs->ss << 4), SP(regs));
                return 0;
        }
        if (trapno !=1)
@@ -541,7 +544,9 @@ int handle_vm86_trap(struct kernel_vm86_regs * regs, long error_code, int trapno
 
 void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
 {
-       unsigned char *csp, *ssp, opcode;
+       unsigned char opcode;
+       unsigned char __user *csp;
+       unsigned char __user *ssp;
        unsigned short ip, sp;
        int data32, pref_done;
 
@@ -553,8 +558,8 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
                return_to_32bit(regs, VM86_PICRETURN); \
        return; } while (0)
 
-       csp = (unsigned char *) (regs->cs << 4);
-       ssp = (unsigned char *) (regs->ss << 4);
+       csp = (unsigned char __user *) (regs->cs << 4);
+       ssp = (unsigned char __user *) (regs->ss << 4);
        sp = SP(regs);
        ip = IP(regs);
 
index 518cebc..1354843 100644 (file)
@@ -3,9 +3,8 @@
 #
 
 
-lib-y = checksum.o delay.o \
-       usercopy.o getuser.o \
-       memcpy.o strstr.o
+lib-y = checksum.o delay.o usercopy.o getuser.o memcpy.o strstr.o \
+       bitops.o
 
 lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
 lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
index 028dd9b..97b97af 100644 (file)
@@ -31,15 +31,16 @@ void __delay(unsigned long loops)
 inline void __const_udelay(unsigned long xloops)
 {
        int d0;
+       xloops *= 4;
        __asm__("mull %0"
                :"=d" (xloops), "=&a" (d0)
-               :"1" (xloops),"0" (current_cpu_data.loops_per_jiffy));
-        __delay(xloops * HZ);
+               :"1" (xloops),"0" (current_cpu_data.loops_per_jiffy * (HZ/4)));
+        __delay(++xloops);
 }
 
 void __udelay(unsigned long usecs)
 {
-       __const_udelay(usecs * 0x000010c6);  /* 2**32 / 1000000 */
+       __const_udelay(usecs * 0x000010c7);  /* 2**32 / 1000000 (rounded up) */
 }
 
 void __ndelay(unsigned long nsecs)
index 70db264..784576c 100644 (file)
@@ -50,7 +50,6 @@ struct mip_reg                *mip_reg;
 struct mip_reg         *host_reg;
 int                    mip_port;
 unsigned long          mip_addr, host_addr;
-extern int (*platform_rename_gsi)();
 
 static int __init
 es7000_rename_gsi(int ioapic, int gsi)
@@ -134,7 +133,6 @@ parse_unisys_oem (char *oemptr, int oem_entries)
        }
 
        if (success < 2) {
-               printk("\nNo ES7000 found.\n");
                es7000_plat = 0;
        } else {
                printk("\nEnabling ES7000 specific features...\n");
index dd1525a..fa80064 100644 (file)
@@ -57,12 +57,12 @@ void __init MP_processor_info (struct mpc_config_processor *m)
                boot_cpu_logical_apicid = logical_apicid;
        }
 
-       if (m->mpc_apicid > MAX_APICS) {
+       ver = m->mpc_apicver;
+       if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) {
                printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
                        m->mpc_apicid, MAX_APICS);
                return;
        }
-       ver = m->mpc_apicver;
 
        apic_cpus = apicid_to_cpu_present(m->mpc_apicid);
        physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus);
index a3c22c0..9643539 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/pci_ids.h>
 
 #include <asm/io.h>
-#include <asm/pgalloc.h>
 #include <asm/arch_hooks.h>
 #include <asm/apic.h>
 #include "cobalt.h"
index 528bc8f..61a4814 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/reboot.h>
 #include <linux/sysrq.h>
 #include <asm/io.h>
-#include <asm/pgalloc.h>
 #include <asm/voyager.h>
 #include <asm/vic.h>
 #include <linux/pm.h>
index 2bdc18f..b99561d 100644 (file)
@@ -24,7 +24,6 @@
 #include <asm/desc.h>
 #include <asm/voyager.h>
 #include <asm/vic.h>
-#include <asm/pgalloc.h>
 #include <asm/mtrr.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
index b091fcf..9980eef 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/desc.h>
 #include <asm/voyager.h>
 #include <asm/vic.h>
-#include <asm/pgalloc.h>
 #include <asm/mtrr.h>
 #include <asm/msr.h>
 
index 4861545..f755641 100644 (file)
@@ -41,18 +41,18 @@ void Un_impl(void)
 
   RE_ENTRANT_CHECK_OFF;
   /* No need to verify_area(), we have previously fetched these bytes. */
-  printk("Unimplemented FPU Opcode at eip=%p : ", (void *) address);
+  printk("Unimplemented FPU Opcode at eip=%p : ", (void __user *) address);
   if ( FPU_CS == __USER_CS )
     {
       while ( 1 )
        {
-         FPU_get_user(byte1, (u_char *) address);
+         FPU_get_user(byte1, (u_char __user *) address);
          if ( (byte1 & 0xf8) == 0xd8 ) break;
          printk("[%02x]", byte1);
          address++;
        }
       printk("%02x ", byte1);
-      FPU_get_user(FPU_modrm, 1 + (u_char *) address);
+      FPU_get_user(FPU_modrm, 1 + (u_char __user *) address);
       
       if (FPU_modrm >= 0300)
        printk("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
@@ -98,7 +98,7 @@ void FPU_printall(void)
 #define MAX_PRINTED_BYTES 20
       for ( i = 0; i < MAX_PRINTED_BYTES; i++ )
        {
-         FPU_get_user(byte1, (u_char *) address);
+         FPU_get_user(byte1, (u_char __user *) address);
          if ( (byte1 & 0xf8) == 0xd8 )
            {
              printk(" %02x", byte1);
@@ -111,7 +111,7 @@ void FPU_printall(void)
        printk(" [more..]\n");
       else
        {
-         FPU_get_user(FPU_modrm, 1 + (u_char *) address);
+         FPU_get_user(FPU_modrm, 1 + (u_char __user *) address);
          
          if (FPU_modrm >= 0300)
            printk(" %02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
index fcad7ec..6972dec 100644 (file)
@@ -16,7 +16,7 @@
 #include "status_w.h"
 
 
-void fadd__()
+void fadd__(void)
 {
   /* fadd st,st(i) */
   int i = FPU_rm;
@@ -25,7 +25,7 @@ void fadd__()
 }
 
 
-void fmul__()
+void fmul__(void)
 {
   /* fmul st,st(i) */
   int i = FPU_rm;
@@ -35,7 +35,7 @@ void fmul__()
 
 
 
-void fsub__()
+void fsub__(void)
 {
   /* fsub st,st(i) */
   clear_C1();
@@ -43,7 +43,7 @@ void fsub__()
 }
 
 
-void fsubr_()
+void fsubr_(void)
 {
   /* fsubr st,st(i) */
   clear_C1();
@@ -51,7 +51,7 @@ void fsubr_()
 }
 
 
-void fdiv__()
+void fdiv__(void)
 {
   /* fdiv st,st(i) */
   clear_C1();
@@ -59,7 +59,7 @@ void fdiv__()
 }
 
 
-void fdivr_()
+void fdivr_(void)
 {
   /* fdivr st,st(i) */
   clear_C1();
@@ -68,7 +68,7 @@ void fdivr_()
 
 
 
-void fadd_i()
+void fadd_i(void)
 {
   /* fadd st(i),st */
   int i = FPU_rm;
@@ -77,7 +77,7 @@ void fadd_i()
 }
 
 
-void fmul_i()
+void fmul_i(void)
 {
   /* fmul st(i),st */
   clear_C1();
@@ -85,7 +85,7 @@ void fmul_i()
 }
 
 
-void fsubri()
+void fsubri(void)
 {
   /* fsubr st(i),st */
   clear_C1();
@@ -93,7 +93,7 @@ void fsubri()
 }
 
 
-void fsub_i()
+void fsub_i(void)
 {
   /* fsub st(i),st */
   clear_C1();
@@ -101,7 +101,7 @@ void fsub_i()
 }
 
 
-void fdivri()
+void fdivri(void)
 {
   /* fdivr st(i),st */
   clear_C1();
@@ -109,7 +109,7 @@ void fdivri()
 }
 
 
-void fdiv_i()
+void fdiv_i(void)
 {
   /* fdiv st(i),st */
   clear_C1();
@@ -118,7 +118,7 @@ void fdiv_i()
 
 
 
-void faddp_()
+void faddp_(void)
 {
   /* faddp st(i),st */
   int i = FPU_rm;
@@ -128,7 +128,7 @@ void faddp_()
 }
 
 
-void fmulp_()
+void fmulp_(void)
 {
   /* fmulp st(i),st */
   clear_C1();
@@ -138,7 +138,7 @@ void fmulp_()
 
 
 
-void fsubrp()
+void fsubrp(void)
 {
   /* fsubrp st(i),st */
   clear_C1();
@@ -147,7 +147,7 @@ void fsubrp()
 }
 
 
-void fsubp_()
+void fsubp_(void)
 {
   /* fsubp st(i),st */
   clear_C1();
@@ -156,7 +156,7 @@ void fsubp_()
 }
 
 
-void fdivrp()
+void fdivrp(void)
 {
   /* fdivrp st(i),st */
   clear_C1();
@@ -165,7 +165,7 @@ void fdivrp()
 }
 
 
-void fdivp_()
+void fdivp_(void)
 {
   /* fdivp st(i),st */
   clear_C1();
index 112c173..0251b2c 100644 (file)
@@ -30,7 +30,7 @@ void fclex(void)
 }
 
 /* Needs to be externally visible */
-void finit()
+void finit(void)
 {
   control_word = 0x037f;
   partial_status = 0;
@@ -58,7 +58,7 @@ static FUNC const finit_table[] = {
   fsetpm, FPU_illegal, FPU_illegal, FPU_illegal
 };
 
-void finit_()
+void finit_(void)
 {
   (finit_table[FPU_rm])();
 }
@@ -75,7 +75,7 @@ static FUNC const fstsw_table[] = {
   FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
 };
 
-void fstsw_()
+void fstsw_(void)
 {
   (fstsw_table[FPU_rm])();
 }
@@ -86,13 +86,13 @@ static FUNC const fp_nop_table[] = {
   FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
 };
 
-void fp_nop()
+void fp_nop(void)
 {
   (fp_nop_table[FPU_rm])();
 }
 
 
-void fld_i_()
+void fld_i_(void)
 {
   FPU_REG *st_new_ptr;
   int i;
@@ -124,7 +124,7 @@ void fld_i_()
 }
 
 
-void fxch_i()
+void fxch_i(void)
 {
   /* fxch st(i) */
   FPU_REG t;
@@ -173,14 +173,14 @@ void fxch_i()
 }
 
 
-void ffree_()
+void ffree_(void)
 {
   /* ffree st(i) */
   FPU_settagi(FPU_rm, TAG_Empty);
 }
 
 
-void ffreep()
+void ffreep(void)
 {
   /* ffree st(i) + pop - unofficial code */
   FPU_settagi(FPU_rm, TAG_Empty);
@@ -188,14 +188,14 @@ void ffreep()
 }
 
 
-void fst_i_()
+void fst_i_(void)
 {
   /* fst st(i) */
   FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
 }
 
 
-void fstp_i()
+void fstp_i(void)
 {
   /* fstp st(i) */
   FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
index baebe5c..633f954 100644 (file)
@@ -128,7 +128,7 @@ static u_char const type_table[64] = {
 u_char emulating=0;
 #endif /* RE_ENTRANT_CHECKING */
 
-static int valid_prefix(u_char *Byte, u_char **fpu_eip,
+static int valid_prefix(u_char *Byte, u_char __user **fpu_eip,
                        overrides *override);
 
 asmlinkage void math_emulate(long arg)
@@ -140,7 +140,7 @@ asmlinkage void math_emulate(long arg)
   FPU_REG loaded_data;
   FPU_REG *st0_ptr;
   u_char         loaded_tag, st0_tag;
-  void *data_address;
+  void __user *data_address;
   struct address data_sel_off;
   struct address entry_sel_off;
   unsigned long code_base = 0;
@@ -192,7 +192,8 @@ asmlinkage void math_emulate(long arg)
          math_abort(FPU_info, SIGILL);
        }
 
-      if ( SEG_D_SIZE(code_descriptor = LDT_DESCRIPTOR(FPU_CS)) )
+      code_descriptor = LDT_DESCRIPTOR(FPU_CS);
+      if ( SEG_D_SIZE(code_descriptor) )
        {
          /* The above test may be wrong, the book is not clear */
          /* Segmented 32 bit protected mode */
@@ -214,7 +215,7 @@ asmlinkage void math_emulate(long arg)
   if (current->ptrace & PT_PTRACED)
     FPU_lookahead = 0;
 
-  if ( !valid_prefix(&byte1, (u_char **)&FPU_EIP,
+  if ( !valid_prefix(&byte1, (u_char __user **)&FPU_EIP,
                     &addr_modes.override) )
     {
       RE_ENTRANT_CHECK_OFF;
@@ -257,7 +258,7 @@ do_another_FPU_instruction:
 
   RE_ENTRANT_CHECK_OFF;
   FPU_code_verify_area(1);
-  FPU_get_user(FPU_modrm, (u_char *) FPU_EIP);
+  FPU_get_user(FPU_modrm, (u_char __user *) FPU_EIP);
   RE_ENTRANT_CHECK_ON;
   FPU_EIP++;
 
@@ -336,23 +337,23 @@ do_another_FPU_instruction:
              switch ( (byte1 >> 1) & 3 )
                {
                case 0:
-                 unmasked = FPU_load_single((float *)data_address,
+                 unmasked = FPU_load_single((float __user *)data_address,
                                             &loaded_data);
                  loaded_tag = unmasked & 0xff;
                  unmasked &= ~0xff;
                  break;
                case 1:
-                 loaded_tag = FPU_load_int32((long *)data_address, &loaded_data);
+                 loaded_tag = FPU_load_int32((long __user *)data_address, &loaded_data);
                  break;
                case 2:
-                 unmasked = FPU_load_double((double *)data_address,
+                 unmasked = FPU_load_double((double __user *)data_address,
                                             &loaded_data);
                  loaded_tag = unmasked & 0xff;
                  unmasked &= ~0xff;
                  break;
                case 3:
                default:  /* Used here to suppress gcc warnings. */
-                 loaded_tag = FPU_load_int16((short *)data_address, &loaded_data);
+                 loaded_tag = FPU_load_int16((short __user *)data_address, &loaded_data);
                  break;
                }
 
@@ -563,7 +564,7 @@ FPU_fwait_done:
   if (FPU_lookahead && !need_resched())
     {
       FPU_ORIG_EIP = FPU_EIP - code_base;
-      if ( valid_prefix(&byte1, (u_char **)&FPU_EIP,
+      if ( valid_prefix(&byte1, (u_char __user **)&FPU_EIP,
                        &addr_modes.override) )
        goto do_another_FPU_instruction;
     }
@@ -579,11 +580,11 @@ FPU_fwait_done:
    all prefix bytes, further changes are needed in the emulator code
    which accesses user address space. Access to separate segments is
    important for msdos emulation. */
-static int valid_prefix(u_char *Byte, u_char **fpu_eip,
+static int valid_prefix(u_char *Byte, u_char __user **fpu_eip,
                        overrides *override)
 {
   u_char byte;
-  u_char *ip = *fpu_eip;
+  u_char __user *ip = *fpu_eip;
 
   *override = (overrides) { 0, 0, PREFIX_DEFAULT };       /* defaults */
 
@@ -679,9 +680,9 @@ void math_abort(struct info * info, unsigned int signal)
 #define sstatus_word() \
   ((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top))
 
-int restore_i387_soft(void *s387, struct _fpstate *buf)
+int restore_i387_soft(void *s387, struct _fpstate __user *buf)
 {
-  u_char *d = (u_char *)buf;
+  u_char __user *d = (u_char __user *)buf;
   int offset, other, i, tags, regnr, tag, newtop;
 
   RE_ENTRANT_CHECK_OFF;
@@ -725,9 +726,9 @@ int restore_i387_soft(void *s387, struct _fpstate *buf)
 }
 
 
-int save_i387_soft(void *s387, struct _fpstate * buf)
+int save_i387_soft(void *s387, struct _fpstate __user * buf)
 {
-  u_char *d = (u_char *)buf;
+  u_char __user *d = (u_char __user *)buf;
   int offset = (S387->ftop & 7) * 10, other = 80 - offset;
 
   RE_ENTRANT_CHECK_OFF;
index ba562d1..e3b5d46 100644 (file)
@@ -137,7 +137,7 @@ static FUNC_ST0 const fp_etc_table[] = {
   ftst_, fxam, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal
 };
 
-void FPU_etc()
+void FPU_etc(void)
 {
   (fp_etc_table[FPU_rm])(&st(0), FPU_gettag0());
 }
index fb61163..a8618df 100644 (file)
@@ -77,13 +77,13 @@ extern void FPU_copy_to_reg0(FPU_REG const *r, u_char tag);
 extern void FPU_triga(void);
 extern void FPU_trigb(void);
 /* get_address.c */
-extern void *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
+extern void __user *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
                         struct address *addr, fpu_addr_modes addr_modes);
-extern void *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
+extern void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
                            struct address *addr, fpu_addr_modes addr_modes);
 /* load_store.c */
 extern int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
-                           void *data_address);
+                           void __user *data_address);
 /* poly_2xm1.c */
 extern int poly_2xm1(u_char sign, FPU_REG *arg, FPU_REG *result);
 /* poly_atan.c */
@@ -112,26 +112,26 @@ extern void fucompp(void);
 /* reg_constant.c */
 extern void fconst(void);
 /* reg_ld_str.c */
-extern int FPU_load_extended(long double *s, int stnr);
-extern int FPU_load_double(double *dfloat, FPU_REG *loaded_data);
-extern int FPU_load_single(float *single, FPU_REG *loaded_data);
-extern int FPU_load_int64(long long *_s);
-extern int FPU_load_int32(long *_s, FPU_REG *loaded_data);
-extern int FPU_load_int16(short *_s, FPU_REG *loaded_data);
-extern int FPU_load_bcd(u_char *s);
+extern int FPU_load_extended(long double __user *s, int stnr);
+extern int FPU_load_double(double __user *dfloat, FPU_REG *loaded_data);
+extern int FPU_load_single(float __user *single, FPU_REG *loaded_data);
+extern int FPU_load_int64(long long __user *_s);
+extern int FPU_load_int32(long __user *_s, FPU_REG *loaded_data);
+extern int FPU_load_int16(short __user *_s, FPU_REG *loaded_data);
+extern int FPU_load_bcd(u_char __user *s);
 extern int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag,
-                             long double *d);
-extern int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double *dfloat);
-extern int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single);
-extern int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long *d);
-extern int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long *d);
-extern int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short *d);
-extern int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char *d);
+                             long double __user *d);
+extern int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double __user *dfloat);
+extern int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float __user *single);
+extern int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d);
+extern int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long __user *d);
+extern int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short __user *d);
+extern int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d);
 extern int FPU_round_to_int(FPU_REG *r, u_char tag);
-extern u_char *fldenv(fpu_addr_modes addr_modes, u_char *s);
-extern void frstor(fpu_addr_modes addr_modes, u_char *data_address);
-extern u_char *fstenv(fpu_addr_modes addr_modes, u_char *d);
-extern void fsave(fpu_addr_modes addr_modes, u_char *data_address);
+extern u_char __user *fldenv(fpu_addr_modes addr_modes, u_char __user *s);
+extern void frstor(fpu_addr_modes addr_modes, u_char __user *data_address);
+extern u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d);
+extern void fsave(fpu_addr_modes addr_modes, u_char __user *data_address);
 extern int FPU_tagof(FPU_REG *ptr);
 /* reg_mul.c */
 extern int FPU_mul(FPU_REG const *b, u_char tagb, int deststnr, int control_w);
index 78693a5..7ff3286 100644 (file)
@@ -81,7 +81,7 @@
 /* A simpler test than verify_area() can probably be done for
    FPU_code_verify_area() because the only possible error is to step
    past the upper boundary of a legal code area. */
-#define        FPU_code_verify_area(z) FPU_verify_area(VERIFY_READ,(void *)FPU_EIP,z)
+#define        FPU_code_verify_area(z) FPU_verify_area(VERIFY_READ,(void __user *)FPU_EIP,z)
 #endif
 
 #define FPU_get_user(x,y)       get_user((x),(y))
index dd568ad..59eee72 100644 (file)
@@ -82,7 +82,7 @@ static int sib(int mod, unsigned long *fpu_eip)
 
   RE_ENTRANT_CHECK_OFF;
   FPU_code_verify_area(1);
-  FPU_get_user(base, (u_char *) (*fpu_eip));   /* The SIB byte */
+  FPU_get_user(base, (u_char __user *) (*fpu_eip));   /* The SIB byte */
   RE_ENTRANT_CHECK_ON;
   (*fpu_eip)++;
   ss = base >> 6;
@@ -112,7 +112,7 @@ static int sib(int mod, unsigned long *fpu_eip)
       long displacement;
       RE_ENTRANT_CHECK_OFF;
       FPU_code_verify_area(1);
-      FPU_get_user(displacement, (signed char *) (*fpu_eip));
+      FPU_get_user(displacement, (signed char __user *) (*fpu_eip));
       offset += displacement;
       RE_ENTRANT_CHECK_ON;
       (*fpu_eip)++;
@@ -123,7 +123,7 @@ static int sib(int mod, unsigned long *fpu_eip)
       long displacement;
       RE_ENTRANT_CHECK_OFF;
       FPU_code_verify_area(4);
-      FPU_get_user(displacement, (long *) (*fpu_eip));
+      FPU_get_user(displacement, (long __user *) (*fpu_eip));
       offset += displacement;
       RE_ENTRANT_CHECK_ON;
       (*fpu_eip) += 4;
@@ -241,7 +241,7 @@ static long pm_address(u_char FPU_modrm, u_char segment,
 
 */
 
-void *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
+void __user *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
                  struct address *addr,
                  fpu_addr_modes addr_modes)
 {
@@ -277,24 +277,24 @@ void *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
              /* Special case: disp32 */
              RE_ENTRANT_CHECK_OFF;
              FPU_code_verify_area(4);
-             FPU_get_user(address, (unsigned long *) (*fpu_eip));
+             FPU_get_user(address, (unsigned long __user *) (*fpu_eip));
              (*fpu_eip) += 4;
              RE_ENTRANT_CHECK_ON;
              addr->offset = address;
-             return (void *) address;
+             return (void __user *) address;
            }
          else
            {
              address = *cpu_reg_ptr;  /* Just return the contents
                                          of the cpu register */
              addr->offset = address;
-             return (void *) address;
+             return (void __user *) address;
            }
        case 1:
          /* 8 bit signed displacement */
          RE_ENTRANT_CHECK_OFF;
          FPU_code_verify_area(1);
-         FPU_get_user(address, (signed char *) (*fpu_eip));
+         FPU_get_user(address, (signed char __user *) (*fpu_eip));
          RE_ENTRANT_CHECK_ON;
          (*fpu_eip)++;
          break;
@@ -302,7 +302,7 @@ void *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
          /* 32 bit displacement */
          RE_ENTRANT_CHECK_OFF;
          FPU_code_verify_area(4);
-         FPU_get_user(address, (long *) (*fpu_eip));
+         FPU_get_user(address, (long __user *) (*fpu_eip));
          (*fpu_eip) += 4;
          RE_ENTRANT_CHECK_ON;
          break;
@@ -331,11 +331,11 @@ void *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
       EXCEPTION(EX_INTERNAL|0x133);
     }
 
-  return (void *)address;
+  return (void __user *)address;
 }
 
 
-void *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
+void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
                     struct address *addr,
                     fpu_addr_modes addr_modes)
 {
@@ -363,7 +363,7 @@ void *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
          /* Special case: disp16 */
          RE_ENTRANT_CHECK_OFF;
          FPU_code_verify_area(2);
-         FPU_get_user(address, (unsigned short *) (*fpu_eip));
+         FPU_get_user(address, (unsigned short __user *) (*fpu_eip));
          (*fpu_eip) += 2;
          RE_ENTRANT_CHECK_ON;
          goto add_segment;
@@ -373,7 +373,7 @@ void *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
       /* 8 bit signed displacement */
       RE_ENTRANT_CHECK_OFF;
       FPU_code_verify_area(1);
-      FPU_get_user(address, (signed char *) (*fpu_eip));
+      FPU_get_user(address, (signed char __user *) (*fpu_eip));
       RE_ENTRANT_CHECK_ON;
       (*fpu_eip)++;
       break;
@@ -381,7 +381,7 @@ void *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
       /* 16 bit displacement */
       RE_ENTRANT_CHECK_OFF;
       FPU_code_verify_area(2);
-      FPU_get_user(address, (unsigned short *) (*fpu_eip));
+      FPU_get_user(address, (unsigned short __user *) (*fpu_eip));
       (*fpu_eip) += 2;
       RE_ENTRANT_CHECK_ON;
       break;
@@ -445,5 +445,5 @@ void *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
       EXCEPTION(EX_INTERNAL|0x131);
     }
 
-  return (void *)address ;
+  return (void __user *)address ;
 }
index 27d2f40..ff3a617 100644 (file)
@@ -61,7 +61,7 @@ u_char const data_sizes_32[32] = {
 };
 
 int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
-                    void *data_address)
+                    void __user *data_address)
 {
   FPU_REG loaded_data;
   FPU_REG *st0_ptr;
@@ -119,7 +119,7 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
     {
     case 000:       /* fld m32real */
       clear_C1();
-      loaded_tag = FPU_load_single((float *)data_address, &loaded_data);
+      loaded_tag = FPU_load_single((float __user *)data_address, &loaded_data);
       if ( (loaded_tag == TAG_Special)
           && isNaN(&loaded_data)
           && (real_1op_NaN(&loaded_data) < 0) )
@@ -131,12 +131,12 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
       break;
     case 001:      /* fild m32int */
       clear_C1();
-      loaded_tag = FPU_load_int32((long *)data_address, &loaded_data);
+      loaded_tag = FPU_load_int32((long __user *)data_address, &loaded_data);
       FPU_copy_to_reg0(&loaded_data, loaded_tag);
       break;
     case 002:      /* fld m64real */
       clear_C1();
-      loaded_tag = FPU_load_double((double *)data_address, &loaded_data);
+      loaded_tag = FPU_load_double((double __user *)data_address, &loaded_data);
       if ( (loaded_tag == TAG_Special)
           && isNaN(&loaded_data)
           && (real_1op_NaN(&loaded_data) < 0) )
@@ -148,68 +148,68 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
       break;
     case 003:      /* fild m16int */
       clear_C1();
-      loaded_tag = FPU_load_int16((short *)data_address, &loaded_data);
+      loaded_tag = FPU_load_int16((short __user *)data_address, &loaded_data);
       FPU_copy_to_reg0(&loaded_data, loaded_tag);
       break;
     case 010:      /* fst m32real */
       clear_C1();
-      FPU_store_single(st0_ptr, st0_tag, (float *)data_address);
+      FPU_store_single(st0_ptr, st0_tag, (float __user *)data_address);
       break;
     case 011:      /* fist m32int */
       clear_C1();
-      FPU_store_int32(st0_ptr, st0_tag, (long *)data_address);
+      FPU_store_int32(st0_ptr, st0_tag, (long __user *)data_address);
       break;
     case 012:     /* fst m64real */
       clear_C1();
-      FPU_store_double(st0_ptr, st0_tag, (double *)data_address);
+      FPU_store_double(st0_ptr, st0_tag, (double __user *)data_address);
       break;
     case 013:     /* fist m16int */
       clear_C1();
-      FPU_store_int16(st0_ptr, st0_tag, (short *)data_address);
+      FPU_store_int16(st0_ptr, st0_tag, (short __user *)data_address);
       break;
     case 014:     /* fstp m32real */
       clear_C1();
-      if ( FPU_store_single(st0_ptr, st0_tag, (float *)data_address) )
+      if ( FPU_store_single(st0_ptr, st0_tag, (float __user *)data_address) )
        pop_0();  /* pop only if the number was actually stored
                     (see the 80486 manual p16-28) */
       break;
     case 015:     /* fistp m32int */
       clear_C1();
-      if ( FPU_store_int32(st0_ptr, st0_tag, (long *)data_address) )
+      if ( FPU_store_int32(st0_ptr, st0_tag, (long __user *)data_address) )
        pop_0();  /* pop only if the number was actually stored
                     (see the 80486 manual p16-28) */
       break;
     case 016:     /* fstp m64real */
       clear_C1();
-      if ( FPU_store_double(st0_ptr, st0_tag, (double *)data_address) )
+      if ( FPU_store_double(st0_ptr, st0_tag, (double __user *)data_address) )
        pop_0();  /* pop only if the number was actually stored
                     (see the 80486 manual p16-28) */
       break;
     case 017:     /* fistp m16int */
       clear_C1();
-      if ( FPU_store_int16(st0_ptr, st0_tag, (short *)data_address) )
+      if ( FPU_store_int16(st0_ptr, st0_tag, (short __user *)data_address) )
        pop_0();  /* pop only if the number was actually stored
                     (see the 80486 manual p16-28) */
       break;
     case 020:     /* fldenv  m14/28byte */
-      fldenv(addr_modes, (u_char *)data_address);
+      fldenv(addr_modes, (u_char __user *)data_address);
       /* Ensure that the values just loaded are not changed by
         fix-up operations. */
       return 1;
     case 022:     /* frstor m94/108byte */
-      frstor(addr_modes, (u_char *)data_address);
+      frstor(addr_modes, (u_char __user *)data_address);
       /* Ensure that the values just loaded are not changed by
         fix-up operations. */
       return 1;
     case 023:     /* fbld m80dec */
       clear_C1();
-      loaded_tag = FPU_load_bcd((u_char *)data_address);
+      loaded_tag = FPU_load_bcd((u_char __user *)data_address);
       FPU_settag0(loaded_tag);
       break;
     case 024:     /* fldcw */
       RE_ENTRANT_CHECK_OFF;
       FPU_verify_area(VERIFY_READ, data_address, 2);
-      FPU_get_user(control_word, (unsigned short *) data_address);
+      FPU_get_user(control_word, (unsigned short __user *) data_address);
       RE_ENTRANT_CHECK_ON;
       if ( partial_status & ~control_word & CW_Exceptions )
        partial_status |= (SW_Summary | SW_Backward);
@@ -221,47 +221,47 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
       return 1;
     case 025:      /* fld m80real */
       clear_C1();
-      loaded_tag = FPU_load_extended((long double *)data_address, 0);
+      loaded_tag = FPU_load_extended((long double __user *)data_address, 0);
       FPU_settag0(loaded_tag);
       break;
     case 027:      /* fild m64int */
       clear_C1();
-      loaded_tag = FPU_load_int64((long long *)data_address);
+      loaded_tag = FPU_load_int64((long long __user *)data_address);
       FPU_settag0(loaded_tag);
       break;
     case 030:     /* fstenv  m14/28byte */
-      fstenv(addr_modes, (u_char *)data_address);
+      fstenv(addr_modes, (u_char __user *)data_address);
       return 1;
     case 032:      /* fsave */
-      fsave(addr_modes, (u_char *)data_address);
+      fsave(addr_modes, (u_char __user *)data_address);
       return 1;
     case 033:      /* fbstp m80dec */
       clear_C1();
-      if ( FPU_store_bcd(st0_ptr, st0_tag, (u_char *)data_address) )
+      if ( FPU_store_bcd(st0_ptr, st0_tag, (u_char __user *)data_address) )
        pop_0();  /* pop only if the number was actually stored
                     (see the 80486 manual p16-28) */
       break;
     case 034:      /* fstcw m16int */
       RE_ENTRANT_CHECK_OFF;
       FPU_verify_area(VERIFY_WRITE,data_address,2);
-      FPU_put_user(control_word, (unsigned short *) data_address);
+      FPU_put_user(control_word, (unsigned short __user *) data_address);
       RE_ENTRANT_CHECK_ON;
       return 1;
     case 035:      /* fstp m80real */
       clear_C1();
-      if ( FPU_store_extended(st0_ptr, st0_tag, (long double *)data_address) )
+      if ( FPU_store_extended(st0_ptr, st0_tag, (long double __user *)data_address) )
        pop_0();  /* pop only if the number was actually stored
                     (see the 80486 manual p16-28) */
       break;
     case 036:      /* fstsw m2byte */
       RE_ENTRANT_CHECK_OFF;
       FPU_verify_area(VERIFY_WRITE,data_address,2);
-      FPU_put_user(status_word(),(unsigned short *) data_address);
+      FPU_put_user(status_word(),(unsigned short __user *) data_address);
       RE_ENTRANT_CHECK_ON;
       return 1;
     case 037:      /* fistp m64int */
       clear_C1();
-      if ( FPU_store_int64(st0_ptr, st0_tag, (long long *)data_address) )
+      if ( FPU_store_int64(st0_ptr, st0_tag, (long long __user *)data_address) )
        pop_0();  /* pop only if the number was actually stored
                     (see the 80486 manual p16-28) */
       break;
index afd222c..f37c5b5 100644 (file)
@@ -324,14 +324,14 @@ static int compare_u_st_st(int nr)
 
 /*---------------------------------------------------------------------------*/
 
-void fcom_st()
+void fcom_st(void)
 {
   /* fcom st(i) */
   compare_st_st(FPU_rm);
 }
 
 
-void fcompst()
+void fcompst(void)
 {
   /* fcomp st(i) */
   if ( !compare_st_st(FPU_rm) )
@@ -339,7 +339,7 @@ void fcompst()
 }
 
 
-void fcompp()
+void fcompp(void)
 {
   /* fcompp */
   if (FPU_rm != 1)
@@ -352,7 +352,7 @@ void fcompp()
 }
 
 
-void fucom_()
+void fucom_(void)
 {
   /* fucom st(i) */
   compare_u_st_st(FPU_rm);
@@ -360,7 +360,7 @@ void fucom_()
 }
 
 
-void fucomp()
+void fucomp(void)
 {
   /* fucomp st(i) */
   if ( !compare_u_st_st(FPU_rm) )
@@ -368,7 +368,7 @@ void fucomp()
 }
 
 
-void fucompp()
+void fucompp(void)
 {
   /* fucompp */
   if (FPU_rm == 1)
index cdd3746..699fe33 100644 (file)
@@ -86,7 +86,7 @@ int FPU_tagof(FPU_REG *ptr)
 
 
 /* Get a long double from user memory */
-int FPU_load_extended(long double *s, int stnr)
+int FPU_load_extended(long double __user *s, int stnr)
 {
   FPU_REG *sti_ptr = &st(stnr);
 
@@ -100,15 +100,15 @@ int FPU_load_extended(long double *s, int stnr)
 
 
 /* Get a double from user memory */
-int FPU_load_double(double *dfloat, FPU_REG *loaded_data)
+int FPU_load_double(double __user *dfloat, FPU_REG *loaded_data)
 {
   int exp, tag, negative;
   unsigned m64, l64;
 
   RE_ENTRANT_CHECK_OFF;
   FPU_verify_area(VERIFY_READ, dfloat, 8);
-  FPU_get_user(m64, 1 + (unsigned long *) dfloat);
-  FPU_get_user(l64, (unsigned long *) dfloat);
+  FPU_get_user(m64, 1 + (unsigned long __user *) dfloat);
+  FPU_get_user(l64, (unsigned long __user *) dfloat);
   RE_ENTRANT_CHECK_ON;
 
   negative = (m64 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
@@ -172,14 +172,14 @@ int FPU_load_double(double *dfloat, FPU_REG *loaded_data)
 
 
 /* Get a float from user memory */
-int FPU_load_single(float *single, FPU_REG *loaded_data)
+int FPU_load_single(float __user *single, FPU_REG *loaded_data)
 {
   unsigned m32;
   int exp, tag, negative;
 
   RE_ENTRANT_CHECK_OFF;
   FPU_verify_area(VERIFY_READ, single, 4);
-  FPU_get_user(m32, (unsigned long *) single);
+  FPU_get_user(m32, (unsigned long __user *) single);
   RE_ENTRANT_CHECK_ON;
 
   negative = (m32 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
@@ -236,7 +236,7 @@ int FPU_load_single(float *single, FPU_REG *loaded_data)
 
 
 /* Get a long long from user memory */
-int FPU_load_int64(long long *_s)
+int FPU_load_int64(long long __user *_s)
 {
   long long s;
   int sign;
@@ -268,7 +268,7 @@ int FPU_load_int64(long long *_s)
 
 
 /* Get a long from user memory */
-int FPU_load_int32(long *_s, FPU_REG *loaded_data)
+int FPU_load_int32(long __user *_s, FPU_REG *loaded_data)
 {
   long s;
   int negative;
@@ -297,7 +297,7 @@ int FPU_load_int32(long *_s, FPU_REG *loaded_data)
 
 
 /* Get a short from user memory */
-int FPU_load_int16(short *_s, FPU_REG *loaded_data)
+int FPU_load_int16(short __user *_s, FPU_REG *loaded_data)
 {
   int s, negative;
 
@@ -326,7 +326,7 @@ int FPU_load_int16(short *_s, FPU_REG *loaded_data)
 
 
 /* Get a packed bcd array from user memory */
-int FPU_load_bcd(u_char *s)
+int FPU_load_bcd(u_char __user *s)
 {
   FPU_REG *st0_ptr = &st(0);
   int pos;
@@ -341,7 +341,7 @@ int FPU_load_bcd(u_char *s)
     {
       l *= 10;
       RE_ENTRANT_CHECK_OFF;
-      FPU_get_user(bcd, (u_char *) s+pos);
+      FPU_get_user(bcd, s+pos);
       RE_ENTRANT_CHECK_ON;
       l += bcd >> 4;
       l *= 10;
@@ -349,7 +349,7 @@ int FPU_load_bcd(u_char *s)
     }
  
   RE_ENTRANT_CHECK_OFF;
-  FPU_get_user(sign, (u_char *) s+9);
+  FPU_get_user(sign, s+9);
   sign = sign & 0x80 ? SIGN_Negative : SIGN_Positive;
   RE_ENTRANT_CHECK_ON;
 
@@ -369,7 +369,7 @@ int FPU_load_bcd(u_char *s)
 /*===========================================================================*/
 
 /* Put a long double into user memory */
-int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, long double *d)
+int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, long double __user *d)
 {
   /*
     The only exception raised by an attempt to store to an
@@ -382,9 +382,9 @@ int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, long double *d)
       RE_ENTRANT_CHECK_OFF;
       FPU_verify_area(VERIFY_WRITE, d, 10);
 
-      FPU_put_user(st0_ptr->sigl, (unsigned long *) d);
-      FPU_put_user(st0_ptr->sigh, (unsigned long *) ((u_char *)d + 4));
-      FPU_put_user(exponent16(st0_ptr), (unsigned short *) ((u_char *)d + 8));
+      FPU_put_user(st0_ptr->sigl, (unsigned long __user *) d);
+      FPU_put_user(st0_ptr->sigh, (unsigned long __user *) ((u_char __user *)d + 4));
+      FPU_put_user(exponent16(st0_ptr), (unsigned short __user *) ((u_char __user *)d + 8));
       RE_ENTRANT_CHECK_ON;
 
       return 1;
@@ -398,9 +398,9 @@ int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, long double *d)
       /* Put out the QNaN indefinite */
       RE_ENTRANT_CHECK_OFF;
       FPU_verify_area(VERIFY_WRITE,d,10);
-      FPU_put_user(0, (unsigned long *) d);
-      FPU_put_user(0xc0000000, 1 + (unsigned long *) d);
-      FPU_put_user(0xffff, 4 + (short *) d);
+      FPU_put_user(0, (unsigned long __user *) d);
+      FPU_put_user(0xc0000000, 1 + (unsigned long __user *) d);
+      FPU_put_user(0xffff, 4 + (short __user *) d);
       RE_ENTRANT_CHECK_ON;
       return 1;
     }
@@ -411,7 +411,7 @@ int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, long double *d)
 
 
 /* Put a double into user memory */
-int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double *dfloat)
+int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double __user *dfloat)
 {
   unsigned long l[2];
   unsigned long increment = 0; /* avoid gcc warnings */
@@ -607,9 +607,9 @@ int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double *dfloat)
          /* The masked response */
          /* Put out the QNaN indefinite */
          RE_ENTRANT_CHECK_OFF;
-         FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8);
-         FPU_put_user(0, (unsigned long *) dfloat);
-         FPU_put_user(0xfff80000, 1 + (unsigned long *) dfloat);
+         FPU_verify_area(VERIFY_WRITE,dfloat,8);
+         FPU_put_user(0, (unsigned long __user *) dfloat);
+         FPU_put_user(0xfff80000, 1 + (unsigned long __user *) dfloat);
          RE_ENTRANT_CHECK_ON;
          return 1;
        }
@@ -620,9 +620,9 @@ int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double *dfloat)
     l[1] |= 0x80000000;
 
   RE_ENTRANT_CHECK_OFF;
-  FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8);
-  FPU_put_user(l[0], (unsigned long *)dfloat);
-  FPU_put_user(l[1], 1 + (unsigned long *)dfloat);
+  FPU_verify_area(VERIFY_WRITE,dfloat,8);
+  FPU_put_user(l[0], (unsigned long __user *)dfloat);
+  FPU_put_user(l[1], 1 + (unsigned long __user *)dfloat);
   RE_ENTRANT_CHECK_ON;
 
   return 1;
@@ -630,7 +630,7 @@ int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double *dfloat)
 
 
 /* Put a float into user memory */
-int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single)
+int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float __user *single)
 {
   long templ = 0;
   unsigned long increment = 0;         /* avoid gcc warnings */
@@ -826,8 +826,8 @@ int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single)
          /* The masked response */
          /* Put out the QNaN indefinite */
          RE_ENTRANT_CHECK_OFF;
-         FPU_verify_area(VERIFY_WRITE,(void *)single,4);
-         FPU_put_user(0xffc00000, (unsigned long *) single);
+         FPU_verify_area(VERIFY_WRITE,single,4);
+         FPU_put_user(0xffc00000, (unsigned long __user *) single);
          RE_ENTRANT_CHECK_ON;
          return 1;
        }
@@ -845,8 +845,8 @@ int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single)
     templ |= 0x80000000;
 
   RE_ENTRANT_CHECK_OFF;
-  FPU_verify_area(VERIFY_WRITE,(void *)single,4);
-  FPU_put_user(templ,(unsigned long *) single);
+  FPU_verify_area(VERIFY_WRITE,single,4);
+  FPU_put_user(templ,(unsigned long __user *) single);
   RE_ENTRANT_CHECK_ON;
 
   return 1;
@@ -854,7 +854,7 @@ int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single)
 
 
 /* Put a long long into user memory */
-int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long *d)
+int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d)
 {
   FPU_REG t;
   long long tll;
@@ -906,7 +906,7 @@ int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long *d)
     }
 
   RE_ENTRANT_CHECK_OFF;
-  FPU_verify_area(VERIFY_WRITE,(void *)d,8);
+  FPU_verify_area(VERIFY_WRITE,d,8);
   copy_to_user(d, &tll, 8);
   RE_ENTRANT_CHECK_ON;
 
@@ -915,7 +915,7 @@ int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long *d)
 
 
 /* Put a long into user memory */
-int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long *d)
+int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long __user *d)
 {
   FPU_REG t;
   int precision_loss;
@@ -964,7 +964,7 @@ int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long *d)
 
   RE_ENTRANT_CHECK_OFF;
   FPU_verify_area(VERIFY_WRITE,d,4);
-  FPU_put_user(t.sigl, (unsigned long *) d);
+  FPU_put_user(t.sigl, (unsigned long __user *) d);
   RE_ENTRANT_CHECK_ON;
 
   return 1;
@@ -972,7 +972,7 @@ int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long *d)
 
 
 /* Put a short into user memory */
-int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short *d)
+int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short __user *d)
 {
   FPU_REG t;
   int precision_loss;
@@ -1021,7 +1021,7 @@ int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short *d)
 
   RE_ENTRANT_CHECK_OFF;
   FPU_verify_area(VERIFY_WRITE,d,2);
-  FPU_put_user((short)t.sigl,(short *) d);
+  FPU_put_user((short)t.sigl, d);
   RE_ENTRANT_CHECK_ON;
 
   return 1;
@@ -1029,7 +1029,7 @@ int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short *d)
 
 
 /* Put a packed bcd array into user memory */
-int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char *d)
+int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d)
 {
   FPU_REG t;
   unsigned long long ll;
@@ -1071,10 +1071,10 @@ int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char *d)
          RE_ENTRANT_CHECK_OFF;
          FPU_verify_area(VERIFY_WRITE,d,10);
          for ( i = 0; i < 7; i++)
-           FPU_put_user(0, (u_char *) d+i); /* These bytes "undefined" */
-         FPU_put_user(0xc0, (u_char *) d+7); /* This byte "undefined" */
-         FPU_put_user(0xff, (u_char *) d+8);
-         FPU_put_user(0xff, (u_char *) d+9);
+           FPU_put_user(0, d+i); /* These bytes "undefined" */
+         FPU_put_user(0xc0, d+7); /* This byte "undefined" */
+         FPU_put_user(0xff, d+8);
+         FPU_put_user(0xff, d+9);
          RE_ENTRANT_CHECK_ON;
          return 1;
        }
@@ -1095,11 +1095,11 @@ int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char *d)
       b = FPU_div_small(&ll, 10);
       b |= (FPU_div_small(&ll, 10)) << 4;
       RE_ENTRANT_CHECK_OFF;
-      FPU_put_user(b,(u_char *) d+i);
+      FPU_put_user(b, d+i);
       RE_ENTRANT_CHECK_ON;
     }
   RE_ENTRANT_CHECK_OFF;
-  FPU_put_user(sign,(u_char *) d+9);
+  FPU_put_user(sign, d+9);
   RE_ENTRANT_CHECK_ON;
 
   return 1;
@@ -1175,7 +1175,7 @@ int FPU_round_to_int(FPU_REG *r, u_char tag)
 
 /*===========================================================================*/
 
-u_char *fldenv(fpu_addr_modes addr_modes, u_char *s)
+u_char __user *fldenv(fpu_addr_modes addr_modes, u_char __user *s)
 {
   unsigned short tag_word = 0;
   u_char tag;
@@ -1187,13 +1187,13 @@ u_char *fldenv(fpu_addr_modes addr_modes, u_char *s)
     {
       RE_ENTRANT_CHECK_OFF;
       FPU_verify_area(VERIFY_READ, s, 0x0e);
-      FPU_get_user(control_word, (unsigned short *) s);
-      FPU_get_user(partial_status, (unsigned short *) (s+2));
-      FPU_get_user(tag_word, (unsigned short *) (s+4));
-      FPU_get_user(instruction_address.offset, (unsigned short *) (s+6));
-      FPU_get_user(instruction_address.selector, (unsigned short *) (s+8));
-      FPU_get_user(operand_address.offset, (unsigned short *) (s+0x0a));
-      FPU_get_user(operand_address.selector, (unsigned short *) (s+0x0c));
+      FPU_get_user(control_word, (unsigned short __user *) s);
+      FPU_get_user(partial_status, (unsigned short __user *) (s+2));
+      FPU_get_user(tag_word, (unsigned short __user *) (s+4));
+      FPU_get_user(instruction_address.offset, (unsigned short __user *) (s+6));
+      FPU_get_user(instruction_address.selector, (unsigned short __user *) (s+8));
+      FPU_get_user(operand_address.offset, (unsigned short __user *) (s+0x0a));
+      FPU_get_user(operand_address.selector, (unsigned short __user *) (s+0x0c));
       RE_ENTRANT_CHECK_ON;
       s += 0x0e;
       if ( addr_modes.default_mode == VM86 )
@@ -1207,14 +1207,14 @@ u_char *fldenv(fpu_addr_modes addr_modes, u_char *s)
     {
       RE_ENTRANT_CHECK_OFF;
       FPU_verify_area(VERIFY_READ, s, 0x1c);
-      FPU_get_user(control_word, (unsigned short *) s);
-      FPU_get_user(partial_status, (unsigned short *) (s+4));
-      FPU_get_user(tag_word, (unsigned short *) (s+8));
-      FPU_get_user(instruction_address.offset, (unsigned long *) (s+0x0c));
-      FPU_get_user(instruction_address.selector, (unsigned short *) (s+0x10));
-      FPU_get_user(instruction_address.opcode, (unsigned short *) (s+0x12));
-      FPU_get_user(operand_address.offset, (unsigned long *) (s+0x14));
-      FPU_get_user(operand_address.selector, (unsigned long *) (s+0x18));
+      FPU_get_user(control_word, (unsigned short __user *) s);
+      FPU_get_user(partial_status, (unsigned short __user *) (s+4));
+      FPU_get_user(tag_word, (unsigned short __user *) (s+8));
+      FPU_get_user(instruction_address.offset, (unsigned long __user *) (s+0x0c));
+      FPU_get_user(instruction_address.selector, (unsigned short __user *) (s+0x10));
+      FPU_get_user(instruction_address.opcode, (unsigned short __user *) (s+0x12));
+      FPU_get_user(operand_address.offset, (unsigned long __user *) (s+0x14));
+      FPU_get_user(operand_address.selector, (unsigned long __user *) (s+0x18));
       RE_ENTRANT_CHECK_ON;
       s += 0x1c;
     }
@@ -1266,10 +1266,10 @@ u_char *fldenv(fpu_addr_modes addr_modes, u_char *s)
 }
 
 
-void frstor(fpu_addr_modes addr_modes, u_char *data_address)
+void frstor(fpu_addr_modes addr_modes, u_char __user *data_address)
 {
   int i, regnr;
-  u_char *s = fldenv(addr_modes, data_address);
+  u_char __user *s = fldenv(addr_modes, data_address);
   int offset = (top & 7) * 10, other = 80 - offset;
 
   /* Copy all registers in stack order. */
@@ -1291,7 +1291,7 @@ void frstor(fpu_addr_modes addr_modes, u_char *data_address)
 }
 
 
-u_char *fstenv(fpu_addr_modes addr_modes, u_char *d)
+u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d)
 {
   if ( (addr_modes.default_mode == VM86) ||
       ((addr_modes.default_mode == PM16)
@@ -1300,25 +1300,25 @@ u_char *fstenv(fpu_addr_modes addr_modes, u_char *d)
       RE_ENTRANT_CHECK_OFF;
       FPU_verify_area(VERIFY_WRITE,d,14);
 #ifdef PECULIAR_486
-      FPU_put_user(control_word & ~0xe080, (unsigned long *) d);
+      FPU_put_user(control_word & ~0xe080, (unsigned long __user *) d);
 #else
-      FPU_put_user(control_word, (unsigned short *) d);
+      FPU_put_user(control_word, (unsigned short __user *) d);
 #endif /* PECULIAR_486 */
-      FPU_put_user(status_word(), (unsigned short *) (d+2));
-      FPU_put_user(fpu_tag_word, (unsigned short *) (d+4));
-      FPU_put_user(instruction_address.offset, (unsigned short *) (d+6));
-      FPU_put_user(operand_address.offset, (unsigned short *) (d+0x0a));
+      FPU_put_user(status_word(), (unsigned short __user *) (d+2));
+      FPU_put_user(fpu_tag_word, (unsigned short __user *) (d+4));
+      FPU_put_user(instruction_address.offset, (unsigned short __user *) (d+6));
+      FPU_put_user(operand_address.offset, (unsigned short __user *) (d+0x0a));
       if ( addr_modes.default_mode == VM86 )
        {
          FPU_put_user((instruction_address.offset & 0xf0000) >> 4,
-                     (unsigned short *) (d+8));
+                     (unsigned short __user *) (d+8));
          FPU_put_user((operand_address.offset & 0xf0000) >> 4,
-                     (unsigned short *) (d+0x0c));
+                     (unsigned short __user *) (d+0x0c));
        }
       else
        {
-         FPU_put_user(instruction_address.selector, (unsigned short *) (d+8));
-         FPU_put_user(operand_address.selector, (unsigned short *) (d+0x0c));
+         FPU_put_user(instruction_address.selector, (unsigned short __user *) (d+8));
+         FPU_put_user(operand_address.selector, (unsigned short __user *) (d+0x0c));
        }
       RE_ENTRANT_CHECK_ON;
       d += 0x0e;
@@ -1348,9 +1348,9 @@ u_char *fstenv(fpu_addr_modes addr_modes, u_char *d)
 }
 
 
-void fsave(fpu_addr_modes addr_modes, u_char *data_address)
+void fsave(fpu_addr_modes addr_modes, u_char __user *data_address)
 {
-  u_char *d;
+  u_char __user *d;
   int offset = (top & 7) * 10, other = 80 - offset;
 
   d = fstenv(addr_modes, data_address);
index 97d4af3..4ea886f 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/pgalloc.h>
 #include <asm/hardirq.h>
 #include <asm/desc.h>
 #include <asm/tlbflush.h>
@@ -451,7 +450,7 @@ no_context:
        else
                printk(KERN_ALERT "Unable to handle kernel paging request");
        printk(" at virtual address %08lx\n",address);
-       printk(" printing eip:\n");
+       printk(KERN_ALERT " printing eip:\n");
        printk("%08lx\n", regs->eip);
        asm("movl %%cr3,%0":"=r" (page));
        page = ((unsigned long *) __va(page))[address >> 22];
index 0397fe9..1ed5962 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/err.h>
 #include <linux/sysctl.h>
 #include <asm/mman.h>
-#include <asm/pgalloc.h>
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 
@@ -245,8 +244,15 @@ int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
                        ret = -ENOMEM;
                        goto out;
                }
-               if (!pte_none(*pte))
-                       continue;
+
+               if (!pte_none(*pte)) {
+                       pmd_t *pmd = (pmd_t *) pte;
+
+                       page = pmd_page(*pmd);
+                       pmd_clear(pmd);
+                       dec_page_state(nr_page_table_pages);
+                       page_cache_release(page);
+               }
 
                idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
                        + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
index 77179eb..837110f 100644 (file)
@@ -32,7 +32,6 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
-#include <asm/pgalloc.h>
 #include <asm/dma.h>
 #include <asm/fixmap.h>
 #include <asm/e820.h>
index 8c15932..7b11be0 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <asm/io.h>
-#include <asm/pgalloc.h>
 #include <asm/fixmap.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
index d0a5b79..86ce016 100644 (file)
@@ -1,6 +1,8 @@
 #include <linux/pci.h>
 #include <linux/acpi.h>
 #include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/hw_irq.h>
 #include "pci.h"
 
 struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum)
@@ -15,18 +17,31 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
 
 static int __init pci_acpi_init(void)
 {
+       struct pci_dev *dev = NULL;
+
        if (pcibios_scanned)
                return 0;
 
-       if (!acpi_noirq) {
-               if (!acpi_pci_irq_init()) {
-                       printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
-                       pcibios_scanned++;
-                       pcibios_enable_irq = acpi_pci_irq_enable;
-               } else
-                       printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n");
+       if (acpi_noirq)
+               return 0;
 
-       }
+       printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
+       acpi_irq_penalty_init();
+       pcibios_scanned++;
+       pcibios_enable_irq = acpi_pci_irq_enable;
+
+       /*
+        * PCI IRQ routing is set up by pci_enable_device(), but we
+        * also do it here in case there are still broken drivers that
+        * don't use pci_enable_device().
+        */
+       while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+               acpi_pci_irq_enable(dev);
+
+#ifdef CONFIG_X86_IO_APIC
+       if (acpi_ioapic)
+               print_IO_APIC();
+#endif
 
        return 0;
 }
index ac6acb3..a8b1954 100644 (file)
@@ -226,7 +226,12 @@ static void __init pci_fixup_nforce2(struct pci_dev *dev)
        fixed_val = rev < 0xC1 ? 0x1F01FF01 : 0x9F01FF01;
 
        pci_read_config_dword(dev, 0x6c, &val);
-       if (val != fixed_val) {
+
+       /*
+        * Apply fixup only if C1 Halt Disconnect is enabled
+        * (bit28) because it is not supported on some boards.
+        */
+       if ((val & (1 << 28)) && val != fixed_val) {
                printk(KERN_WARNING "PCI: nForce2 C1 Halt Disconnect fixup\n");
                pci_write_config_dword(dev, 0x6c, fixed_val);
        }
index b856ffa..573b749 100644 (file)
@@ -75,15 +75,6 @@ config IA64_HP_SIM
 
 endchoice
 
-config HOTPLUG_CPU
-    bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
-    depends on SMP && HOTPLUG && EXPERIMENTAL
-       default n
-    ---help---
-      Say Y here to experiment with turning CPUs off and on.  CPUs
-      can be controlled through /sys/devices/system/cpu/cpu#.
-      Say N if you want to disable cpu hotplug.
-
 choice
        prompt "Processor type"
        default ITANIUM
@@ -250,6 +241,15 @@ config NR_CPUS
          than 64 will cause the use of a CPU mask array, causing a small
          performance hit.
 
+config HOTPLUG_CPU
+    bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+    depends on SMP && HOTPLUG && EXPERIMENTAL
+       default n
+    ---help---
+      Say Y here to experiment with turning CPUs off and on.  CPUs
+      can be controlled through /sys/devices/system/cpu/cpu#.
+      Say N if you want to disable CPU hotplug.
+
 config PREEMPT
        bool "Preemptible Kernel"
         help
index 30f2b84..a8becf0 100644 (file)
@@ -218,3 +218,16 @@ elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int p
        return ia32_do_mmap(filep, (addr & IA32_PAGE_MASK), eppnt->p_filesz + pgoff, prot, type,
                            eppnt->p_offset - pgoff);
 }
+
+#define cpu_uses_ia32el()      (local_cpu_data->family > 0x1f)
+
+static int __init check_elf32_binfmt(void)
+{
+       if (cpu_uses_ia32el()) {
+               printk("Please use IA-32 EL for executing IA-32 binaries\n");
+               return unregister_binfmt(&elf_format);
+       }
+       return 0;
+}
+
+module_init(check_elf32_binfmt)
index 4ee1e55..0c7db9e 100644 (file)
@@ -349,7 +349,7 @@ ia32_syscall_table:
        data8 sys_setfsuid      /* 16-bit version */
        data8 sys_setfsgid      /* 16-bit version */
        data8 sys_llseek          /* 140 */
-       data8 sys32_getdents
+       data8 compat_sys_getdents
        data8 compat_sys_select
        data8 sys_flock
        data8 sys32_msync
@@ -428,7 +428,7 @@ ia32_syscall_table:
        data8 sys_pivot_root
        data8 sys_mincore
        data8 sys_madvise
-       data8 sys_getdents64      /* 220 */
+       data8 compat_sys_getdents64       /* 220 */
        data8 compat_sys_fcntl64
        data8 sys_ni_syscall            /* reserved for TUX */
        data8 sys_ni_syscall            /* reserved for Security */
index 10f2c7c..2826444 100644 (file)
@@ -521,9 +521,14 @@ acpi_numa_arch_fixup (void)
 #endif /* CONFIG_ACPI_NUMA */
 
 unsigned int
-acpi_register_gsi (u32 gsi, int polarity, int trigger)
+acpi_register_gsi (u32 gsi, int edge_level, int active_high_low)
 {
-       return acpi_register_irq(gsi, polarity, trigger);
+       if (has_8259 && gsi < 16)
+               return isa_irq_to_vector(gsi);
+
+       return iosapic_register_intr(gsi,
+                       (active_high_low == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
+                       (edge_level == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
 }
 EXPORT_SYMBOL(acpi_register_gsi);
 
@@ -548,7 +553,7 @@ acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
        if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES)
                acpi_legacy_devices = 1;
 
-       acpi_register_gsi(fadt->sci_int, ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE);
+       acpi_register_gsi(fadt->sci_int, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
        return 0;
 }
 
@@ -662,16 +667,4 @@ acpi_gsi_to_irq (u32 gsi, unsigned int *irq)
        return 0;
 }
 
-int
-acpi_register_irq (u32 gsi, u32 polarity, u32 trigger)
-{
-       if (has_8259 && gsi < 16)
-               return isa_irq_to_vector(gsi);
-
-       return iosapic_register_intr(gsi,
-                       (polarity == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
-                       (trigger == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
-}
-EXPORT_SYMBOL(acpi_register_irq);
-
 #endif /* CONFIG_ACPI_BOOT */
index 75a3aa6..933e4f1 100644 (file)
@@ -21,7 +21,7 @@
  * Jonathan Nicklin    <nicklin@missioncriticallinux.com>
  * Patrick O'Rourke    <orourke@missioncriticallinux.com>
  * 11/07/2000
- /
*/
 /*
  * Global (preserved) predicate usage on syscall entry/exit path:
  *
index c6e88e4..874bb10 100644 (file)
@@ -502,6 +502,7 @@ ENTRY(fsys_fallback_syscall)
        adds r17=-1024,r15
        movl r14=sys_call_table
        ;;
+       rsm psr.i
        shladd r18=r17,3,r14
        ;;
        ld8 r18=[r18]                           // load normal (heavy-weight) syscall entry-point
@@ -542,7 +543,7 @@ GLOBAL_ENTRY(fsys_bubble_down)
         * to synthesize.
         */
 #      define PSR_ONE_BITS             ((3 << IA64_PSR_CPL0_BIT) | (0x1 << IA64_PSR_RI_BIT) \
-                                        | IA64_PSR_BN)
+                                        | IA64_PSR_BN | IA64_PSR_I)
 
        invala
        movl r8=PSR_ONE_BITS
index 36e8a24..a4dba36 100644 (file)
@@ -91,16 +91,18 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
        cmp.geu p6,p7=r19,r17                   // (syscall > 0 && syscall < 1024+NR_syscalls)?
        ;;
 (p6)   ld8 r18=[r18]
-       mov r29=psr                             // read psr (12 cyc load latency)
+       mov r21=ar.fpsr
        add r14=-8,r14                          // r14 <- addr of fsys_bubble_down entry
        ;;
 (p6)   mov b7=r18
 (p6)   tbit.z p8,p0=r18,0
 (p8)   br.dptk.many b7
 
+(p6)   rsm psr.i
        mov r27=ar.rsc
-       mov r21=ar.fpsr
        mov r26=ar.pfs
+       ;;
+       mov r29=psr                             // read psr (12 cyc load latency)
 /*
  * brl.cond doesn't work as intended because the linker would convert this branch
  * into a branch to a PLT.  Perhaps there will be a way to avoid this with some
index 6f74b9a..0a5eb48 100644 (file)
@@ -815,6 +815,42 @@ GLOBAL_ENTRY(ia64_delay_loop)
        br.ret.sptk.many rp
 END(ia64_delay_loop)
 
+/*
+ * Return a CPU-local timestamp in nano-seconds.  This timestamp is
+ * NOT synchronized across CPUs its return value must never be
+ * compared against the values returned on another CPU.  The usage in
+ * kernel/sched.c ensures that.
+ *
+ * The return-value of sched_clock() is NOT supposed to wrap-around.
+ * If it did, it would cause some scheduling hiccups (at the worst).
+ * Fortunately, with a 64-bit cycle-counter ticking at 100GHz, even
+ * that would happen only once every 5+ years.
+ *
+ * The code below basically calculates:
+ *
+ *   (ia64_get_itc() * local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT
+ *
+ * except that the multiplication and the shift are done with 128-bit
+ * intermediate precision so that we can produce a full 64-bit result.
+ */
+GLOBAL_ENTRY(sched_clock)
+       addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
+       mov.m r9=ar.itc         // fetch cycle-counter                          (35 cyc)
+       ;;
+       ldf8 f8=[r8]
+       ;;
+       setf.sig f9=r9          // certain to stall, so issue it _after_ ldf8...
+       ;;
+       xmpy.lu f10=f9,f8       // calculate low 64 bits of 128-bit product     (4 cyc)
+       xmpy.hu f11=f9,f8       // calculate high 64 bits of 128-bit product
+       ;;
+       getf.sig r8=f10         //                                              (5 cyc)
+       getf.sig r9=f11
+       ;;
+       shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT
+       br.ret.sptk.many rp
+END(sched_clock)
+
 GLOBAL_ENTRY(start_kernel_thread)
        .prologue
        .save rp, r0                            // this is the end of the call-chain
index 46cf054..b69c397 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/init_task.h>
+#include <linux/mqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
index 33044bc..1e1f05c 100644 (file)
 #endif
 
 static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
-cpumask_t      __cacheline_aligned pending_irq_cpumask[NR_IRQS];
+extern cpumask_t       __cacheline_aligned pending_irq_cpumask[NR_IRQS];
 
 /* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */
 
@@ -483,7 +483,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
 
        index = find_iosapic(gsi);
        if (index < 0) {
-               printk(KERN_WARNING "%s: No IOSAPIC for GSI 0x%x\n", __FUNCTION__, gsi);
+               printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi);
                return;
        }
 
@@ -512,6 +512,42 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
        }
 }
 
+static unsigned int
+get_target_cpu (void)
+{
+#ifdef CONFIG_SMP
+       static int cpu = -1;
+
+       /*
+        * If the platform supports redirection via XTP, let it
+        * distribute interrupts.
+        */
+       if (smp_int_redirect & SMP_IRQ_REDIRECTION)
+               return hard_smp_processor_id();
+
+       /*
+        * Some interrupts (ACPI SCI, for instance) are registered
+        * before the BSP is marked as online.
+        */
+       if (!cpu_online(smp_processor_id()))
+               return hard_smp_processor_id();
+
+       /*
+        * Otherwise, round-robin interrupt vectors across all the
+        * processors.  (It'd be nice if we could be smarter in the
+        * case of NUMA.)
+        */
+       do {
+               if (++cpu >= NR_CPUS)
+                       cpu = 0;
+       } while (!cpu_online(cpu));
+
+       return cpu_physical_id(cpu);
+#else
+       return hard_smp_processor_id();
+#endif
+}
+
 /*
  * ACPI can describe IOSAPIC interrupts via static tables and namespace
  * methods.  This provides an interface to register those interrupts and
@@ -522,21 +558,35 @@ iosapic_register_intr (unsigned int gsi,
                       unsigned long polarity, unsigned long trigger)
 {
        int vector;
-       unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
+       unsigned int dest;
+       unsigned long flags;
 
-       vector = gsi_to_vector(gsi);
-       if (vector < 0)
-               vector = assign_irq_vector(AUTO_ASSIGN);
+       /*
+        * If this GSI has already been registered (i.e., it's a
+        * shared interrupt, or we lost a race to register it),
+        * don't touch the RTE.
+        */
+       spin_lock_irqsave(&iosapic_lock, flags);
+       {
+               vector = gsi_to_vector(gsi);
+               if (vector > 0) {
+                       spin_unlock_irqrestore(&iosapic_lock, flags);
+                       return vector;
+               }
 
-       register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
-                     polarity, trigger);
+               vector = assign_irq_vector(AUTO_ASSIGN);
+               dest = get_target_cpu();
+               register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
+                       polarity, trigger);
+       }
+       spin_unlock_irqrestore(&iosapic_lock, flags);
 
-       printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
-              gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
-              (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
+       printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n",
+              gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
+              (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
+              cpu_logical_id(dest), dest, vector);
 
-       /* program the IOSAPIC routing table */
-       set_rte(vector, dest, 0);
+       set_rte(vector, dest, 1);
        return vector;
 }
 
@@ -549,8 +599,9 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
                                int iosapic_vector, u16 eid, u16 id,
                                unsigned long polarity, unsigned long trigger)
 {
+       static const char * const name[] = {"unknown", "PMI", "INIT", "CPEI"};
        unsigned char delivery;
-       int vector;
+       int vector, mask = 0;
        unsigned int dest = ((id << 8) | eid) & 0xffff;
 
        switch (int_type) {
@@ -570,21 +621,22 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
              case ACPI_INTERRUPT_CPEI:
                vector = IA64_CPE_VECTOR;
                delivery = IOSAPIC_LOWEST_PRIORITY;
+               mask = 1;
                break;
              default:
-               printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type\n");
+               printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type 0x%x\n", int_type);
                return -1;
        }
 
-       register_intr(gsi, vector, delivery, polarity,
-                     trigger);
+       register_intr(gsi, vector, delivery, polarity, trigger);
 
-       printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
-              int_type, gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
-              (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
+       printk(KERN_INFO "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n",
+              int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown",
+              int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
+              (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
+              cpu_logical_id(dest), dest, vector);
 
-       /* program the IOSAPIC routing table */
-       set_rte(vector, dest, 0);
+       set_rte(vector, dest, mask);
        return vector;
 }
 
@@ -599,18 +651,18 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
                          unsigned long trigger)
 {
        int vector;
-       unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
+       unsigned int dest = hard_smp_processor_id();
 
        vector = isa_irq_to_vector(isa_irq);
 
        register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
 
-       DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n",
-           isa_irq, gsi, polarity == IOSAPIC_POL_HIGH ? "high" : "low",
-           trigger == IOSAPIC_EDGE ? "edge" : "level", dest, vector);
+       DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n",
+           isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level",
+           polarity == IOSAPIC_POL_HIGH ? "high" : "low",
+           cpu_logical_id(dest), dest, vector);
 
-       /* program the IOSAPIC routing table */
-       set_rte(vector, dest, 0);
+       set_rte(vector, dest, 1);
 }
 
 void __init
@@ -665,104 +717,3 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
                        iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
        }
 }
-
-void
-iosapic_enable_intr (unsigned int vector)
-{
-       unsigned int dest;
-       irq_desc_t *desc;
-
-       /*
-        * In the case of a shared interrupt, do not re-route the vector, and
-        * especially do not mask a running interrupt (startup will not get
-        * called for a shared interrupt).
-        */
-       desc = irq_descp(vector);
-       if (desc->action)
-               return;
-
-#ifdef CONFIG_SMP
-       /*
-        * For platforms that do not support interrupt redirect via the XTP interface, we
-        * can round-robin the PCI device interrupts to the processors
-        */
-       if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) {
-               static int cpu_index = -1;
-
-               do
-                       if (++cpu_index >= NR_CPUS)
-                               cpu_index = 0;
-               while (!cpu_online(cpu_index));
-
-               dest = cpu_physical_id(cpu_index) & 0xffff;
-       } else {
-               /*
-                * Direct the interrupt vector to the current cpu, platform redirection
-                * will distribute them.
-                */
-               dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
-       }
-#else
-       /* direct the interrupt vector to the running cpu id */
-       dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
-#endif
-       set_rte(vector, dest, 1);
-
-       printk(KERN_INFO "IOSAPIC: vector %d -> CPU 0x%04x, enabled\n",
-              vector, dest);
-}
-
-#ifdef CONFIG_ACPI_PCI
-
-void __init
-iosapic_parse_prt (void)
-{
-       struct acpi_prt_entry *entry;
-       struct list_head *node;
-       unsigned int gsi;
-       int vector;
-       char pci_id[16];
-       struct hw_interrupt_type *irq_type = &irq_type_iosapic_level;
-       irq_desc_t *idesc;
-
-       list_for_each(node, &acpi_prt.entries) {
-               entry = list_entry(node, struct acpi_prt_entry, node);
-
-               /* We're only interested in static (non-link) entries.  */
-               if (entry->link.handle)
-                       continue;
-
-               gsi = entry->link.index;
-
-               vector = gsi_to_vector(gsi);
-               if (vector < 0) {
-                       if (find_iosapic(gsi) < 0)
-                               continue;
-
-                       /* allocate a vector for this interrupt line */
-                       if (pcat_compat && (gsi < 16))
-                               vector = isa_irq_to_vector(gsi);
-                       else
-                               /* new GSI; allocate a vector for it */
-                               vector = assign_irq_vector(AUTO_ASSIGN);
-
-                       register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
-                                     IOSAPIC_LEVEL);
-               }
-               entry->irq = vector;
-               snprintf(pci_id, sizeof(pci_id), "%02x:%02x:%02x[%c]",
-                        entry->id.segment, entry->id.bus, entry->id.device, 'A' + entry->pin);
-
-               /*
-                * If vector was previously initialized to a different
-                * handler, re-initialize.
-                */
-               idesc = irq_descp(vector);
-               if (idesc->handler != irq_type)
-                       register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
-                                     IOSAPIC_LEVEL);
-
-       }
-}
-
-#endif /* CONFIG_ACPI */
index 37c1788..42056fb 100644 (file)
@@ -56,7 +56,6 @@
 #include <asm/delay.h>
 #include <asm/irq.h>
 
-extern cpumask_t    __cacheline_aligned pending_irq_cpumask[NR_IRQS];
 
 /*
  * Linux has a controller-independent x86 interrupt architecture.
@@ -85,6 +84,11 @@ irq_desc_t _irq_desc[NR_IRQS] __cacheline_aligned = {
        }
 };
 
+/*
+ * This is updated when the user sets irq affinity via /proc
+ */
+cpumask_t    __cacheline_aligned pending_irq_cpumask[NR_IRQS];
+
 #ifdef CONFIG_IA64_GENERIC
 irq_desc_t * __ia64_irq_desc (unsigned int irq)
 {
index 26eb180..aa2cb4f 100644 (file)
@@ -330,18 +330,8 @@ setup_arch (char **cmdline_p)
                setup_serial_hcdp(efi.hcdp);
        }
 #endif
-       /*
-        * Without HCDP, we won't discover any serial ports until the serial driver looks
-        * in the ACPI namespace.  If ACPI claims there are some legacy devices, register
-        * the legacy COM ports so serial console works earlier.  This is slightly dangerous
-        * because we don't *really* know whether there's anything there, but we hope that
-        * all new boxes will implement HCDP.
-        */
-       {
-               extern unsigned char acpi_legacy_devices;
-               if (!efi.hcdp && acpi_legacy_devices)
-                       setup_serial_legacy();
-       }
+       if (!efi.hcdp)
+               setup_serial_legacy();
 #endif
 
 #ifdef CONFIG_VT
@@ -635,6 +625,9 @@ cpu_init (void)
        ia32_cpu_init();
 #endif
 
+       /* Clear ITC to eliminiate sched_clock() overflows in human time.  */
+       ia64_set_itc(0);
+
        /* disable all local interrupt sources: */
        ia64_set_itv(1 << 16);
        ia64_set_lrr0(1 << 16);
index 8058fb5..8cef119 100644 (file)
@@ -202,7 +202,6 @@ ia64_sync_itc (unsigned int master)
 {
        long i, delta, adj, adjust_latency = 0, done = 0;
        unsigned long flags, rt, master_time_stamp, bound;
-       extern void ia64_cpu_local_tick (void);
 #if DEBUG_ITC_SYNC
        struct {
                long rt;        /* roundtrip time */
@@ -525,7 +524,7 @@ build_cpu_to_node_map (void)
 #else
 #              error Fixme: Dunno how to build CPU-to-node map.
 #endif
-               cpu_to_node_map[cpu] = node;
+               cpu_to_node_map[cpu] = (node >= 0) ? node : 0;
                if (node >= 0)
                        cpu_set(cpu, node_to_cpu_mask[node]);
        }
index 3ebc74a..e33bcb6 100644 (file)
@@ -45,14 +45,6 @@ EXPORT_SYMBOL(last_cli_ip);
 
 #endif
 
-unsigned long long
-sched_clock (void)
-{
-       unsigned long offset = ia64_get_itc();
-
-       return (offset * local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT;
-}
-
 static void
 itc_reset (void)
 {
index 5c45718..5791221 100644 (file)
@@ -195,11 +195,10 @@ SECTIONS
   .data : AT(ADDR(.data) - LOAD_OFFSET)
        { *(.data) *(.data1) *(.gnu.linkonce.d*) CONSTRUCTORS }
 
-  . = ALIGN(16);
-  __gp = . + 0x200000; /* gp must be 16-byte aligned for exc. table */
-
+  . = ALIGN(16);       /* gp must be 16-byte aligned for exc. table */
   .got : AT(ADDR(.got) - LOAD_OFFSET)
        { *(.got.plt) *(.got) }
+  __gp = ADDR(.got) + 0x200000;
   /* We want the small data sections together, so single-instruction offsets
      can access them all, and initialized data all before uninitialized, so
      we can shorten the on-disk segment size.  */
index 218de3e..1902c3c 100644 (file)
@@ -6,7 +6,7 @@ obj-y := io.o
 
 lib-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o                 \
        __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o                   \
-       checksum.o clear_page.o csum_partial_copy.o copy_page.o         \
+       bitop.o checksum.o clear_page.o csum_partial_copy.o copy_page.o \
        clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o   \
        flush.o ip_fast_csum.o do_csum.o                                \
        memset.o strlen.o swiotlb.o
index 6626740..82204f1 100644 (file)
@@ -134,10 +134,18 @@ static struct pci_ops pci_root_ops = {
 static int __init
 pci_acpi_init (void)
 {
-       if (!acpi_pci_irq_init())
-               printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
-       else
-               printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n");
+       struct pci_dev *dev = NULL;
+
+       printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
+
+       /*
+        * PCI IRQ routing is set up by pci_enable_device(), but we
+        * also do it here in case there are still broken drivers that
+        * don't use pci_enable_device().
+        */
+       while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+               acpi_pci_irq_enable(dev);
+
        return 0;
 }
 
@@ -323,8 +331,10 @@ pcibios_fixup_device_resources (struct pci_dev *dev, struct pci_bus *bus)
        struct pci_controller *controller = PCI_CONTROLLER(dev);
        struct pci_window *window;
        int i, j;
+       int limit = (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) ? \
+               PCI_ROM_RESOURCE : PCI_NUM_RESOURCES;
 
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+       for (i = 0; i < limit; i++) {
                if (!dev->resource[i].start)
                        continue;
 
index df17cc0..10ee752 100644 (file)
@@ -71,6 +71,6 @@ sn_mmiob (void)
 {
        while ((((volatile unsigned long) (*pda->pio_write_status_addr)) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) != 
                                SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK)
-               udelay(1);
+               cpu_relax();
 }
 EXPORT_SYMBOL(sn_mmiob);
index f8147fe..a4d7c56 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -1615,6 +1615,46 @@ pcibr_piomap_probe(pcibr_piomap_t piomap, off_t offset, int len, void *valp)
                                piomap->bp_kvaddr + offset, len, valp);
 }
 
+static uint64_t
+pcibr_disable_mst_timeout(pcibr_soft_t pcibr_soft)
+{
+    uint64_t           old_enable;
+    uint64_t           new_enable;
+    uint64_t           intr_bits;
+
+    intr_bits = PIC_ISR_PCI_MST_TIMEOUT
+               | PIC_ISR_PCIX_MTOUT | PIC_ISR_PCIX_SPLIT_EMSG;
+    old_enable = pcireg_intr_enable_get(pcibr_soft);
+    pcireg_intr_enable_bit_clr(pcibr_soft, intr_bits);
+    new_enable = pcireg_intr_enable_get(pcibr_soft);
+
+    if (old_enable == new_enable) {
+       return 0;               /* was already disabled */
+    } else {
+       return 1;
+    }
+}
+
+static int
+pcibr_enable_mst_timeout(pcibr_soft_t pcibr_soft)
+{
+    uint64_t           old_enable;
+    uint64_t           new_enable;
+    uint64_t           intr_bits;
+    
+    intr_bits = PIC_ISR_PCI_MST_TIMEOUT
+               | PIC_ISR_PCIX_MTOUT | PIC_ISR_PCIX_SPLIT_EMSG;
+    old_enable = pcireg_intr_enable_get(pcibr_soft);
+    pcireg_intr_enable_bit_set(pcibr_soft, intr_bits);
+    new_enable = pcireg_intr_enable_get(pcibr_soft);
+
+    if (old_enable == new_enable) {
+       return 0;               /* was alread enabled */
+    } else {
+       return 1;
+    }
+}
+
 /*
  * pcibr_probe_slot: read a config space word
  * while trapping any errors; return zero if
@@ -1628,7 +1668,7 @@ pcibr_probe_work(pcibr_soft_t pcibr_soft,
                 int len,
                 void *valp)
 {
-    int                        rv;
+    int                        rv, changed;
 
     /*
      * Sanity checks ...
@@ -1642,15 +1682,19 @@ pcibr_probe_work(pcibr_soft_t pcibr_soft,
        return -1;                              /* invalid alignment */
     }
 
+    changed = pcibr_disable_mst_timeout(pcibr_soft);
+
     rv = snia_badaddr_val((void *)addr, len, valp);
 
     /* Clear the int_view register incase it was set */
     pcireg_intr_reset_set(pcibr_soft, BRIDGE_IRR_MULTI_CLR);
 
+    if (changed) {
+       pcibr_enable_mst_timeout(pcibr_soft);
+    }
     return (rv ? 1 : 0);       /* return 1 for snia_badaddr_val error, 0 if ok */
 }
 
-
 void
 pcibr_device_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot)
 {
index 552bd2f..b426ab5 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/a.out.h>
 #include <linux/reboot.h>
 #include <linux/init_task.h>
+#include <linux/mqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
index 51ee0a0..3897043 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/init_task.h>
 #include <linux/fs.h>
+#include <linux/mqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
index 945606b..aeda7f5 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/sched.h>
 #include <linux/init_task.h>
 #include <linux/fs.h>
+#include <linux/mqueue.h>
 
 #include <asm/thread_info.h>
 #include <asm/uaccess.h>
index ed4fb58..c71b946 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/init_task.h>
+#include <linux/mqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
index 226214c..d9df49c 100644 (file)
@@ -158,12 +158,21 @@ static int fcc_enet_set_mac_address(struct net_device *dev, void *addr);
 #define PA1_DIRA0      (PA1_RXDAT | PA1_CRS | PA1_COL | PA1_RXER | PA1_RXDV)
 #define PA1_DIRA1      (PA1_TXDAT | PA1_TXEN | PA1_TXER)
 
+#ifdef CONFIG_SBC82xx
+/* rx is clk9, tx is clk10
+ */
+#define PC_F1RXCLK     ((uint)0x00000100)
+#define PC_F1TXCLK     ((uint)0x00000200)
+#define CMX1_CLK_ROUTE ((uint)0x25000000)
+#define CMX1_CLK_MASK  ((uint)0xff000000)
+#else
 /* CLK12 is receive, CLK11 is transmit.  These are board specific.
 */
 #define PC_F1RXCLK     ((uint)0x00000800)
 #define PC_F1TXCLK     ((uint)0x00000400)
 #define CMX1_CLK_ROUTE ((uint)0x3e000000)
 #define CMX1_CLK_MASK  ((uint)0xff000000)
+#endif /* !CONFIG_SBC82xx */
 
 /* I/O Pin assignment for FCC2.  I don't yet know the best way to do this,
  * but there is little variation among the choices.
@@ -288,6 +297,8 @@ struct fcc_enet_private {
        ushort  skb_cur;
        ushort  skb_dirty;
 
+       atomic_t n_pkts;  /* Number of packets in tx ring */
+
        /* CPM dual port RAM relative addresses.
        */
        cbd_t   *rx_bd_base;            /* Address of Rx and Tx buffers. */
@@ -347,6 +358,7 @@ fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct fcc_enet_private *cep = (struct fcc_enet_private *)dev->priv;
        volatile cbd_t  *bdp;
+       int idx;
 
        if (!cep->link) {
                /* Link is down or autonegotiation is in progress. */
@@ -379,13 +391,24 @@ fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        bdp->cbd_datlen = skb->len;
        bdp->cbd_bufaddr = __pa(skb->data);
 
+       spin_lock_irq(&cep->lock);
+
        /* Save skb pointer. */
-       cep->tx_skbuff[cep->skb_cur] = skb;
+       idx = cep->skb_cur & TX_RING_MOD_MASK;
+       if (cep->tx_skbuff[idx]) {
+               /* This should never happen (any more).
+                  Leave the sanity check in for now... */
+               printk(KERN_ERR "EEP. cep->tx_skbuff[%d] is %p not NULL in %s\n", 
+                      idx, cep->tx_skbuff[idx], __func__);
+               printk(KERN_ERR "Expect to lose %d bytes of sock space", 
+                      cep->tx_skbuff[idx]->truesize);
+       }
+       cep->tx_skbuff[idx] = skb;
 
        cep->stats.tx_bytes += skb->len;
-       cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK;
+       cep->skb_cur++;
 
-       spin_lock_irq(&cep->lock);
+       atomic_inc(&cep->n_pkts);
 
        /* Send it on its way.  Tell CPM its ready, interrupt when done,
         * its the last BD of the frame, and to put the CRC on the end.
@@ -404,9 +427,13 @@ fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        else
                bdp++;
 
-       if (bdp->cbd_sc & BD_ENET_TX_READY) {
-               netif_stop_queue(dev);
+
+       /* If the tx_ring is full, stop the queue */
+       if (atomic_read(&cep->n_pkts) >= (TX_RING_SIZE-1)) {
+         if (!netif_queue_stopped(dev)) {
+               netif_stop_queue(dev);    
                cep->tx_full = 1;
+         }
        }
 
        cep->cur_tx = (cbd_t *)bdp;
@@ -460,6 +487,7 @@ fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
        volatile cbd_t  *bdp;
        ushort  int_events;
        int     must_restart;
+       int idx;
 
        cep = (struct fcc_enet_private *)dev->priv;
 
@@ -522,8 +550,12 @@ fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
                        cep->stats.collisions++;
 
                /* Free the sk buffer associated with this last transmit. */
-               dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]);
-               cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK;
+               idx = cep->skb_dirty & TX_RING_MOD_MASK;
+               dev_kfree_skb_irq(cep->tx_skbuff[idx]);
+               cep->tx_skbuff[idx] = NULL;
+               cep->skb_dirty++;
+
+               atomic_dec(&cep->n_pkts);
 
                /* Update pointer to next buffer descriptor to be transmitted. */
                if (bdp->cbd_sc & BD_ENET_TX_WRAP)
@@ -1594,11 +1626,21 @@ init_fcc_param(fcc_info_t *fip, struct net_device *dev,
         */
        eap = (unsigned char *)&(ep->fen_paddrh);
        for (i=5; i>=0; i--) {
+#ifdef CONFIG_SBC82xx
+               if (i == 5) {
+                       /* bd->bi_enetaddr holds the SCC0 address; the FCC
+                          devices count up from there */
+                       dev->dev_addr[i] = bd->bi_enetaddr[i] & ~3;
+                       dev->dev_addr[i] += 1 + fip->fc_fccnum;
+                       *eap++ = dev->dev_addr[i];
+               }
+#else
                if (i == 3) {
                        dev->dev_addr[i] = bd->bi_enetaddr[i];
                        dev->dev_addr[i] |= (1 << (7 - fip->fc_fccnum));
                        *eap++ = dev->dev_addr[i];
                }
+#endif
                else {
                        *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i];
                }
@@ -1683,6 +1725,7 @@ init_fcc_param(fcc_info_t *fip, struct net_device *dev,
        while (cp->cp_cpcr & CPM_CR_FLG);
 
        cep->skb_cur = cep->skb_dirty = 0;
+       atomic_set(&cep->n_pkts, 0);
 }
 
 /* Let 'er rip.
index 3e9f887..23c0322 100644 (file)
@@ -161,7 +161,7 @@ static struct serial_state rs_table[] = {
 #ifndef CONFIG_SCC1_ENET
        { 0,     0, PROFF_SCC1, SIU_INT_SCC1,   0, SCC_NUM_BASE},    /* SCC1 ttyS2 */
 #endif
-#ifndef CONFIG_SCC2_ENET
+#if !defined(CONFIG_SBC82xx) && !defined(CONFIG_SCC2_ENET)
        { 0,     0, PROFF_SCC2, SIU_INT_SCC2,   0, SCC_NUM_BASE + 1},    /* SCC2 ttyS3 */
 #endif
 };
@@ -475,7 +475,7 @@ static _INLINE_ void receive_chars(ser_info_t *info, struct pt_regs *regs)
                        if (break_pressed && info->line == sercons.index) {
                                if (ch != 0 && time_before(jiffies,
                                                        break_pressed + HZ*5)) {
-                                       handle_sysrq(ch, regs, NULL, NULL);
+                                       handle_sysrq(ch, regs, NULL);
                                        break_pressed = 0;
                                        goto ignore_char;
                                } else
index faeb15e..2b49740 100644 (file)
@@ -72,8 +72,21 @@ config POWER4
 config 8xx
        bool "8xx"
 
+config E500
+       bool "e500"
+
 endchoice
 
+config BOOKE
+       bool
+       depends on E500
+       default y
+
+config FSL_BOOKE
+       bool
+       depends on E500
+       default y
+
 config PTE_64BIT
        bool
        depends on 44x
@@ -96,6 +109,21 @@ config ALTIVEC
 
          If in doubt, say Y here.
 
+config SPE
+       bool "SPE Support"
+       depends on E500
+       ---help---
+         This option enables kernel support for the Signal Processing
+         Extensions (SPE) to the PowerPC processor. The kernel currently
+         supports saving and restoring SPE registers, and turning on the
+         'spe enable' bit so user processes can execute SPE instructions.
+
+         This option is only usefully if you have a processor that supports
+         SPE (e500, otherwise known as 85xx series), but does not have any
+         affect on a non-spe cpu (it does, however add code to the kernel).
+
+         If in doubt, say Y here.
+
 config TAU
        bool "Thermal Management Support"
        depends on 6xx && !8260
@@ -142,7 +170,7 @@ config TAU_AVERAGE
 
 config MATH_EMULATION
        bool "Math emulation"
-       depends on 4xx || 8xx
+       depends on 4xx || 8xx || E500
        ---help---
          Some PowerPC chips designed for embedded applications do not have
          a floating-point unit and therefore do not implement the
@@ -198,6 +226,7 @@ config PPC601_SYNC_FIX
          If in doubt, say Y here.
 
 source arch/ppc/platforms/4xx/Kconfig
+source arch/ppc/platforms/85xx/Kconfig
 
 config PPC64BRIDGE
        bool
@@ -542,6 +571,15 @@ config EST8260
          <http://www.windriver.com/>, but the EST8260 cannot be found on it
          and has probably been discontinued or rebadged.
 
+config SBC82xx
+       bool "SBC82xx"
+       ---help---
+         SBC PowerQUICC II, single-board computer with MPC82xx CPU
+         Manufacturer: Wind River Systems, Inc.
+         Date of Release: May 2003
+         End of Life: -
+         URL: <http://www.windriver.com/>
+
 config SBS8260
        bool "SBS8260"
 
@@ -575,7 +613,7 @@ config EMBEDDEDBOOT
 config 8260
        bool "MPC8260 CPM Support" if WILLOW
        depends on 6xx
-       default y if TQM8260 || RPXSUPER || EST8260 || SBS8260
+       default y if TQM8260 || RPXSUPER || EST8260 || SBS8260 || SBC82xx
        help
          The MPC8260 CPM (Communications Processor Module) is a typical
          embedded CPU made by Motorola.  Selecting this option means that
@@ -965,8 +1003,8 @@ config MCA
        bool
 
 config PCI
-       bool "PCI support" if 40x || 8260
-       default y if !40x && !8260 && !8xx && !APUS
+       bool "PCI support" if 40x || 8260 || 85xx
+       default y if !40x && !8260 && !8xx && !APUS && !85xx
        default PCI_PERMEDIA if !4xx && !8260 && !8xx && APUS
        default PCI_QSPAN if !4xx && !8260 && 8xx
        help
@@ -1264,7 +1302,7 @@ config SERIAL_TEXT_DEBUG
 
 config PPC_OCP
        bool
-       depends on IBM_OCP
+       depends on IBM_OCP || FSL_OCP
        default y
 
 endmenu
index 36d94af..cf7a3a4 100644 (file)
@@ -17,19 +17,24 @@ LDFLAGS_vmlinux     := -Ttext $(KERNELLOAD) -Bstatic
 CPPFLAGS       += -Iarch/$(ARCH)
 AFLAGS         += -Iarch/$(ARCH)
 cflags-y       += -Iarch/$(ARCH) -msoft-float -pipe \
-               -ffixed-r2 -Wno-uninitialized -mmultiple -mstring
+               -ffixed-r2 -Wno-uninitialized -mmultiple
 CPP            = $(CC) -E $(CFLAGS)
 
+ifndef CONFIG_E500
+cflags-y       += -mstring
+endif
+
 cflags-$(CONFIG_4xx)           += -Wa,-m405
+cflags-$(CONFIG_E500)          += -Wa,-me500
 cflags-$(CONFIG_PPC64BRIDGE)   += -Wa,-mppc64bridge
 
 CFLAGS += $(cflags-y)
 
-
 head-y                         := arch/ppc/kernel/head.o
 head-$(CONFIG_8xx)             := arch/ppc/kernel/head_8xx.o
 head-$(CONFIG_4xx)             := arch/ppc/kernel/head_4xx.o
 head-$(CONFIG_44x)             := arch/ppc/kernel/head_44x.o
+head-$(CONFIG_E500)            := arch/ppc/kernel/head_e500.o
 
 head-$(CONFIG_6xx)             += arch/ppc/kernel/idle_6xx.o
 head-$(CONFIG_POWER4)          += arch/ppc/kernel/idle_power4.o
@@ -37,6 +42,7 @@ head-$(CONFIG_POWER4)         += arch/ppc/kernel/idle_power4.o
 core-y                         += arch/ppc/kernel/ arch/ppc/platforms/ \
                                   arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/
 core-$(CONFIG_4xx)             += arch/ppc/platforms/4xx/
+core-$(CONFIG_85xx)            += arch/ppc/platforms/85xx/
 core-$(CONFIG_MATH_EMULATION)  += arch/ppc/math-emu/
 core-$(CONFIG_XMON)            += arch/ppc/xmon/
 core-$(CONFIG_APUS)            += arch/ppc/amiga/
@@ -87,7 +93,7 @@ include/asm-$(ARCH)/offsets.h: arch/$(ARCH)/kernel/asm-offsets.s
 
 ifdef CONFIG_6xx
 # Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later
-NEW_AS := $(shell echo dssall | $(AS) -o /dev/null >/dev/null 2>&1 ; echo $$?)
+NEW_AS := $(shell echo dssall | $(AS) -many -o /dev/null >/dev/null 2>&1 ; echo $$?)
 GOODVER        := 2.12.1
 else
 NEW_AS := 0
@@ -95,7 +101,7 @@ endif
 
 ifneq ($(NEW_AS),0)
 checkbin:
-       @echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build'
+       @echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '
        @echo 'correctly with old versions of binutils.'
        @echo '*** Please upgrade your binutils to ${GOODVER} or newer'
        @false
index 8f40dd1..4dc12e6 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/types.h>
 #include <linux/config.h>
 #include <linux/string.h>
+#include <asm/reg.h>
 #ifdef CONFIG_8xx
 #include <asm/mpc8xx.h>
 #endif
@@ -402,14 +403,18 @@ embed_config(bd_t **bdp)
 
 #ifdef CONFIG_8260
 /* Compute 8260 clock values if the rom doesn't provide them.
- * We can't compute the internal core frequency (I don't know how to
- * do that).
  */
+static unsigned char bus2core_8260[] = {
+/*      0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f */
+       3,  2,  2,  2,  4,  4,  5,  9,  6, 11,  8, 10,  3, 12,  7,  2,
+       6,  5, 13,  2, 14,  4, 15,  2,  3, 11,  8, 10, 16, 12,  7,  2,
+};
+
 static void
 clk_8260(bd_t *bd)
 {
        uint    scmr, vco_out, clkin;
-       uint    plldf, pllmf, busdf, brgdf, cpmdf;
+       uint    plldf, pllmf, corecnf;
        volatile immap_t        *ip;
 
        ip = (immap_t *)IMAP_ADDR;
@@ -423,8 +428,7 @@ clk_8260(bd_t *bd)
        */
        plldf = (scmr >> 12) & 1;
        pllmf = scmr & 0xfff;
-       cpmdf = (scmr >> 16) & 0x0f;
-       busdf = (scmr >> 20) & 0x0f;
+       corecnf = (scmr >> 24) &0x1f;
 
        /* This is arithmetic from the 8260 manual.
        */
@@ -433,6 +437,7 @@ clk_8260(bd_t *bd)
        bd->bi_vco = vco_out;           /* Save for later */
 
        bd->bi_cpmfreq = vco_out / 2;   /* CPM Freq, in MHz */
+       bd->bi_intfreq = bd->bi_busfreq * bus2core_8260[corecnf] / 2;
 
        /* Set Baud rate divisor.  The power up default is divide by 16,
         * but we set it again here in case it was changed.
@@ -440,8 +445,79 @@ clk_8260(bd_t *bd)
        ip->im_clkrst.car_sccr = 1;     /* DIV 16 BRG */
        bd->bi_brgfreq = vco_out / 16;
 }
+
+static unsigned char bus2core_8280[] = {
+/*      0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f */
+       3,  2,  2,  2,  4,  4,  5,  9,  6, 11,  8, 10,  3, 12,  7,  2,
+       6,  5, 13,  2, 14,  2, 15,  2,  3,  2,  2,  2, 16,  2,  2,  2,
+};
+
+static void
+clk_8280(bd_t *bd)
+{
+       uint    scmr, main_clk, clkin;
+       uint    pllmf, corecnf;
+       volatile immap_t        *ip;
+
+       ip = (immap_t *)IMAP_ADDR;
+       scmr = ip->im_clkrst.car_scmr;
+
+       /* The clkin is always bus frequency.
+       */
+       clkin = bd->bi_busfreq;
+
+       /* Collect the bits from the scmr.
+       */
+       pllmf = scmr & 0xf;
+       corecnf = (scmr >> 24) & 0x1f;
+
+       /* This is arithmetic from the 8280 manual.
+       */
+       main_clk = clkin * (pllmf + 1);
+
+       bd->bi_cpmfreq = main_clk / 2;  /* CPM Freq, in MHz */
+       bd->bi_intfreq = bd->bi_busfreq * bus2core_8280[corecnf] / 2;
+
+       /* Set Baud rate divisor.  The power up default is divide by 16,
+        * but we set it again here in case it was changed.
+        */
+       ip->im_clkrst.car_sccr = (ip->im_clkrst.car_sccr & 0x3) | 0x1;
+       bd->bi_brgfreq = main_clk / 16;
+}
 #endif
 
+#ifdef CONFIG_SBC82xx
+void
+embed_config(bd_t **bdp)
+{
+       u_char  *cp;
+       int     i;
+       bd_t    *bd;
+       unsigned long pvr;
+
+       bd = *bdp;
+
+       bd = &bdinfo;
+       *bdp = bd;
+       bd->bi_baudrate = 9600;
+       bd->bi_memsize = 256 * 1024 * 1024;     /* just a guess */
+
+       cp = (void*)SBC82xx_MACADDR_NVRAM_SCC1;
+       memcpy(bd->bi_enetaddr, cp, 6);
+
+       /* can busfreq be calculated? */
+       pvr = mfspr(PVR);
+       if ((pvr & 0xffff0000) == 0x80820000) {
+               bd->bi_busfreq = 100000000;
+               clk_8280(bd);
+       } else {
+               bd->bi_busfreq = 66000000;
+               clk_8260(bd);
+       }
+
+}
+#endif /* SBC82xx */
+
 #if defined(CONFIG_EST8260) || defined(CONFIG_TQM8260)
 void
 embed_config(bd_t **bdp)
index 1934cd3..c3b03b6 100644 (file)
@@ -8,10 +8,14 @@ endif
 ifdef CONFIG_4xx
 EXTRA_AFLAGS           := -Wa,-m405
 endif
+ifdef CONFIG_E500
+EXTRA_AFLAGS           := -Wa,-me500
+endif
 
 extra-$(CONFIG_PPC_STD_MMU)    := head.o
 extra-$(CONFIG_40x)            := head_4xx.o
 extra-$(CONFIG_44x)            := head_44x.o
+extra-$(CONFIG_E500)           := head_e500.o
 extra-$(CONFIG_8xx)            := head_8xx.o
 extra-$(CONFIG_6xx)            += idle_6xx.o
 extra-$(CONFIG_POWER4)         += idle_power4.o
index 59a20f3..39f5198 100644 (file)
@@ -21,7 +21,7 @@ struct aligninfo {
        unsigned char flags;
 };
 
-#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
+#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) || defined(CONFIG_BOOKE)
 #define        OPCD(inst)      (((inst) & 0xFC000000) >> 26)
 #define        RS(inst)        (((inst) & 0x03E00000) >> 21)
 #define        RA(inst)        (((inst) & 0x001F0000) >> 16)
@@ -184,7 +184,7 @@ int
 fix_alignment(struct pt_regs *regs)
 {
        int instr, nb, flags;
-#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
+#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) || defined(CONFIG_BOOKE)
        int opcode, f1, f2, f3;
 #endif
        int i, t;
@@ -199,8 +199,8 @@ fix_alignment(struct pt_regs *regs)
 
        CHECK_FULL_REGS(regs);
 
-#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
-       /* The 4xx-family processors have no DSISR register,
+#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) || defined(CONFIG_BOOKE)
+       /* The 4xx-family & Book-E processors have no DSISR register,
         * so we emulate it.
         * The POWER4 has a DSISR register but doesn't set it on
         * an alignment fault.  -- paulus
@@ -250,7 +250,7 @@ fix_alignment(struct pt_regs *regs)
 
        flags = aligninfo[instr].flags;
 
-       /* For the 4xx-family processors, the 'dar' field of the
+       /* For the 4xx-family & Book-E processors, the 'dar' field of the
         * pt_regs structure is overloaded and is really from the DEAR.
         */
 
index e41af4f..1999a42 100644 (file)
@@ -44,7 +44,7 @@ main(void)
        DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
        DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
        DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
        DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
        DEFINE(PT_PTRACED, PT_PTRACED);
 #endif
@@ -54,6 +54,12 @@ main(void)
        DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
        DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
 #endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+       DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0]));
+       DEFINE(THREAD_ACC, offsetof(struct thread_struct, acc));
+       DEFINE(THREAD_SPEFSCR, offsetof(struct thread_struct, spefscr));
+       DEFINE(THREAD_USED_SPE, offsetof(struct thread_struct, used_spe));
+#endif /* CONFIG_SPE */
        /* Interrupt register frame */
        DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
        DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
index 45732ae..4f560f5 100644 (file)
@@ -34,7 +34,8 @@ extern void __setup_cpu_8xx(unsigned long offset, int cpu_nr, struct cpu_spec* s
 extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
 
 #define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \
-                    !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4))
+                    !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \
+                    !defined(CONFIG_BOOKE))
 
 /* This table only contains "desktop" CPUs, it need to be filled with embedded
  * ones as well...
@@ -350,6 +351,14 @@ struct cpu_spec    cpu_specs[] = {
        32, 32,
        __setup_cpu_603
     },
+    {  /* 8280 is a G2_LE (603e core, plus some) */
+       0x7fff0000, 0x00820000, "8280",
+       CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+       CPU_FTR_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
+       COMMON_PPC,
+       32, 32,
+       __setup_cpu_603
+    },
     {  /* default match, we assume split I/D cache & TB (non-601)... */
        0x00000000, 0x00000000, "(generic PPC)",
        CPU_FTR_COMMON |
@@ -553,6 +562,16 @@ struct cpu_spec    cpu_specs[] = {
         0, /*__setup_cpu_440 */
     },
 #endif /* CONFIG_44x */
+#ifdef CONFIG_E500
+    { /* e500 */
+        0xffff0000, 0x80200000, "e500",
+       /* xxx - galak: add CPU_FTR_CAN_DOZE */
+        CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+        PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+        32, 32,
+        0, /*__setup_cpu_e500 */
+    },
+#endif
 #if !CLASSIC_PPC
     {  /* default match */
        0x00000000, 0x00000000, "(generic PPC)",
index 8108917..4963b79 100644 (file)
@@ -36,7 +36,7 @@
 #undef SHOW_SYSCALLS_TASK
 
 /*
- * MSR_KERNEL is > 0x10000 on 4xx since it include MSR_CE.
+ * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE.
  */
 #if MSR_KERNEL >= 0x10000
 #define LOAD_MSR_KERNEL(r, x)  lis r,(x)@h; ori r,r,(x)@l
@@ -45,7 +45,7 @@
 #endif
 
 #ifdef CONFIG_BOOKE
-#define        COR     r8
+#define        COR     r8      /* Critical Offset Register (COR) */
 #define BOOKE_LOAD_COR lis COR,crit_save@ha
 #define BOOKE_REST_COR mfspr COR,SPRG2
 #define BOOKE_SAVE_COR mtspr SPRG2,COR
@@ -241,11 +241,11 @@ ret_from_syscall:
        andi.   r0,r9,(_TIF_SYSCALL_TRACE|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
        bne-    syscall_exit_work
 syscall_exit_cont:
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
        /* If the process has its own DBCR0 value, load it up */
        lwz     r0,PTRACE(r2)
        andi.   r0,r0,PT_PTRACED
-       bnel-   load_4xx_dbcr0
+       bnel-   load_dbcr0
 #endif
        stwcx.  r0,0,r1                 /* to clear the reservation */
        lwz     r4,_LINK(r1)
@@ -510,7 +510,12 @@ BEGIN_FTR_SECTION
        stw     r12,THREAD+THREAD_VRSAVE(r2)
 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 #endif /* CONFIG_ALTIVEC */
-       and.    r0,r0,r11       /* FP or altivec enabled? */
+#ifdef CONFIG_SPE
+       oris    r0,r0,MSR_SPE@h  /* Disable SPE */
+       mfspr   r12,SPRN_SPEFSCR /* save spefscr register value */
+       stw     r12,THREAD+THREAD_SPEFSCR(r2)
+#endif /* CONFIG_SPE */
+       and.    r0,r0,r11       /* FP or altivec or SPE enabled? */
        beq+    1f
        andc    r11,r11,r0
        MTMSRD(r11)
@@ -543,6 +548,10 @@ BEGIN_FTR_SECTION
        mtspr   SPRN_VRSAVE,r0          /* if G4, restore VRSAVE reg */
 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 #endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+       lwz     r0,THREAD+THREAD_SPEFSCR(r2)
+       mtspr   SPRN_SPEFSCR,r0         /* restore SPEFSCR reg */
+#endif /* CONFIG_SPE */
 
        lwz     r0,_CCR(r1)
        mtcrf   0xFF,r0
@@ -589,11 +598,11 @@ user_exc_return:          /* r10 contains MSR_KERNEL here */
        bne     do_work
 
 restore_user:
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
        /* Check whether this process has its own DBCR0 value */
        lwz     r0,PTRACE(r2)
        andi.   r0,r0,PT_PTRACED
-       bnel-   load_4xx_dbcr0
+       bnel-   load_dbcr0
 #endif
 
 #ifdef CONFIG_PREEMPT
@@ -645,7 +654,7 @@ restore:
        PPC405_ERR77(0,r1)
        stwcx.  r0,0,r1                 /* to clear the reservation */
 
-#ifndef CONFIG_4xx
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
        lwz     r9,_MSR(r1)
        andi.   r10,r9,MSR_RI           /* check if this exception occurred */
        beql    nonrecoverable          /* at a bad place (MSR:RI = 0) */
@@ -681,9 +690,9 @@ exc_exit_restart_end:
        SYNC
        RFI
 
-#else /* CONFIG_4xx */
+#else /* !(CONFIG_4xx || CONFIG_BOOKE) */
        /*
-        * This is a bit different on 4xx because 4xx doesn't have
+        * This is a bit different on 4xx/Book-E because it doesn't have
         * the RI bit in the MSR.
         * The TLB miss handler checks if we have interrupted
         * the exception exit path and restarts it if so
@@ -720,6 +729,9 @@ exc_exit_restart_end:
  * give the wrong answer).
  * We have to restore various SPRs that may have been in use at the
  * time of the critical interrupt.
+ *
+ * Note that SPRG6 is used for machine check on CONFIG_BOOKE parts and
+ * thus not saved in the critical handler
  */
        .globl  ret_from_crit_exc
 ret_from_crit_exc:
@@ -866,7 +878,7 @@ ret_from_mcheck_exc:
  * Load the DBCR0 value for a task that is being ptraced,
  * having first saved away the global DBCR0.
  */
-load_4xx_dbcr0:
+load_dbcr0:
        mfmsr   r0              /* first disable debug exceptions */
        rlwinm  r0,r0,0,~MSR_DE
        mtmsr   r0
@@ -885,7 +897,7 @@ load_4xx_dbcr0:
        blr
 
        .comm   global_dbcr0,8
-#endif /* CONFIG_4xx */
+#endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
 
 do_work:                       /* r10 contains MSR_KERNEL here */
        andi.   r0,r9,_TIF_NEED_RESCHED
index c1df603..f3c0d2c 100644 (file)
@@ -304,8 +304,10 @@ void disable_irq_nosync(unsigned int irq)
 
 void disable_irq(unsigned int irq)
 {
+       irq_desc_t *desc = irq_desc + irq;
        disable_irq_nosync(irq);
-       synchronize_irq(irq);
+       if (desc->action)
+               synchronize_irq(irq);
 }
 
 /**
@@ -626,7 +628,9 @@ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
 static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer,
                                        unsigned long count, void *data)
 {
-       cpumask_t *mask = (cpumask_t *)data, full_count = count, err;
+       int err;
+       int full_count = count;
+       cpumask_t *mask = (cpumask_t *)data;
        cpumask_t new_value;
 
        err = cpumask_parse(buffer, count, new_value);
index c3ed5ed..38cd36d 100644 (file)
@@ -419,7 +419,24 @@ _GLOBAL(_tlbia)
        ble     1b
 
        isync
-#else /* !(CONFIG_40x || CONFIG_44x) */
+#elif defined(CONFIG_FSL_BOOKE)
+       /* Invalidate all entries in TLB0 */
+       li      r3, 0x04
+       tlbivax 0,3
+       /* Invalidate all entries in TLB1 */
+       li      r3, 0x0c
+       tlbivax 0,3
+       /* Invalidate all entries in TLB2 */
+       li      r3, 0x14
+       tlbivax 0,3
+       /* Invalidate all entries in TLB3 */
+       li      r3, 0x1c
+       tlbivax 0,3
+       msync
+#ifdef CONFIG_SMP
+       tlbsync
+#endif /* CONFIG_SMP */
+#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
 #if defined(CONFIG_SMP)
        rlwinm  r8,r1,0,0,18
        lwz     r8,TI_CPU(r8)
@@ -487,7 +504,20 @@ _GLOBAL(_tlbie)
        tlbwe   r3, r3, PPC44x_TLB_PAGEID
        isync
 10:
-#else /* !(CONFIG_40x || CONFIG_44x) */
+#elif defined(CONFIG_FSL_BOOKE)
+       rlwinm  r4, r3, 0, 0, 19
+       ori     r5, r4, 0x08    /* TLBSEL = 1 */
+       ori     r6, r4, 0x10    /* TLBSEL = 2 */
+       ori     r7, r4, 0x18    /* TLBSEL = 3 */
+       tlbivax 0, r4
+       tlbivax 0, r5
+       tlbivax 0, r6
+       tlbivax 0, r7
+       msync
+#if defined(CONFIG_SMP)
+       tlbsync
+#endif /* CONFIG_SMP */
+#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
 #if defined(CONFIG_SMP)
        rlwinm  r8,r1,0,0,18
        lwz     r8,TI_CPU(r8)
@@ -544,6 +574,10 @@ _GLOBAL(flush_instruction_cache)
        lis     r3, KERNELBASE@h
        iccci   0,r3
 #endif
+#elif CONFIG_FSL_BOOKE
+       mfspr   r3,SPRN_L1CSR1
+       ori     r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
+       mtspr   SPRN_L1CSR1,r3
 #else
        mfspr   r3,PVR
        rlwinm  r3,r3,16,16,31
@@ -1047,7 +1081,7 @@ _GLOBAL(_get_SP)
  * and exceptions as if the cpu had performed the load or store.
  */
 
-#if defined(CONFIG_4xx)
+#if defined(CONFIG_4xx) || defined(CONFIG_E500)
 _GLOBAL(cvt_fd)
        lfs     0,0(r3)
        stfd    0,0(r4)
index 5b49655..f095fcd 100644 (file)
@@ -128,7 +128,7 @@ pcibios_fixup_resources(struct pci_dev *dev)
                struct resource *res = dev->resource + i;
                if (!res->flags)
                        continue;
-               if (!res->start || res->end == 0xffffffff) {
+               if (res->end == 0xffffffff) {
                        DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n",
                            pci_name(dev), i, res->start, res->end);
                        res->end -= res->start;
@@ -347,6 +347,8 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i)
                return -1;
        }
        res = bus->resource[i];
+       if (res == NULL)
+               return -1;
        pr = NULL;
        for (j = 0; j < 4; j++) {
                struct resource *r = parent->resource[j];
@@ -659,11 +661,11 @@ make_one_node_map(struct device_node* node, u8 pci_bus)
                return;
        bus_range = (int *) get_property(node, "bus-range", &len);
        if (bus_range == NULL || len < 2 * sizeof(int)) {
-               printk(KERN_WARNING "Can't get bus-range for %s\n",
-                      node->full_name);
-               return;
-       }
-       pci_to_OF_bus_map[pci_bus] = bus_range[0];
+               printk(KERN_WARNING "Can't get bus-range for %s, "
+                      "assuming it starts at 0\n", node->full_name);
+               pci_to_OF_bus_map[pci_bus] = 0;
+       } else
+               pci_to_OF_bus_map[pci_bus] = bus_range[0];
 
        for (node=node->child; node != 0;node = node->sibling) {
                struct pci_dev* dev;
@@ -1073,6 +1075,8 @@ do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga)
        u16 w;
        struct resource res;
 
+       if (bus->resource[0] == NULL)
+               return;
        res = *(bus->resource[0]);
 
        DBG("Remapping Bus %d, bridge: %s\n", bus->number, bridge->slot_name);
@@ -1168,7 +1172,8 @@ do_fixup_p2p_level(struct pci_bus *bus)
        int has_vga = 0;
 
        for (parent_io=0; parent_io<4; parent_io++)
-               if (bus->resource[parent_io]->flags & IORESOURCE_IO)
+               if (bus->resource[parent_io]
+                   && bus->resource[parent_io]->flags & IORESOURCE_IO)
                        break;
        if (parent_io >= 4)
                return;
index 7d2f3a5..ad7808f 100644 (file)
@@ -101,7 +101,7 @@ static ssize_t ppc_htab_read(struct file * file, char __user * buf,
 {
        unsigned long mmcr0 = 0, pmc1 = 0, pmc2 = 0;
        int n = 0;
-#ifdef CONFIG_PPC_STD_MMU
+#if defined(CONFIG_PPC_STD_MMU) && !defined(CONFIG_PPC64BRIDGE)
        unsigned int kptes = 0, uptes = 0;
        PTE *ptr;
 #endif /* CONFIG_PPC_STD_MMU */
@@ -135,6 +135,7 @@ static ssize_t ppc_htab_read(struct file * file, char __user * buf,
                goto return_string;
        }
 
+#ifndef CONFIG_PPC64BRIDGE
        for (ptr = Hash; ptr < Hash_end; ptr++) {
                unsigned int mctx, vsid;
 
@@ -148,6 +149,7 @@ static ssize_t ppc_htab_read(struct file * file, char __user * buf,
                else
                        uptes++;
        }
+#endif
 
        n += sprintf( buffer + n,
                      "PTE Hash Table Information\n"
@@ -155,16 +157,20 @@ static ssize_t ppc_htab_read(struct file * file, char __user * buf,
                      "Buckets\t\t: %lu\n"
                      "Address\t\t: %08lx\n"
                      "Entries\t\t: %lu\n"
+#ifndef CONFIG_PPC64BRIDGE
                      "User ptes\t: %u\n"
                      "Kernel ptes\t: %u\n"
-                     "Percent full\t: %lu%%\n",
-                      (unsigned long)(Hash_size>>10),
+                     "Percent full\t: %lu%%\n"
+#endif
+                      , (unsigned long)(Hash_size>>10),
                      (Hash_size/(sizeof(PTE)*8)),
                      (unsigned long)Hash,
-                     Hash_size/sizeof(PTE),
-                      uptes,
+                     Hash_size/sizeof(PTE)
+#ifndef CONFIG_PPC64BRIDGE
+                      , uptes,
                      kptes,
                      ((kptes+uptes)*100) / (Hash_size/sizeof(PTE))
+#endif
                );
 
        n += sprintf( buffer + n,
index 0bcd36a..9bd46c1 100644 (file)
@@ -199,16 +199,11 @@ EXPORT_SYMBOL(flush_tlb_page);
 EXPORT_SYMBOL(last_task_used_altivec);
 EXPORT_SYMBOL(giveup_altivec);
 #endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+EXPORT_SYMBOL(last_task_used_spe);
+EXPORT_SYMBOL(giveup_spe);
+#endif /* CONFIG_SPE */
 #ifdef CONFIG_SMP
-#ifdef CONFIG_DEBUG_SPINLOCK
-EXPORT_SYMBOL(_raw_spin_lock);
-EXPORT_SYMBOL(_raw_spin_unlock);
-EXPORT_SYMBOL(_raw_spin_trylock);
-EXPORT_SYMBOL(_raw_read_lock);
-EXPORT_SYMBOL(_raw_read_unlock);
-EXPORT_SYMBOL(_raw_write_lock);
-EXPORT_SYMBOL(_raw_write_unlock);
-#endif
 EXPORT_SYMBOL(smp_call_function);
 EXPORT_SYMBOL(smp_hw_index);
 EXPORT_SYMBOL(synchronize_irq);
@@ -333,7 +328,7 @@ EXPORT_SYMBOL(debugger_fault_handler);
 EXPORT_SYMBOL(cpm_install_handler);
 EXPORT_SYMBOL(cpm_free_handler);
 #endif /* CONFIG_8xx */
-#if defined(CONFIG_8xx) || defined(CONFIG_40x)
+#if defined(CONFIG_8xx) || defined(CONFIG_40x) || defined(CONFIG_85xx)
 EXPORT_SYMBOL(__res);
 #endif
 #if defined(CONFIG_8xx)
index 19515a1..f6d8cd3 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/init_task.h>
 #include <linux/module.h>
 #include <linux/kallsyms.h>
+#include <linux/mqueue.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -49,6 +50,7 @@ extern unsigned long _get_SP(void);
 
 struct task_struct *last_task_used_math = NULL;
 struct task_struct *last_task_used_altivec = NULL;
+struct task_struct *last_task_used_spe = NULL;
 
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
@@ -163,7 +165,7 @@ dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
 void
 enable_kernel_altivec(void)
 {
-       WARN_ON(current_thread_info()->preempt_count == 0 && !irqs_disabled());
+       WARN_ON(preemptible());
 
 #ifdef CONFIG_SMP
        if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
@@ -177,10 +179,38 @@ enable_kernel_altivec(void)
 EXPORT_SYMBOL(enable_kernel_altivec);
 #endif /* CONFIG_ALTIVEC */
 
+#ifdef CONFIG_SPE
+int
+dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
+{
+       if (regs->msr & MSR_SPE)
+               giveup_spe(current);
+       /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
+       memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
+       return 1;
+}
+
+void
+enable_kernel_spe(void)
+{
+       WARN_ON(preemptible());
+
+#ifdef CONFIG_SMP
+       if (current->thread.regs && (current->thread.regs->msr & MSR_SPE))
+               giveup_spe(current);
+       else
+               giveup_spe(NULL);       /* just enable SPE for kernel - force */
+#else
+       giveup_spe(last_task_used_spe);
+#endif /* __SMP __ */
+}
+EXPORT_SYMBOL(enable_kernel_spe);
+#endif /* CONFIG_SPE */
+
 void
 enable_kernel_fp(void)
 {
-       WARN_ON(current_thread_info()->preempt_count == 0 && !irqs_disabled());
+       WARN_ON(preemptible());
 
 #ifdef CONFIG_SMP
        if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
@@ -244,6 +274,17 @@ struct task_struct *__switch_to(struct task_struct *prev,
        if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)))
                giveup_altivec(prev);
 #endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+       /*
+        * If the previous thread used spe in the last quantum
+        * (thus changing spe regs) then save them.
+        *
+        * On SMP we always save/restore spe regs just to avoid the
+        * complexity of changing processors.
+        */
+       if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
+               giveup_spe(prev);
+#endif /* CONFIG_SPE */
 #endif /* CONFIG_SMP */
 
        /* Avoid the trap.  On smp this this never happens since
@@ -251,6 +292,13 @@ struct task_struct *__switch_to(struct task_struct *prev,
         */
        if (new->thread.regs && last_task_used_altivec == new)
                new->thread.regs->msr |= MSR_VEC;
+#ifdef CONFIG_SPE
+       /* Avoid the trap.  On smp this this never happens since
+        * we don't set last_task_used_spe
+        */
+       if (new->thread.regs && last_task_used_spe == new)
+               new->thread.regs->msr |= MSR_SPE;
+#endif /* CONFIG_SPE */
        new_thread = &new->thread;
        old_thread = &current->thread;
        last = _switch(old_thread, new_thread);
@@ -354,6 +402,10 @@ void prepare_to_copy(struct task_struct *tsk)
        if (regs->msr & MSR_VEC)
                giveup_altivec(current);
 #endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+       if (regs->msr & MSR_SPE)
+               giveup_spe(current);
+#endif /* CONFIG_SPE */
        preempt_enable();
 }
 
@@ -438,18 +490,45 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
        current->thread.vrsave = 0;
        current->thread.used_vr = 0;
 #endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+       memset(current->thread.evr, 0, sizeof(current->thread.evr));
+       current->thread.acc = 0;
+       current->thread.spefscr = 0;
+       current->thread.used_spe = 0;
+#endif /* CONFIG_SPE */
 }
 
+#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \
+               | PR_FP_EXC_RES | PR_FP_EXC_INV)
+
 int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
 {
        struct pt_regs *regs = tsk->thread.regs;
 
-       if (val > PR_FP_EXC_PRECISE)
+       /* This is a bit hairy.  If we are an SPE enabled  processor
+        * (have embedded fp) we store the IEEE exception enable flags in
+        * fpexc_mode.  fpexc_mode is also used for setting FP exception
+        * mode (asyn, precise, disabled) for 'Classic' FP. */
+       if (val & PR_FP_EXC_SW_ENABLE) {
+#ifdef CONFIG_SPE
+               tsk->thread.fpexc_mode = val &
+                       (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
+#else
                return -EINVAL;
-       tsk->thread.fpexc_mode = __pack_fe01(val);
-       if (regs != NULL && (regs->msr & MSR_FP) != 0)
-               regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))
-                       | tsk->thread.fpexc_mode;
+#endif
+       } else {
+               /* on a CONFIG_SPE this does not hurt us.  The bits that
+                * __pack_fe01 use do not overlap with bits used for
+                * PR_FP_EXC_SW_ENABLE.  Additionally, the MSR[FE0,FE1] bits
+                * on CONFIG_SPE implementations are reserved so writing to
+                * them does not change anything */
+               if (val > PR_FP_EXC_PRECISE)
+                       return -EINVAL;
+               tsk->thread.fpexc_mode = __pack_fe01(val);
+               if (regs != NULL && (regs->msr & MSR_FP) != 0)
+                       regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))
+                               | tsk->thread.fpexc_mode;
+       }
        return 0;
 }
 
@@ -457,7 +536,14 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
 {
        unsigned int val;
 
-       val = __unpack_fe01(tsk->thread.fpexc_mode);
+       if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
+#ifdef CONFIG_SPE
+               val = tsk->thread.fpexc_mode;
+#else
+               return -EINVAL;
+#endif
+       else
+               val = __unpack_fe01(tsk->thread.fpexc_mode);
        return put_user(val, (unsigned int *) adr);
 }
 
@@ -506,6 +592,10 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
        if (regs->msr & MSR_VEC)
                giveup_altivec(current);
 #endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+       if (regs->msr & MSR_SPE)
+               giveup_spe(current);
+#endif /* CONFIG_SPE */
        preempt_enable();
        error = do_execve(filename, (char __user *__user *) a1,
                          (char __user *__user *) a2, regs);
index 2ddfb1a..30a81ff 100644 (file)
@@ -35,7 +35,7 @@
 /*
  * Set of msr bits that gdb can change on behalf of a process.
  */
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
 #define MSR_DEBUGCHANGE        0
 #else
 #define MSR_DEBUGCHANGE        (MSR_SE | MSR_BE)
@@ -131,13 +131,77 @@ static inline int set_vrregs(struct task_struct *task, unsigned long *data)
 }
 #endif
 
+#ifdef CONFIG_SPE
+
+/*
+ * For get_evrregs/set_evrregs functions 'data' has the following layout:
+ *
+ * struct {
+ *   u32 evr[32];
+ *   u64 acc;
+ *   u32 spefscr;
+ * }
+ */
+
+/*
+ * Get contents of SPE register state in task TASK.
+ */
+static inline int get_evrregs(unsigned long *data, struct task_struct *task)
+{
+       int i;
+
+       if (!access_ok(VERIFY_WRITE, data, 35 * sizeof(unsigned long)))
+               return -EFAULT;
+
+       /* copy SPEFSCR */
+       if (__put_user(task->thread.spefscr, &data[34]))
+               return -EFAULT;
+
+       /* copy SPE registers EVR[0] .. EVR[31] */
+       for (i = 0; i < 32; i++, data++)
+               if (__put_user(task->thread.evr[i], data))
+                       return -EFAULT;
+
+       /* copy ACC */
+       if (__put_user64(task->thread.acc, (unsigned long long *)data))
+               return -EFAULT;
+
+       return 0;
+}
+
+/*
+ * Write contents of SPE register state into task TASK.
+ */
+static inline int set_evrregs(struct task_struct *task, unsigned long *data)
+{
+       int i;
+
+       if (!access_ok(VERIFY_READ, data, 35 * sizeof(unsigned long)))
+               return -EFAULT;
+
+       /* copy SPEFSCR */
+       if (__get_user(task->thread.spefscr, &data[34]))
+               return -EFAULT;
+
+       /* copy SPE registers EVR[0] .. EVR[31] */
+       for (i = 0; i < 32; i++, data++)
+               if (__get_user(task->thread.evr[i], data))
+                       return -EFAULT;
+       /* copy ACC */
+       if (__get_user64(task->thread.acc, (unsigned long long*)data))
+               return -EFAULT;
+
+       return 0;
+}
+#endif /* CONFIG_SPE */
+
 static inline void
 set_single_step(struct task_struct *task)
 {
        struct pt_regs *regs = task->thread.regs;
 
        if (regs != NULL) {
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
                task->thread.dbcr0 = DBCR0_IDM | DBCR0_IC;
                /* MSR.DE should already be set */
 #else
@@ -152,7 +216,7 @@ clear_single_step(struct task_struct *task)
        struct pt_regs *regs = task->thread.regs;
 
        if (regs != NULL) {
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
                task->thread.dbcr0 = 0;
 #else
                regs->msr &= ~MSR_SE;
@@ -360,6 +424,23 @@ int sys_ptrace(long request, long pid, long addr, long data)
                ret = set_vrregs(child, (unsigned long *)data);
                break;
 #endif
+#ifdef CONFIG_SPE
+       case PTRACE_GETEVRREGS:
+               /* Get the child spe register state. */
+               if (child->thread.regs->msr & MSR_SPE)
+                       giveup_spe(child);
+               ret = get_evrregs((unsigned long *)data, child);
+               break;
+
+       case PTRACE_SETEVRREGS:
+               /* Set the child spe register state. */
+               /* this is to clear the MSR_SPE bit to force a reload
+                * of register state from memory */
+               if (child->thread.regs->msr & MSR_SPE)
+                       giveup_spe(child);
+               ret = set_evrregs(child, (unsigned long *)data);
+               break;
+#endif
 
        default:
                ret = ptrace_request(child, request, addr, data);
index e4f2390..82f6cf8 100644 (file)
@@ -183,8 +183,8 @@ struct rt_sigframe
 
 /*
  * Save the current user registers on the user stack.
- * We only save the altivec registers if the process has used
- * altivec instructions at some point.
+ * We only save the altivec/spe registers if the process has used
+ * altivec/spe instructions at some point.
  */
 static int
 save_user_regs(struct pt_regs *regs, struct mcontext *frame, int sigret)
@@ -197,6 +197,10 @@ save_user_regs(struct pt_regs *regs, struct mcontext *frame, int sigret)
 #ifdef CONFIG_ALTIVEC
        if (current->thread.used_vr && (regs->msr & MSR_VEC))
                giveup_altivec(current);
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+       if (current->thread.used_spe && (regs->msr & MSR_SPE))
+               giveup_spe(current);
 #endif /* CONFIG_ALTIVEC */
        preempt_enable();
 
@@ -229,6 +233,24 @@ save_user_regs(struct pt_regs *regs, struct mcontext *frame, int sigret)
                return 1;
 #endif /* CONFIG_ALTIVEC */
 
+#ifdef CONFIG_SPE
+       /* save spe registers */
+       if (current->thread.used_spe) {
+               if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
+                                  ELF_NEVRREG * sizeof(u32)))
+                       return 1;
+               /* set MSR_SPE in the saved MSR value to indicate that
+                  frame->mc_vregs contains valid data */
+               if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR]))
+                       return 1;
+       }
+       /* else assert((regs->msr & MSR_SPE) == 0) */
+
+       /* We always copy to/from spefscr */
+       if (__put_user(current->thread.spefscr, (u32 *)&frame->mc_vregs + ELF_NEVRREG))
+               return 1;
+#endif /* CONFIG_SPE */
+
        if (sigret) {
                /* Set up the sigreturn trampoline: li r0,sigret; sc */
                if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
@@ -249,7 +271,7 @@ static int
 restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr, int sig)
 {
        unsigned long save_r2;
-#ifdef CONFIG_ALTIVEC
+#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE)
        unsigned long msr;
 #endif
 
@@ -290,6 +312,23 @@ restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr, int sig)
                return 1;
 #endif /* CONFIG_ALTIVEC */
 
+#ifdef CONFIG_SPE
+       /* force the process to reload the spe registers from
+          current->thread when it next does spe instructions */
+       regs->msr &= ~MSR_SPE;
+       if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) {
+               /* restore spe registers from the stack */
+               if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
+                                    sizeof(sr->mc_vregs)))
+                       return 1;
+       } else if (current->thread.used_spe)
+               memset(&current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
+
+       /* Always get SPEFSCR back */
+       if (__get_user(current->thread.spefscr, (u32 *)&sr->mc_vregs + ELF_NEVRREG))
+               return 1;
+#endif /* CONFIG_SPE */
+
        return 0;
 }
 
index cc50022..ebe93fe 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/prctl.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -171,6 +172,11 @@ static inline int check_io_access(struct pt_regs *regs)
 /* On 4xx, the reason for the machine check or program exception
    is in the ESR. */
 #define get_reason(regs)       ((regs)->dsisr)
+#ifndef CONFIG_E500
+#define get_mc_reason(regs)    ((regs)->dsisr)
+#else
+#define get_mc_reason(regs)    (mfspr(SPRN_MCSR))
+#endif
 #define REASON_FP              0
 #define REASON_ILLEGAL         ESR_PIL
 #define REASON_PRIVILEGED      ESR_PPR
@@ -184,6 +190,7 @@ static inline int check_io_access(struct pt_regs *regs)
 /* On non-4xx, the reason for the machine check or program
    exception is in the MSR. */
 #define get_reason(regs)       ((regs)->msr)
+#define get_mc_reason(regs)    ((regs)->msr)
 #define REASON_FP              0x100000
 #define REASON_ILLEGAL         0x80000
 #define REASON_PRIVILEGED      0x40000
@@ -196,7 +203,7 @@ static inline int check_io_access(struct pt_regs *regs)
 void
 MachineCheckException(struct pt_regs *regs)
 {
-       unsigned long reason = get_reason(regs);
+       unsigned long reason = get_mc_reason(regs);
 
        if (user_mode(regs)) {
                regs->msr |= MSR_RI;
@@ -256,7 +263,37 @@ MachineCheckException(struct pt_regs *regs)
                /* Clear MCSR */
                mtspr(SPRN_MCSR, mcsr);
        }
-#else /* !CONFIG_4xx */
+#elif defined (CONFIG_E500)
+       printk("Machine check in kernel mode.\n");
+       printk("Caused by (from MCSR=%lx): ", reason);
+
+       if (reason & MCSR_MCP)
+               printk("Machine Check Signal\n");
+       if (reason & MCSR_ICPERR)
+               printk("Instruction Cache Parity Error\n");
+       if (reason & MCSR_DCP_PERR)
+               printk("Data Cache Push Parity Error\n");
+       if (reason & MCSR_DCPERR)
+               printk("Data Cache Parity Error\n");
+       if (reason & MCSR_GL_CI)
+               printk("Guarded Load or Cache-Inhibited stwcx.\n");
+       if (reason & MCSR_BUS_IAERR)
+               printk("Bus - Instruction Address Error\n");
+       if (reason & MCSR_BUS_RAERR)
+               printk("Bus - Read Address Error\n");
+       if (reason & MCSR_BUS_WAERR)
+               printk("Bus - Write Address Error\n");
+       if (reason & MCSR_BUS_IBERR)
+               printk("Bus - Instruction Data Error\n");
+       if (reason & MCSR_BUS_RBERR)
+               printk("Bus - Read Data Bus Error\n");
+       if (reason & MCSR_BUS_WBERR)
+               printk("Bus - Read Data Bus Error\n");
+       if (reason & MCSR_BUS_IPERR)
+               printk("Bus - Instruction Parity Error\n");
+       if (reason & MCSR_BUS_RPERR)
+               printk("Bus - Read Parity Error\n");
+#else /* !CONFIG_4xx && !CONFIG_E500 */
        printk("Machine check in kernel mode.\n");
        printk("Caused by (from SRR1=%lx): ", reason);
        switch (reason & 0x601F0000) {
@@ -682,6 +719,56 @@ AltivecAssistException(struct pt_regs *regs)
 }
 #endif /* CONFIG_ALTIVEC */
 
+#ifdef CONFIG_FSL_BOOKE
+void CacheLockingException(struct pt_regs *regs, unsigned long address,
+                          unsigned long error_code)
+{
+       /* We treat cache locking instructions from the user
+        * as priv ops, in the future we could try to do
+        * something smarter
+        */
+       if (error_code & (ESR_DLK|ESR_ILK))
+               _exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
+       return;
+}
+#endif /* CONFIG_FSL_BOOKE */
+
+#ifdef CONFIG_SPE
+void
+SPEFloatingPointException(struct pt_regs *regs)
+{
+       unsigned long spefscr;
+       int fpexc_mode;
+       int code = 0;
+
+       spefscr = current->thread.spefscr;
+       fpexc_mode = current->thread.fpexc_mode;
+
+       /* Hardware does not neccessarily set sticky
+        * underflow/overflow/invalid flags */
+       if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) {
+               code = FPE_FLTOVF;
+               spefscr |= SPEFSCR_FOVFS;
+       }
+       else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) {
+               code = FPE_FLTUND;
+               spefscr |= SPEFSCR_FUNFS;
+       }
+       else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV))
+               code = FPE_FLTDIV;
+       else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) {
+               code = FPE_FLTINV;
+               spefscr |= SPEFSCR_FINVS;
+       }
+       else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES))
+               code = FPE_FLTRES;
+
+       current->thread.spefscr = spefscr;
+
+       _exception(SIGFPE, regs, code, regs->nip);
+       return;
+}
+#endif
 
 void __init trap_init(void)
 {
index 1f85f3e..0eaffa9 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
+#include <linux/module.h>
 #include <asm/ppc_asm.h>
 #include <asm/smp.h>
 
@@ -22,7 +23,7 @@
  * since they may inhibit forward progress by other CPUs in getting
  * a lock.
  */
-unsigned long __spin_trylock(volatile unsigned long *lock)
+static inline unsigned long __spin_trylock(volatile unsigned long *lock)
 {
        unsigned long ret;
 
@@ -62,6 +63,7 @@ void _raw_spin_lock(spinlock_t *lock)
        lock->owner_pc = (unsigned long)__builtin_return_address(0);
        lock->owner_cpu = cpu;
 }
+EXPORT_SYMBOL(_raw_spin_lock);
 
 int _raw_spin_trylock(spinlock_t *lock)
 {
@@ -71,6 +73,7 @@ int _raw_spin_trylock(spinlock_t *lock)
        lock->owner_pc = (unsigned long)__builtin_return_address(0);
        return 1;
 }
+EXPORT_SYMBOL(_raw_spin_trylock);
 
 void _raw_spin_unlock(spinlock_t *lp)
 {
@@ -86,6 +89,7 @@ void _raw_spin_unlock(spinlock_t *lp)
        wmb();
        lp->lock = 0;
 }
+EXPORT_SYMBOL(_raw_spin_unlock);
 
 
 /*
@@ -119,6 +123,7 @@ again:
        }
        wmb();
 }
+EXPORT_SYMBOL(_raw_read_lock);
 
 void _raw_read_unlock(rwlock_t *rw)
 {
@@ -129,6 +134,7 @@ void _raw_read_unlock(rwlock_t *rw)
        wmb();
        atomic_dec((atomic_t *) &(rw)->lock);
 }
+EXPORT_SYMBOL(_raw_read_unlock);
 
 void _raw_write_lock(rwlock_t *rw)
 {
@@ -169,6 +175,22 @@ again:
        }
        wmb();
 }
+EXPORT_SYMBOL(_raw_write_lock);
+
+int _raw_write_trylock(rwlock_t *rw)
+{
+       if (test_and_set_bit(31, &(rw)->lock)) /* someone has a write lock */
+               return 0;
+
+       if ((rw)->lock & ~(1<<31)) {    /* someone has a read lock */
+               /* clear our write lock and wait for reads to go away */
+               clear_bit(31,&(rw)->lock);
+               return 0;
+       }
+       wmb();
+       return 1;
+}
+EXPORT_SYMBOL(_raw_write_trylock);
 
 void _raw_write_unlock(rwlock_t *rw)
 {
@@ -179,5 +201,6 @@ void _raw_write_unlock(rwlock_t *rw)
        wmb();
        clear_bit(31,&(rw)->lock);
 }
+EXPORT_SYMBOL(_raw_write_unlock);
 
 #endif
index 0382608..458e671 100644 (file)
@@ -12,3 +12,4 @@ obj-y                         := fault.o init.o mem_pieces.o \
 obj-$(CONFIG_PPC_STD_MMU)      += hashtable.o ppc_mmu.o tlb.o
 obj-$(CONFIG_40x)              += 4xx_mmu.o
 obj-$(CONFIG_44x)              += 44x_mmu.o
+obj-$(CONFIG_FSL_BOOKE)                += fsl_booke_mmu.o
index 7a280f9..2a4029c 100644 (file)
@@ -99,7 +99,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
        struct mm_struct *mm = current->mm;
        siginfo_t info;
        int code = SEGV_MAPERR;
-#if defined(CONFIG_4xx)
+#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
        int is_write = error_code & ESR_DST;
 #else
        int is_write = 0;
@@ -114,20 +114,20 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
                error_code &= 0x48200000;
        else
                is_write = error_code & 0x02000000;
-#endif /* CONFIG_4xx */
+#endif /* CONFIG_4xx || CONFIG_BOOKE */
 
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
        if (debugger_fault_handler && TRAP(regs) == 0x300) {
                debugger_fault_handler(regs);
                return 0;
        }
-#if !defined(CONFIG_4xx)
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
        if (error_code & 0x00400000) {
                /* DABR match */
                if (debugger_dabr_match(regs))
                        return 0;
        }
-#endif /* !CONFIG_4xx */
+#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
 #endif /* CONFIG_XMON || CONFIG_KGDB */
 
        if (in_atomic() || mm == NULL)
@@ -200,8 +200,8 @@ good_area:
        if (is_write) {
                if (!(vma->vm_flags & VM_WRITE))
                        goto bad_area;
-#if defined(CONFIG_4xx)
-       /* an exec  - 4xx allows for per-page execute permission */
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+       /* an exec  - 4xx/Book-E allows for per-page execute permission */
        } else if (TRAP(regs) == 0x400) {
                pte_t *ptep;
 
@@ -214,7 +214,7 @@ good_area:
                        goto bad_area;
 #endif
 
-               /* Since 4xx supports per-page execute permission,
+               /* Since 4xx/Book-E supports per-page execute permission,
                 * we lazily flush dcache to icache. */
                ptep = NULL;
                if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) {
index 5584e1d..bf4bd63 100644 (file)
@@ -253,6 +253,12 @@ void __init MMU_init(void)
        if (__max_memory && total_memory > __max_memory)
                total_memory = __max_memory;
        total_lowmem = total_memory;
+#ifdef CONFIG_FSL_BOOKE
+       /* Freescale Book-E parts expect lowmem to be mapped by fixed TLB
+        * entries, so we need to adjust lowmem to match the amount we can map
+        * in the fixed entries */
+       adjust_total_lowmem();
+#endif /* CONFIG_FSL_BOOKE */
        if (total_lowmem > __max_low_memory) {
                total_lowmem = __max_low_memory;
 #ifndef CONFIG_HIGHMEM
index 5f8b045..4699d6f 100644 (file)
@@ -27,6 +27,9 @@ extern int map_page(unsigned long va, phys_addr_t pa, int flags);
 extern void setbat(int index, unsigned long virt, unsigned long phys,
                   unsigned int size, int flags);
 extern void reserve_phys_mem(unsigned long start, unsigned long size);
+extern void settlbcam(int index, unsigned long virt, phys_addr_t phys,
+                     unsigned int size, int flags, unsigned int pid);
+extern void invalidate_tlbcam_entry(int index);
 
 extern int __map_without_bats;
 extern unsigned long ioremap_base;
@@ -53,6 +56,12 @@ extern unsigned long Hash_size, Hash_mask;
 extern void MMU_init_hw(void);
 extern unsigned long mmu_mapin_ram(void);
 
+#elif defined(CONFIG_FSL_BOOKE)
+#define flush_HPTE(X, va, pg)  _tlbie(va)
+extern void MMU_init_hw(void);
+extern unsigned long mmu_mapin_ram(void);
+extern void adjust_total_lowmem(void);
+
 #else
 /* anything except 4xx or 8xx */
 extern void MMU_init_hw(void);
index 04c1481..c16d4cc 100644 (file)
@@ -42,6 +42,10 @@ int io_bat_index;
 #define HAVE_BATS      1
 #endif
 
+#if defined(CONFIG_FSL_BOOKE)
+#define HAVE_TLBCAM    1
+#endif
+
 extern char etext[], _stext[];
 
 #ifdef CONFIG_SMP
@@ -59,6 +63,16 @@ void setbat(int index, unsigned long virt, unsigned long phys,
 #define p_mapped_by_bats(x)    (0UL)
 #endif /* HAVE_BATS */
 
+#ifdef HAVE_TLBCAM
+extern unsigned int tlbcam_index;
+extern unsigned int num_tlbcam_entries;
+extern unsigned long v_mapped_by_tlbcam(unsigned long va);
+extern unsigned long p_mapped_by_tlbcam(unsigned long pa);
+#else /* !HAVE_TLBCAM */
+#define v_mapped_by_tlbcam(x)  (0UL)
+#define p_mapped_by_tlbcam(x)  (0UL)
+#endif /* HAVE_TLBCAM */
+
 #ifdef CONFIG_44x
 /* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */
 #define PGDIR_ORDER    1
@@ -210,6 +224,9 @@ __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
        if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ )
                goto out;
 
+       if ((v = p_mapped_by_tlbcam(p)))
+               goto out;
+
        if (mem_init_done) {
                struct vm_struct *area;
                area = get_vm_area(size, VM_IOREMAP);
@@ -300,6 +317,9 @@ void __init mapin_ram(void)
 /* is x a power of 2? */
 #define is_power_of_2(x)       ((x) != 0 && (((x) & ((x) - 1)) == 0))
 
+/* is x a power of 4? */
+#define is_power_of_4(x)       ((x) != 0 && (((x) & (x-1)) == 0) && (ffs(x) & 1))
+
 /*
  * Set up a mapping for a block of I/O.
  * virt, phys, size must all be page-aligned.
@@ -325,6 +345,18 @@ void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
        }
 #endif /* HAVE_BATS */
 
+#ifdef HAVE_TLBCAM
+       /*
+        * Use a CAM for this if possible...
+        */
+       if (tlbcam_index < num_tlbcam_entries && is_power_of_4(size)
+           && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
+               settlbcam(tlbcam_index, virt, phys, size, flags, 0);
+               ++tlbcam_index;
+               return;
+       }
+#endif /* HAVE_TLBCAM */
+
        /* No BATs available, put it in the page tables. */
        for (i = 0; i < size; i += PAGE_SIZE)
                map_page(virt + i, phys + i, flags);
index 3bf70f6..34605ba 100644 (file)
@@ -66,6 +66,17 @@ void flush_hash_one_pte(pte_t *ptep)
        flush_hash_pages(mm->context, addr, ptephys, 1);
 }
 
+/*
+ * Called by ptep_set_access_flags, must flush on CPUs for which the
+ * DSI handler can't just "fixup" the TLB on a write fault
+ */
+void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr)
+{
+       if (Hash != 0)
+               return;
+       _tlbie(addr);
+}
+
 /*
  * Called at the end of a mmu_gather operation to make sure the
  * TLB flush is completely done.
index 31f2d30..6f0c426 100644 (file)
@@ -45,6 +45,7 @@ obj-$(CONFIG_PPLUS)           += pplus.o
 obj-$(CONFIG_PRPMC750)         += prpmc750.o
 obj-$(CONFIG_PRPMC800)         += prpmc800.o
 obj-$(CONFIG_SANDPOINT)                += sandpoint.o
+obj-$(CONFIG_SBC82xx)          += sbc82xx.o
 obj-$(CONFIG_SPRUCE)           += spruce.o
 
 ifeq ($(CONFIG_SMP),y)
index 626b77a..75c8e3d 100644 (file)
@@ -8,9 +8,12 @@ endif
 ifdef CONFIG_4xx
 EXTRA_AFLAGS           := -Wa,-m405
 endif
+ifdef CONFIG_E500
+EXTRA_AFLAGS           := -Wa,-me500
+endif
 
-CFLAGS_prom_init.o      += -mrelocatable-lib
-CFLAGS_btext.o          += -mrelocatable-lib
+CFLAGS_prom_init.o      += -fPIC
+CFLAGS_btext.o          += -fPIC
 
 obj-$(CONFIG_PPCBUG_NVRAM)     += prep_nvram.o
 obj-$(CONFIG_PPC_OCP)          += ocp.o
@@ -63,6 +66,7 @@ obj-$(CONFIG_PRPMC750)                += open_pic.o indirect_pci.o pci_auto.o \
 obj-$(CONFIG_HARRIER)          += harrier.o
 obj-$(CONFIG_PRPMC800)         += open_pic.o indirect_pci.o pci_auto.o
 obj-$(CONFIG_SANDPOINT)                += i8259.o open_pic.o pci_auto.o todc_time.o
+obj-$(CONFIG_SBC82xx)          += todc_time.o
 obj-$(CONFIG_SPRUCE)           += cpc700_pic.o indirect_pci.o pci_auto.o \
                                   todc_time.o
 obj-$(CONFIG_8260)             += m8260_setup.o ppc8260_pic.o
@@ -72,3 +76,9 @@ obj-$(CONFIG_SERIAL_TEXT_DEBUG)       += gen550_dbg.o
 endif
 obj-$(CONFIG_BOOTX_TEXT)       += btext.o
 obj-$(CONFIG_MPC10X_BRIDGE)     += mpc10x_common.o indirect_pci.o
+obj-$(CONFIG_40x)              += dcr.o
+obj-$(CONFIG_BOOKE)            += dcr.o
+obj-$(CONFIG_85xx)             += open_pic.o ppc85xx_common.o ppc85xx_setup.o
+ifeq ($(CONFIG_85xx),y)
+obj-$(CONFIG_PCI)              += indirect_pci.o pci_auto.o
+endif
index 42e71af..e39c88f 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "open_pic_defs.h"
 
-#ifdef CONFIG_PRPMC800
+#if defined(CONFIG_PRPMC800) || defined(CONFIG_85xx)
 #define OPENPIC_BIG_ENDIAN
 #endif
 
index f0a6ef1..9acd443 100644 (file)
@@ -198,7 +198,6 @@ config SCHED_SMT
 
 config PREEMPT
        bool "Preemptible Kernel"
-       depends on BROKEN
        help
          This option reduces the latency of the kernel when reacting to
          real-time or interactive events by allowing a low priority process to
index 00ffc9f..5381ba1 100644 (file)
@@ -17,7 +17,7 @@ KERNELLOAD    := 0xc000000000000000
 
 HAS_BIARCH      := $(shell if $(CC) -m64 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi;)
 ifeq ($(HAS_BIARCH),y)
-AS              := $(AS) -64
+AS              := $(AS) -a64
 LD              := $(LD) -m elf64ppc
 CC             := $(CC) -m64
 endif
index 58a5eb9..853b3ae 100644 (file)
@@ -22,8 +22,6 @@
 #include <asm/cache.h>
 #include <asm/cputable.h>
 
-void disable_kernel_fp(void); /* asm function from head.S */
-
 struct aligninfo {
        unsigned char len;
        unsigned char flags;
@@ -280,8 +278,11 @@ fix_alignment(struct pt_regs *regs)
        }
 
        /* Force the fprs into the save area so we can reference them */
-       if ((flags & F) && (regs->msr & MSR_FP))
-               giveup_fpu(current);
+       if (flags & F) {
+               if (!user_mode(regs))
+                       return 0;
+               flush_fp_to_thread(current);
+       }
        
        /* If we are loading, get the data from user space */
        if (flags & LD) {
@@ -310,9 +311,11 @@ fix_alignment(struct pt_regs *regs)
                if (flags & F) {
                        if (nb == 4) {
                                /* Doing stfs, have to convert to single */
+                               preempt_disable();
                                enable_kernel_fp();
                                cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread.fpscr);
                                disable_kernel_fp();
+                               preempt_enable();
                        }
                        else
                                data.dd = current->thread.fpr[reg];
@@ -344,9 +347,11 @@ fix_alignment(struct pt_regs *regs)
                if (flags & F) {
                        if (nb == 4) {
                                /* Doing lfs, have to convert to double */
+                               preempt_disable();
                                enable_kernel_fp();
                                cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread.fpscr);
                                disable_kernel_fp();
+                               preempt_enable();
                        }
                        else
                                current->thread.fpr[reg] = data.dd;
index 9368fb0..27d694d 100644 (file)
@@ -48,6 +48,8 @@ int main(void)
        DEFINE(THREAD_SHIFT, THREAD_SHIFT);
        DEFINE(THREAD_SIZE, THREAD_SIZE);
        DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+       DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
+       DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
 
        /* task_struct->thread */
        DEFINE(THREAD, offsetof(struct task_struct, thread));
@@ -99,7 +101,10 @@ int main(void)
        DEFINE(PACALPPACA, offsetof(struct paca_struct, xLpPaca));
         DEFINE(LPPACA, offsetof(struct paca_struct, xLpPaca));
         DEFINE(PACAREGSAV, offsetof(struct paca_struct, xRegSav));
-        DEFINE(PACAEXC, offsetof(struct paca_struct, exception_stack));
+        DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
+        DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
+        DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
+        DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi));
         DEFINE(PACAGUARD, offsetof(struct paca_struct, guard));
         DEFINE(LPPACASRR0, offsetof(struct ItLpPaca, xSavedSrr0));
         DEFINE(LPPACASRR1, offsetof(struct ItLpPaca, xSavedSrr1));
@@ -136,6 +141,10 @@ int main(void)
        DEFINE(GPR7, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[7]));
        DEFINE(GPR8, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[8]));
        DEFINE(GPR9, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[9]));
+       DEFINE(GPR10, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[10]));
+       DEFINE(GPR11, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[11]));
+       DEFINE(GPR12, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[12]));
+       DEFINE(GPR13, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[13]));
        DEFINE(GPR20, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[20]));
        DEFINE(GPR21, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[21]));
        DEFINE(GPR22, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[22]));
@@ -154,7 +163,7 @@ int main(void)
        DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
        DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3));
        DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result));
-       DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
+       DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
        DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe));
 
        /* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */
index 9f08385..e7d88ca 100644 (file)
 #define DO_SOFT_DISABLE
 #endif
 
-#undef SHOW_SYSCALLS
-#undef SHOW_SYSCALLS_TASK
-
-#ifdef SHOW_SYSCALLS_TASK
-       .data
-show_syscalls_task:
-       .long   -1
-#endif
-
+/*
+ * System calls.
+ */
        .section        ".toc","aw"
 .SYS_CALL_TABLE:
        .tc .sys_call_table[TC],.sys_call_table
@@ -51,107 +45,175 @@ show_syscalls_task:
 .SYS_CALL_TABLE32:
        .tc .sys_call_table32[TC],.sys_call_table32
 
+/* This value is used to mark exception frames on the stack. */
+exception_marker:
+       .tc     ID_72656773_68657265[TC],0x7265677368657265
+
        .section        ".text"
-       .align 3
+       .align 7
 
-/*
- * Handle a system call.
- */
-_GLOBAL(DoSyscall)
+#undef SHOW_SYSCALLS
+
+       .globl SystemCall_common
+SystemCall_common:
+       andi.   r10,r12,MSR_PR
+       mr      r10,r1
+       addi    r1,r1,-INT_FRAME_SIZE
+       beq-    1f
+       ld      r1,PACAKSAVE(r13)
+1:     std     r10,0(r1)
+       std     r11,_NIP(r1)
+       std     r12,_MSR(r1)
+       std     r0,GPR0(r1)
+       std     r10,GPR1(r1)
+       std     r2,GPR2(r1)
+       std     r3,GPR3(r1)
+       std     r4,GPR4(r1)
+       std     r5,GPR5(r1)
+       std     r6,GPR6(r1)
+       std     r7,GPR7(r1)
+       std     r8,GPR8(r1)
+       li      r11,0
+       std     r11,GPR9(r1)
+       std     r11,GPR10(r1)
+       std     r11,GPR11(r1)
+       std     r11,GPR12(r1)
+       std     r9,GPR13(r1)
+       crclr   so
+       mfcr    r9
+       mflr    r10
+       li      r11,0xc01
+       std     r9,_CCR(r1)
+       std     r10,_LINK(r1)
+       std     r11,_TRAP(r1)
+       mfxer   r9
+       mfctr   r10
+       std     r9,_XER(r1)
+       std     r10,_CTR(r1)
        std     r3,ORIG_GPR3(r1)
-       ld      r11,_CCR(r1)    /* Clear SO bit in CR */
-       lis     r10,0x1000
-       andc    r11,r11,r10
-       std     r11,_CCR(r1)
+       ld      r2,PACATOC(r13)
+       addi    r9,r1,STACK_FRAME_OVERHEAD
+       ld      r11,exception_marker@toc(r2)
+       std     r11,-16(r9)             /* "regshere" marker */
+#ifdef CONFIG_PPC_ISERIES
+       /* Hack for handling interrupts when soft-enabling on iSeries */
+       cmpdi   cr1,r0,0x5555           /* syscall 0x5555 */
+       andi.   r10,r12,MSR_PR          /* from kernel */
+       crand   4*cr0+eq,4*cr1+eq,4*cr0+eq
+       beq     HardwareInterrupt_entry
+       lbz     r10,PACAPROCENABLED(r13)
+       std     r10,SOFTE(r1)
+#endif
+       mfmsr   r11
+       ori     r11,r11,MSR_EE
+       mtmsrd  r11,1
+
 #ifdef SHOW_SYSCALLS
-#ifdef SHOW_SYSCALLS_TASK
-       LOADBASE(r31,show_syscalls_task)
-       ld      r31,show_syscalls_task@l(r31)
-       ld      r10,PACACURRENT(r13)
-       cmp     0,r10,r31
-       bne     1f
+       bl      .do_show_syscall
+       REST_GPR(0,r1)
+       REST_4GPRS(3,r1)
+       REST_2GPRS(7,r1)
+       addi    r9,r1,STACK_FRAME_OVERHEAD
 #endif
-       LOADADDR(r3,7f)
-       ld      r4,GPR0(r1)
-       ld      r5,GPR3(r1)
-       ld      r6,GPR4(r1)
-       ld      r7,GPR5(r1)
-       ld      r8,GPR6(r1)
-       ld      r9,GPR7(r1)
-       bl      .printk
-       LOADADDR(r3,77f)
-       ld      r4,GPR8(r1)
-       ld      r5,GPR9(r1)
-       ld      r6, PACACURRENT(r13)
-       bl      .printk
-       ld      r0,GPR0(r1)
-       ld      r3,GPR3(r1)
-       ld      r4,GPR4(r1)
-       ld      r5,GPR5(r1)
-       ld      r6,GPR6(r1)
-       ld      r7,GPR7(r1)
-       ld      r8,GPR8(r1)
-1:
-#endif /* SHOW_SYSCALLS */
-       clrrdi  r10,r1,THREAD_SHIFT
-       ld      r10,TI_FLAGS(r10)
+       clrrdi  r11,r1,THREAD_SHIFT
+       li      r12,0
+       ld      r10,TI_FLAGS(r11)
+       stb     r12,TI_SC_NOERR(r11)
        andi.   r11,r10,_TIF_SYSCALL_T_OR_A
-       bne-    50f
+       bne-    syscall_dotrace
+syscall_dotrace_cont:
        cmpli   0,r0,NR_syscalls
-       bge-    66f
+       bge-    syscall_enosys
+
+system_call:                   /* label this so stack traces look sane */
 /*
  * Need to vector to 32 Bit or default sys_call_table here,
  * based on caller's run-mode / personality.
  */
-       andi.   r11,r10,_TIF_32BIT
+       ld      r11,.SYS_CALL_TABLE@toc(2)
+       andi.   r10,r10,_TIF_32BIT
        beq-    15f
-       ld      r10,.SYS_CALL_TABLE32@toc(2)
-/*
- * We now zero extend all six arguments (r3 - r8), the compatibility
- * layer assumes this.
- */
+       ld      r11,.SYS_CALL_TABLE32@toc(2)
        clrldi  r3,r3,32
        clrldi  r4,r4,32
        clrldi  r5,r5,32
        clrldi  r6,r6,32
        clrldi  r7,r7,32
        clrldi  r8,r8,32
-       b       17f
 15:
-       ld      r10,.SYS_CALL_TABLE@toc(2)
-17:    slwi    r0,r0,3
-       ldx     r10,r10,r0      /* Fetch system call handler [ptr] */
+       slwi    r0,r0,3
+       ldx     r10,r11,r0      /* Fetch system call handler [ptr] */
        mtlr    r10
-       addi    r9,r1,STACK_FRAME_OVERHEAD
        blrl                    /* Call handler */
-_GLOBAL(ret_from_syscall_1)
-       std     r3,RESULT(r1)   /* Save result */
+
+syscall_exit:
 #ifdef SHOW_SYSCALLS
-#ifdef SHOW_SYSCALLS_TASK
-       ld      r10, PACACURRENT(13)
-       cmp     0,r10,r31
-       bne     91f
-#endif
-       mr      r4,r3
-       LOADADDR(r3,79f)
-       bl      .printk
-       ld      r3,RESULT(r1)
-91:
+       std     r3,GPR3(r1)
+       bl      .do_show_syscall_exit
+       ld      r3,GPR3(r1)
 #endif
+       std     r3,RESULT(r1)
+       ld      r5,_CCR(r1)
        li      r10,-_LAST_ERRNO
-       cmpld   0,r3,r10
-       blt     30f
+       cmpld   r3,r10
+       clrrdi  r12,r1,THREAD_SHIFT
+       bge-    syscall_error
+syscall_error_cont:
+
+       /* check for syscall tracing or audit */
+       ld      r9,TI_FLAGS(r12)
+       andi.   r0,r9,_TIF_SYSCALL_T_OR_A
+       bne-    syscall_exit_trace
+syscall_exit_trace_cont:
+
+       /* disable interrupts so current_thread_info()->flags can't change,
+          and so that we don't get interrupted after loading SRR0/1. */
+       ld      r8,_MSR(r1)
+       andi.   r10,r8,MSR_RI
+       beq-    unrecov_restore
+       mfmsr   r10
+       rldicl  r10,r10,48,1
+       rotldi  r10,r10,16
+       mtmsrd  r10,1
+       ld      r9,TI_FLAGS(r12)
+       andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+       bne-    syscall_exit_work
+       ld      r7,_NIP(r1)
+       stdcx.  r0,0,r1                 /* to clear the reservation */
+       andi.   r6,r8,MSR_PR
+       ld      r4,_LINK(r1)
+       beq     1f                      /* only restore r13 if */
+       ld      r13,GPR13(r1)           /* returning to usermode */
+1:     ld      r2,GPR2(r1)
+       ld      r1,GPR1(r1)
+       li      r12,MSR_RI
+       andc    r10,r10,r12
+       mtmsrd  r10,1                   /* clear MSR.RI */
+       mtlr    r4
+       mtcr    r5
+       mtspr   SRR0,r7
+       mtspr   SRR1,r8
+       rfid
+
+syscall_enosys:
+       li      r3,-ENOSYS
+       std     r3,RESULT(r1)
+       clrrdi  r12,r1,THREAD_SHIFT
+       ld      r5,_CCR(r1)
+
+syscall_error:
+       lbz     r11,TI_SC_NOERR(r12)
+       cmpi    0,r11,0
+       bne-    syscall_error_cont
        neg     r3,r3
-22:    ld      r10,_CCR(r1)    /* Set SO bit in CR */
-       oris    r10,r10,0x1000
-       std     r10,_CCR(r1)
-30:    std     r3,GPR3(r1)     /* Update return value */
-       b       .ret_from_except
-66:    li      r3,ENOSYS
-       b       22b
+       oris    r5,r5,0x1000    /* Set SO bit in CR */
+       std     r5,_CCR(r1)
+       b       syscall_error_cont
         
 /* Traced system call support */
-50:    addi    r3,r1,STACK_FRAME_OVERHEAD
+syscall_dotrace:
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      .do_syscall_trace_enter
        ld      r0,GPR0(r1)     /* Restore original registers */
        ld      r3,GPR3(r1)
@@ -160,65 +222,82 @@ _GLOBAL(ret_from_syscall_1)
        ld      r6,GPR6(r1)
        ld      r7,GPR7(r1)
        ld      r8,GPR8(r1)
-       /* XXX check this - Anton */
-       ld      r9,GPR9(r1)
-       cmpli   0,r0,NR_syscalls
-       bge-    66f
-/*
- * Need to vector to 32 Bit or default sys_call_table here,
- * based on caller's run-mode / personality.
- */
+       addi    r9,r1,STACK_FRAME_OVERHEAD
        clrrdi  r10,r1,THREAD_SHIFT
        ld      r10,TI_FLAGS(r10)
-       andi.   r11,r10,_TIF_32BIT
-       beq-    55f
-       ld      r10,.SYS_CALL_TABLE32@toc(2)
+       b       syscall_dotrace_cont
+
+syscall_exit_trace:
+       std     r3,GPR3(r1)
+       bl      .save_nvgprs
+       bl      .do_syscall_trace_leave
+       REST_NVGPRS(r1)
+       ld      r3,GPR3(r1)
+       ld      r5,_CCR(r1)
+       clrrdi  r12,r1,THREAD_SHIFT
+       b       syscall_exit_trace_cont
+
+/* Stuff to do on exit from a system call. */
+syscall_exit_work:
+       std     r3,GPR3(r1)
+       std     r5,_CCR(r1)
+       b       .ret_from_except_lite
+
+/* Save non-volatile GPRs, if not already saved. */
+_GLOBAL(save_nvgprs)
+       ld      r11,_TRAP(r1)
+       andi.   r0,r11,1
+       beqlr-
+       SAVE_NVGPRS(r1)
+       clrrdi  r0,r11,1
+       std     r0,_TRAP(r1)
+       blr
+
 /*
- * We now zero extend all six arguments (r3 - r8), the compatibility
- * layer assumes this.
+ * The sigsuspend and rt_sigsuspend system calls can call do_signal
+ * and thus put the process into the stopped state where we might
+ * want to examine its user state with ptrace.  Therefore we need
+ * to save all the nonvolatile registers (r14 - r31) before calling
+ * the C code.  Similarly, fork, vfork and clone need the full
+ * register state on the stack so that it can be copied to the child.
  */
-       clrldi  r3,r3,32
-       clrldi  r4,r4,32
-       clrldi  r5,r5,32
-       clrldi  r6,r6,32
-       clrldi  r7,r7,32
-       clrldi  r8,r8,32
-       b       57f
-55:
-       ld      r10,.SYS_CALL_TABLE@toc(2)
-57:
-       slwi    r0,r0,3
-       ldx     r10,r10,r0      /* Fetch system call handler [ptr] */
-       mtlr    r10
-       addi    r9,r1,STACK_FRAME_OVERHEAD
-       blrl                    /* Call handler */
-_GLOBAL(ret_from_syscall_2)
-       std     r3,RESULT(r1)   /* Save result */       
-       li      r10,-_LAST_ERRNO
-       cmpld   0,r3,r10
-       blt     60f
-       neg     r3,r3
-57:    ld      r10,_CCR(r1)    /* Set SO bit in CR */
-       oris    r10,r10,0x1000
-       std     r10,_CCR(r1)
-60:    std     r3,GPR3(r1)     /* Update return value */
-       bl      .do_syscall_trace_leave
-       b       .ret_from_except
-66:    li      r3,ENOSYS
-       b       57b
-#ifdef SHOW_SYSCALLS
-7:     .string "syscall %d(%x, %x, %x, %x, %x, "
-77:    .string "%x, %x), current=%p\n"
-79:    .string " -> %x\n"
-       .align  2,0
-#endif
+_GLOBAL(ppc32_sigsuspend)
+       bl      .save_nvgprs
+       bl      .sys32_sigsuspend
+       b       syscall_exit
+
+_GLOBAL(ppc64_rt_sigsuspend)
+       bl      .save_nvgprs
+       bl      .sys_rt_sigsuspend
+       b       syscall_exit
+
+_GLOBAL(ppc32_rt_sigsuspend)
+       bl      .save_nvgprs
+       bl      .sys32_rt_sigsuspend
+       b       syscall_exit
+
+_GLOBAL(ppc_fork)
+       bl      .save_nvgprs
+       bl      .sys_fork
+       b       syscall_exit
+
+_GLOBAL(ppc_vfork)
+       bl      .save_nvgprs
+       bl      .sys_vfork
+       b       syscall_exit
+
+_GLOBAL(ppc_clone)
+       bl      .save_nvgprs
+       bl      .sys_clone
+       b       syscall_exit
 
-       
 _GLOBAL(ppc32_swapcontext)
+       bl      .save_nvgprs
        bl      .sys32_swapcontext
        b       80f
        
 _GLOBAL(ppc64_swapcontext)
+       bl      .save_nvgprs
        bl      .sys_swapcontext
        b       80f
 
@@ -233,17 +312,20 @@ _GLOBAL(ppc32_rt_sigreturn)
 _GLOBAL(ppc64_rt_sigreturn)
        bl      .sys_rt_sigreturn
 
-80:    clrrdi  r4,r1,THREAD_SHIFT
+80:    cmpdi   0,r3,0
+       blt     syscall_exit
+       clrrdi  r4,r1,THREAD_SHIFT
        ld      r4,TI_FLAGS(r4)
        andi.   r4,r4,_TIF_SYSCALL_T_OR_A
-       bne-    81f
-       cmpi    0,r3,0
-       bge     .ret_from_except
-       b       .ret_from_syscall_1
-81:    cmpi    0,r3,0
-       blt     .ret_from_syscall_2
+       beq+    81f
        bl      .do_syscall_trace_leave
-       b       .ret_from_except
+81:    b       .ret_from_except
+
+_GLOBAL(ret_from_fork)
+       bl      .schedule_tail
+       REST_NVGPRS(r1)
+       li      r3,0
+       b       syscall_exit
 
 /*
  * This routine switches between two different tasks.  The process
@@ -263,6 +345,7 @@ _GLOBAL(ppc64_rt_sigreturn)
  * The code which creates the new task context is in 'copy_thread'
  * in arch/ppc64/kernel/process.c
  */
+       .align  7
 _GLOBAL(_switch)
        mflr    r0
        std     r0,16(r1)
@@ -315,7 +398,10 @@ BEGIN_FTR_SECTION
 2:
 END_FTR_SECTION_IFSET(CPU_FTR_SLB)
        clrrdi  r7,r8,THREAD_SHIFT      /* base of new stack */
-       addi    r7,r7,THREAD_SIZE-INT_FRAME_SIZE
+       /* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE
+          because we don't need to leave the 288-byte ABI gap at the
+          top of the kernel stack. */
+       addi    r7,r7,THREAD_SIZE-SWITCH_FRAME_SIZE
 
        mr      r1,r8           /* start using new stack pointer */
        std     r7,PACAKSAVE(r13)
@@ -350,60 +436,56 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        addi    r1,r1,SWITCH_FRAME_SIZE
        blr
 
-_GLOBAL(ret_from_fork)
-       bl      .schedule_tail
-       clrrdi  r4,r1,THREAD_SHIFT
-       ld      r4,TI_FLAGS(r4)
-       andi.   r4,r4,_TIF_SYSCALL_T_OR_A
-       beq+    .ret_from_except
-       bl      .do_syscall_trace_leave
-       b       .ret_from_except
-
+       .align  7
 _GLOBAL(ret_from_except)
+       ld      r11,_TRAP(r1)
+       andi.   r0,r11,1
+       bne     .ret_from_except_lite
+       REST_NVGPRS(r1)
+
+_GLOBAL(ret_from_except_lite)
        /*
         * Disable interrupts so that current_thread_info()->flags
         * can't change between when we test it and when we return
         * from the interrupt.
         */
        mfmsr   r10             /* Get current interrupt state */
-       li      r4,0
-       ori     r4,r4,MSR_EE
-       andc    r9,r10,r4       /* clear MSR_EE */
+       rldicl  r9,r10,48,1     /* clear MSR_EE */
+       rotldi  r9,r9,16
        mtmsrd  r9,1            /* Update machine state */
 
+#ifdef CONFIG_PREEMPT
+       clrrdi  r9,r1,THREAD_SHIFT      /* current_thread_info() */
+       li      r0,_TIF_NEED_RESCHED    /* bits to check */
+       ld      r3,_MSR(r1)
+       ld      r4,TI_FLAGS(r9)
+       /* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */
+       rlwimi  r0,r3,32+TIF_SIGPENDING-MSR_PR_LG,_TIF_SIGPENDING
+       and.    r0,r4,r0        /* check NEED_RESCHED and maybe SIGPENDING */
+       bne     do_work
+
+#else /* !CONFIG_PREEMPT */
        ld      r3,_MSR(r1)     /* Returning to user mode? */
        andi.   r3,r3,MSR_PR
        beq     restore         /* if not, just restore regs and return */
 
        /* Check current_thread_info()->flags */
-       clrrdi  r3,r1,THREAD_SHIFT
-       ld      r3,TI_FLAGS(r3)
-       andi.   r0,r3,_TIF_USER_WORK_MASK
+       clrrdi  r9,r1,THREAD_SHIFT
+       ld      r4,TI_FLAGS(r9)
+       andi.   r0,r4,_TIF_USER_WORK_MASK
        bne     do_work
-
-       addi    r0,r1,INT_FRAME_SIZE    /* size of frame */
-       ld      r4,PACACURRENT(r13)
-       std     r0,THREAD+KSP(r4)       /* save kernel stack pointer */
-
-       /*
-        * r13 is our per cpu area, only restore it if we are returning to
-        * userspace
-        */
-       REST_GPR(13,r1)
+#endif
 
 restore:
 #ifdef CONFIG_PPC_ISERIES
        ld      r5,SOFTE(r1)
-       mfspr   r4,SPRG3                /* get paca address */
        cmpdi   0,r5,0
        beq     4f
        /* Check for pending interrupts (iSeries) */
-       /* this is CHECKANYINT except that we already have the paca address */
-       ld      r3,PACALPPACA+LPPACAANYINT(r4)
+       ld      r3,PACALPPACA+LPPACAANYINT(r13)
        cmpdi   r3,0
        beq+    4f                      /* skip do_IRQ if no interrupts */
 
-       mfspr   r13,SPRG3               /* get paca pointer back */
        li      r3,0
        stb     r3,PACAPROCENABLED(r13) /* ensure we are soft-disabled */
        mtmsrd  r10                     /* hard-enable again */
@@ -411,13 +493,22 @@ restore:
        bl      .do_IRQ
        b       .ret_from_except                /* loop back and handle more */
 
-4:     stb     r5,PACAPROCENABLED(r4)
+4:     stb     r5,PACAPROCENABLED(r13)
 #endif
 
        ld      r3,_MSR(r1)
-       andi.   r3,r3,MSR_RI
+       andi.   r0,r3,MSR_RI
        beq-    unrecov_restore
 
+       andi.   r0,r3,MSR_PR
+
+       /*
+        * r13 is our per cpu area, only restore it if we are returning to
+        * userspace
+        */
+       beq     1f
+       REST_GPR(13, r1)
+1:
        ld      r3,_CTR(r1)
        ld      r0,_LINK(r1)
        mtctr   r3
@@ -426,8 +517,6 @@ restore:
        mtspr   XER,r3
 
        REST_8GPRS(5, r1)
-       REST_10GPRS(14, r1)
-       REST_8GPRS(24, r1)
 
        stdcx.  r0,0,r1         /* to clear the reservation */
 
@@ -451,26 +540,62 @@ restore:
        ld      r1,GPR1(r1)
 
        rfid
+       b       .
 
-/* Note: this must change if we start using the  TIF_NOTIFY_RESUME bit */
+/* Note: this must change if we start using the TIF_NOTIFY_RESUME bit */
 do_work:
+#ifdef CONFIG_PREEMPT
+       andi.   r0,r3,MSR_PR    /* Returning to user mode? */
+       bne     user_work
+       /* Check that preempt_count() == 0 and interrupts are enabled */
+       lwz     r8,TI_PREEMPT(r9)
+       cmpwi   cr1,r8,0
+#ifdef CONFIG_PPC_ISERIES
+       ld      r0,SOFTE(r1)
+       cmpdi   r0,0
+#else
+       andi.   r0,r3,MSR_EE
+#endif
+       crandc  eq,cr1*4+eq,eq
+       bne     restore
+       /* here we are preempting the current task */
+1:     lis     r0,PREEMPT_ACTIVE@h
+       stw     r0,TI_PREEMPT(r9)
+#ifdef CONFIG_PPC_ISERIES
+       li      r0,1
+       stb     r0,PACAPROCENABLED(r13)
+#endif
+       mtmsrd  r10,1           /* reenable interrupts */
+       bl      .schedule
+       mfmsr   r10
+       clrrdi  r9,r1,THREAD_SHIFT
+       rldicl  r10,r10,48,1    /* disable interrupts again */
+       li      r0,0
+       rotldi  r10,r10,16
+       mtmsrd  r10,1
+       ld      r4,TI_FLAGS(r9)
+       andi.   r0,r4,_TIF_NEED_RESCHED
+       bne     1b
+       stw     r0,TI_PREEMPT(r9)
+       b       restore
+
+user_work:
+#endif
        /* Enable interrupts */
        mtmsrd  r10,1
 
-       andi.   r0,r3,_TIF_NEED_RESCHED
+       andi.   r0,r4,_TIF_NEED_RESCHED
        beq     1f
        bl      .schedule
-       b       .ret_from_except
+       b       .ret_from_except_lite
 
-1:     andi.   r0,r3,_TIF_SIGPENDING
-       beq     .ret_from_except
+1:     bl      .save_nvgprs
        li      r3,0
        addi    r4,r1,STACK_FRAME_OVERHEAD
        bl      .do_signal
        b       .ret_from_except
 
 unrecov_restore:
-       mfspr   r13,SPRG3
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      .unrecoverable_exception
        b       unrecov_restore
@@ -488,7 +613,7 @@ _GLOBAL(enter_rtas)
        mflr    r0
        std     r0,16(r1)
         stdu   r1,-RTAS_FRAME_SIZE(r1) /* Save SP and create stack space. */
-       
+
        /* Because RTAS is running in 32b mode, it clobbers the high order half
         * of all registers that it saves.  We therefore save those registers
         * RTAS might touch to the stack.  (r0, r3-r13 are caller saved)
index 6b22a87..83601a8 100644 (file)
 #define DO_SOFT_DISABLE
 #endif
 
-/* copy saved SOFTE bit or EE bit from saved MSR depending
- * if we are doing soft-disable or not
- */
-#ifdef DO_SOFT_DISABLE
-#define DO_COPY_EE()   ld      r20,SOFTE(r1)
-#else
-#define DO_COPY_EE()   rldicl  r20,r23,49,63
-#endif
-
 /*
  * hcall interface to pSeries LPAR
  */
@@ -177,11 +168,18 @@ _GLOBAL(__secondary_hold)
 #endif
 #endif
 
+/* This value is used to mark exception frames on the stack. */
+       .section ".toc","aw"
+exception_marker:
+       .tc     ID_72656773_68657265[TC],0x7265677368657265
+       .text
+
 /*
  * The following macros define the code that appears as
  * the prologue to each of the exception handlers.  They
  * are split into two parts to allow a single kernel binary
- * to be used for pSeries, and iSeries.
+ * to be used for pSeries and iSeries.
+ * LOL.  One day... - paulus
  */
 
 /*
@@ -194,81 +192,55 @@ _GLOBAL(__secondary_hold)
  * This is the start of the interrupt handlers for pSeries
  * This code runs with relocation off.
  */
-#define EX_SRR0                0
-#define EX_SRR1                8
-#define EX_R20         16
-#define EX_R21         24
-#define EX_R22         32
-#define EX_R23         40
+#define EX_R9          0
+#define EX_R10         8
+#define EX_R11         16
+#define EX_R12         24
+#define EX_R13         32
+#define EX_SRR0                40
 #define EX_DAR         48
 #define EX_DSISR       56
 #define EX_CCR         60
-#define EX_TRAP        60
-
-#define EXCEPTION_PROLOG_PSERIES(n,label)                                \
-       mtspr   SPRG2,r20;              /* use SPRG2 as scratch reg   */ \
-       mtspr   SPRG1,r21;              /* save r21                   */ \
-       mfspr   r20,SPRG3;              /* get paca virt addr         */ \
-       ld      r21,PACAEXCSP(r20);     /* get exception stack ptr    */ \
-       addi    r21,r21,EXC_FRAME_SIZE; /* make exception frame       */ \
-       std     r22,EX_R22(r21);        /* Save r22 in exc. frame     */ \
-       li      r22,n;                  /* Save the ex # in exc. frame*/ \
-       stw     r22,EX_TRAP(r21);       /*                            */ \
-       std     r23,EX_R23(r21);        /* Save r23 in exc. frame     */ \
-       mfspr   r22,SRR0;               /* EA of interrupted instr    */ \
-       std     r22,EX_SRR0(r21);       /* Save SRR0 in exc. frame    */ \
-       mfspr   r23,SRR1;               /* machine state at interrupt */ \
-       std     r23,EX_SRR1(r21);       /* Save SRR1 in exc. frame    */ \
-                                                                         \
-       mfspr   r23,DAR;                /* Save DAR in exc. frame      */ \
-       std     r23,EX_DAR(r21);                                          \
-       mfspr   r23,DSISR;              /* Save DSISR in exc. frame    */ \
-       stw     r23,EX_DSISR(r21);                                        \
-       mfspr   r23,SPRG2;              /* Save r20 in exc. frame      */ \
-       std     r23,EX_R20(r21);                                          \
-                                                                         \
-       clrrdi  r22,r20,60;             /* Get 0xc part of the vaddr  */ \
-       ori     r22,r22,(label)@l;      /* add in the vaddr offset    */ \
-                                       /*   assumes *_common < 16b   */ \
-       mfmsr   r23;                                                     \
-       rotldi  r23,r23,4;                                               \
-       ori     r23,r23,0x32B;          /* Set IR, DR, RI, SF, ISF, HV*/ \
-       rotldi  r23,r23,60;             /* for generic handlers       */ \
-       mtspr   SRR0,r22;                                                \
-       mtspr   SRR1,r23;                                                \
-       mfcr    r23;                    /* save CR in r23             */ \
+
+#define EXCEPTION_PROLOG_PSERIES(area, label)                          \
+       mfspr   r13,SPRG3;              /* get paca address into r13 */ \
+       std     r9,area+EX_R9(r13);     /* save r9 - r12 */             \
+       std     r10,area+EX_R10(r13);                                   \
+       std     r11,area+EX_R11(r13);                                   \
+       std     r12,area+EX_R12(r13);                                   \
+       mfspr   r9,SPRG1;                                               \
+       std     r9,area+EX_R13(r13);                                    \
+       mfcr    r9;                                                     \
+       clrrdi  r12,r13,32;             /* get high part of &label */   \
+       mfmsr   r10;                                                    \
+       mfspr   r11,SRR0;               /* save SRR0 */                 \
+       ori     r12,r12,(label)@l;      /* virt addr of handler */      \
+       ori     r10,r10,MSR_IR|MSR_DR|MSR_RI;                           \
+       mtspr   SRR0,r12;                                               \
+       mfspr   r12,SRR1;               /* and SRR1 */                  \
+       mtspr   SRR1,r10;                                               \
        rfid
 
 /*
  * This is the start of the interrupt handlers for iSeries
  * This code runs with relocation on.
  */
-#define EXCEPTION_PROLOG_ISERIES(n)                                          \
-       mtspr   SPRG2,r20;                  /* use SPRG2 as scratch reg    */ \
-       mtspr   SPRG1,r21;                  /* save r21                    */ \
-       mfspr   r20,SPRG3;                  /* get paca                    */ \
-       ld      r21,PACAEXCSP(r20);         /* get exception stack ptr     */ \
-       addi    r21,r21,EXC_FRAME_SIZE;     /* make exception frame        */ \
-       std     r22,EX_R22(r21);            /* save r22 on exception frame */ \
-       li      r22,n;                      /* Save the ex # in exc. frame */ \
-       stw     r22,EX_TRAP(r21);           /*                             */ \
-       std     r23,EX_R23(r21);            /* Save r23 in exc. frame      */ \
-       ld      r22,LPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca      */ \
-       std     r22,EX_SRR0(r21);           /* save SRR0 in exc. frame     */ \
-       ld      r23,LPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca      */ \
-       std     r23,EX_SRR1(r21);           /* save SRR1 in exc. frame     */ \
-                                                                         \
-       mfspr   r23,DAR;                /* Save DAR in exc. frame      */ \
-       std     r23,EX_DAR(r21);                                          \
-       mfspr   r23,DSISR;              /* Save DSISR in exc. frame    */ \
-       stw     r23,EX_DSISR(r21);                                        \
-       mfspr   r23,SPRG2;              /* Save r20 in exc. frame      */ \
-       std     r23,EX_R20(r21);                                          \
-                                                                         \
-       mfmsr   r22;                        /* set MSR.RI                  */ \
-       ori     r22,r22,MSR_RI;                                               \
-       mtmsrd  r22,1;                                                        \
-       mfcr    r23;                        /* save CR in r23              */
+#define EXCEPTION_PROLOG_ISERIES_1(area)                               \
+       mfspr   r13,SPRG3;              /* get paca address into r13 */ \
+       std     r9,area+EX_R9(r13);     /* save r9 - r12 */             \
+       std     r10,area+EX_R10(r13);                                   \
+       std     r11,area+EX_R11(r13);                                   \
+       std     r12,area+EX_R12(r13);                                   \
+       mfspr   r9,SPRG1;                                               \
+       std     r9,area+EX_R13(r13);                                    \
+       mfcr    r9
+
+#define EXCEPTION_PROLOG_ISERIES_2                                     \
+       mfmsr   r10;                                                    \
+       ld      r11,LPPACA+LPPACASRR0(r13);                             \
+       ld      r12,LPPACA+LPPACASRR1(r13);                             \
+       ori     r10,r10,MSR_RI;                                         \
+       mtmsrd  r10,1
 
 /*
  * The common exception prolog is used for all except a few exceptions
@@ -276,107 +248,154 @@ _GLOBAL(__secondary_hold)
  * to take another exception from the point where we first touch the
  * kernel stack onwards.
  *
- * On entry r20 points to the paca and r21 points to the exception
- * frame on entry, r23 contains the saved CR, and relocation is on.
- */
-#define EXCEPTION_PROLOG_COMMON                                           \
-       mfspr   r22,SPRG1;              /* Save r21 in exc. frame      */ \
-       std     r22,EX_R21(r21);                                          \
-       std     r21,PACAEXCSP(r20);     /* update exception stack ptr  */ \
-       ld      r22,EX_SRR1(r21);       /* Get SRR1 from exc. frame    */ \
-       andi.   r22,r22,MSR_PR;         /* Set CR for later branch     */ \
-       mr      r22,r1;                 /* Save r1                     */ \
-       subi    r1,r1,INT_FRAME_SIZE;   /* alloc frame on kernel stack */ \
-       beq-    1f;                                                       \
-       ld      r1,PACAKSAVE(r20);      /* kernel stack to use         */ \
-1:      cmpdi  cr1,r1,0;               /* check if r1 is in userspace */ \
-       bge     cr1,bad_stack;          /* abort if it is              */ \
-       std     r22,GPR1(r1);           /* save r1 in stackframe       */ \
-       std     r22,0(r1);              /* make stack chain pointer    */ \
-       std     r23,_CCR(r1);           /* save CR in stackframe       */ \
-       ld      r22,EX_R20(r21);        /* move r20 to stackframe      */ \
-       std     r22,GPR20(r1);                                            \
-       ld      r23,EX_R21(r21);        /* move r21 to stackframe      */ \
-       std     r23,GPR21(r1);                                            \
-       ld      r22,EX_R22(r21);        /* move r22 to stackframe      */ \
-       std     r22,GPR22(r1);                                            \
-       ld      r23,EX_R23(r21);        /* move r23 to stackframe      */ \
-       std     r23,GPR23(r1);                                            \
-       mflr    r22;                    /* save LR in stackframe       */ \
-       std     r22,_LINK(r1);                                            \
-       mfctr   r23;                    /* save CTR in stackframe      */ \
-       std     r23,_CTR(r1);                                             \
-       mfspr   r22,XER;                /* save XER in stackframe      */ \
-       std     r22,_XER(r1);                                             \
-       ld      r23,EX_DAR(r21);        /* move DAR to stackframe      */ \
-       std     r23,_DAR(r1);                                             \
-       lwz     r22,EX_DSISR(r21);      /* move DSISR to stackframe    */ \
-       std     r22,_DSISR(r1);                                           \
-       lbz     r22,PACAPROCENABLED(r20);                                 \
-       std     r22,SOFTE(r1);                                            \
-       ld      r22,EX_SRR0(r21);       /* get SRR0 from exc. frame    */ \
-       ld      r23,EX_SRR1(r21);       /* get SRR1 from exc. frame    */ \
-       addi    r21,r21,-EXC_FRAME_SIZE;/* pop off exception frame     */ \
-       std     r21,PACAEXCSP(r20);                                       \
-       SAVE_GPR(0, r1);                /* save r0 in stackframe       */ \
-       SAVE_8GPRS(2, r1);              /* save r2 - r13 in stackframe */ \
-       SAVE_4GPRS(10, r1);                                               \
-       ld      r2,PACATOC(r20);                                          \
-       mr      r13,r20
-
-/*
- * Note: code which follows this uses cr0.eq (set if from kernel),
- * r1, r22 (SRR0), and r23 (SRR1).
+ * On entry r13 points to the paca, r9-r13 are saved in the paca,
+ * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
+ * SRR1, and relocation is on.
  */
+#define EXCEPTION_PROLOG_COMMON(n, area)                                  \
+       andi.   r10,r12,MSR_PR;         /* See if coming from user      */ \
+       mr      r10,r1;                 /* Save r1                      */ \
+       subi    r1,r1,INT_FRAME_SIZE;   /* alloc frame on kernel stack  */ \
+       beq-    1f;                                                        \
+       ld      r1,PACAKSAVE(r13);      /* kernel stack to use          */ \
+1:      cmpdi  cr1,r1,0;               /* check if r1 is in userspace  */ \
+       bge-    cr1,bad_stack;          /* abort if it is               */ \
+       std     r9,_CCR(r1);            /* save CR in stackframe        */ \
+       std     r11,_NIP(r1);           /* save SRR0 in stackframe      */ \
+       std     r12,_MSR(r1);           /* save SRR1 in stackframe      */ \
+       std     r10,0(r1);              /* make stack chain pointer     */ \
+       std     r0,GPR0(r1);            /* save r0 in stackframe        */ \
+       std     r10,GPR1(r1);           /* save r1 in stackframe        */ \
+       std     r2,GPR2(r1);            /* save r2 in stackframe        */ \
+       SAVE_4GPRS(3, r1);              /* save r3 - r6 in stackframe   */ \
+       SAVE_2GPRS(7, r1);              /* save r7, r8 in stackframe    */ \
+       ld      r9,area+EX_R9(r13);     /* move r9, r10 to stackframe   */ \
+       ld      r10,area+EX_R10(r13);                                      \
+       std     r9,GPR9(r1);                                               \
+       std     r10,GPR10(r1);                                             \
+       ld      r9,area+EX_R11(r13);    /* move r11 - r13 to stackframe */ \
+       ld      r10,area+EX_R12(r13);                                      \
+       ld      r11,area+EX_R13(r13);                                      \
+       std     r9,GPR11(r1);                                              \
+       std     r10,GPR12(r1);                                             \
+       std     r11,GPR13(r1);                                             \
+       ld      r2,PACATOC(r13);        /* get kernel TOC into r2       */ \
+       mflr    r9;                     /* save LR in stackframe        */ \
+       std     r9,_LINK(r1);                                              \
+       mfctr   r10;                    /* save CTR in stackframe       */ \
+       std     r10,_CTR(r1);                                              \
+       mfspr   r11,XER;                /* save XER in stackframe       */ \
+       std     r11,_XER(r1);                                              \
+       li      r9,(n)+1;                                                  \
+       std     r9,_TRAP(r1);           /* set trap number              */ \
+       li      r10,0;                                                     \
+       ld      r11,exception_marker@toc(r2);                              \
+       std     r10,RESULT(r1);         /* clear regs->result           */ \
+       std     r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame      */
 
 /*
  * Exception vectors.
  */
-#define STD_EXCEPTION_PSERIES(n, label )       \
-       . = n;                                  \
-       .globl label##_Pseries;                 \
-label##_Pseries:                               \
-       EXCEPTION_PROLOG_PSERIES( n, label##_common )
-
-#define STD_EXCEPTION_ISERIES( n, label )      \
-       .globl label##_Iseries;                 \
-label##_Iseries:                               \
-       EXCEPTION_PROLOG_ISERIES( n );          \
+#define STD_EXCEPTION_PSERIES(n, label )               \
+       . = n;                                          \
+       .globl label##_Pseries;                         \
+label##_Pseries:                                       \
+       mtspr   SPRG1,r13;              /* save r13 */  \
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+
+#define STD_EXCEPTION_ISERIES(n, label, area)          \
+       .globl label##_Iseries;                         \
+label##_Iseries:                                       \
+       mtspr   SPRG1,r13;              /* save r13 */  \
+       EXCEPTION_PROLOG_ISERIES_1(area);               \
+       EXCEPTION_PROLOG_ISERIES_2;                     \
        b       label##_common
 
-#define MASKABLE_EXCEPTION_ISERIES( n, label ) \
-       .globl label##_Iseries;                 \
-label##_Iseries:                               \
-       EXCEPTION_PROLOG_ISERIES( n );          \
-       lbz     r22,PACAPROFENABLED(r20);       \
-       cmpi    0,r22,0;                        \
-       bne-    label##_Iseries_profile;        \
-label##_Iseries_prof_ret:                      \
-       lbz     r22,PACAPROCENABLED(r20);       \
-       cmpi    0,r22,0;                        \
-       beq-    label##_Iseries_masked;         \
-       b       label##_common;                 \
-label##_Iseries_profile:                       \
-       std     r24,48(r21);                    \
-       std     r25,56(r21);                    \
-       mflr    r24;                            \
-       bl      do_profile;                     \
-       mtlr    r24;                            \
-       ld      r24,48(r21);                    \
-       ld      r25,56(r21);                    \
+#define MASKABLE_EXCEPTION_ISERIES( n, label )                         \
+       .globl label##_Iseries;                                         \
+label##_Iseries:                                                       \
+       mtspr   SPRG1,r13;              /* save r13 */                  \
+       EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN);                         \
+       lbz     r10,PACAPROFENABLED(r13);                               \
+       cmpwi   r10,0;                                                  \
+       bne-    label##_Iseries_profile;                                \
+label##_Iseries_prof_ret:                                              \
+       lbz     r10,PACAPROCENABLED(r13);                               \
+       cmpwi   0,r10,0;                                                \
+       beq-    label##_Iseries_masked;                                 \
+       EXCEPTION_PROLOG_ISERIES_2;                                     \
+       b       label##_common;                                         \
+label##_Iseries_profile:                                               \
+       ld      r12,LPPACA+LPPACASRR1(r13);                             \
+       andi.   r12,r12,MSR_PR;         /* Test if in kernel */         \
+       bne     label##_Iseries_prof_ret;                               \
+       ld      r11,LPPACA+LPPACASRR0(r13);                             \
+       ld      r12,PACAPROFSTEXT(r13); /* _stext */                    \
+       subf    r11,r12,r11;            /* offset into kernel */        \
+       lwz     r12,PACAPROFSHIFT(r13);                                 \
+       srd     r11,r11,r12;                                            \
+       lwz     r12,PACAPROFLEN(r13);   /* profile table length - 1 */  \
+       cmpd    r11,r12;                /* off end? */                  \
+       ble     1f;                                                     \
+       mr      r11,r12;                /* force into last entry */     \
+1:     sldi    r11,r11,2;              /* convert to offset */         \
+       ld      r12,PACAPROFBUFFER(r13);/* profile buffer */            \
+       add     r12,r12,r11;                                            \
+2:     lwarx   r11,0,r12;              /* atomically increment */      \
+       addi    r11,r11,1;                                              \
+       stwcx.  r11,0,r12;                                              \
+       bne-    2b;                                                     \
        b       label##_Iseries_prof_ret
 
+#ifdef DO_SOFT_DISABLE
+#define DISABLE_INTS                           \
+       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
+
+#define ENABLE_INTS                            \
+       lbz     r10,PACAPROCENABLED(r13);       \
+       mfmsr   r11;                            \
+       std     r10,SOFTE(r1);                  \
+       ori     r11,r11,MSR_EE;                 \
+       mtmsrd  r11,1
+
+#else  /* hard enable/disable interrupts */
+#define DISABLE_INTS
+
+#define ENABLE_INTS                            \
+       ld      r12,_MSR(r1);                   \
+       mfmsr   r11;                            \
+       rlwimi  r11,r12,0,MSR_EE;               \
+       mtmsrd  r11,1
+
+#endif
+
 #define STD_EXCEPTION_COMMON( trap, label, hdlr )      \
-       .globl label##_common;                  \
-label##_common:                                        \
-       EXCEPTION_PROLOG_COMMON;                \
-       addi    r3,r1,STACK_FRAME_OVERHEAD;     \
-       li      r20,0;                          \
-       li      r6,trap;                        \
-       bl      .save_remaining_regs;           \
-       bl      hdlr;                           \
+       .align  7;                                      \
+       .globl label##_common;                          \
+label##_common:                                                \
+       EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);      \
+       DISABLE_INTS;                                   \
+       bl      .save_nvgprs;                           \
+       addi    r3,r1,STACK_FRAME_OVERHEAD;             \
+       bl      hdlr;                                   \
        b       .ret_from_except
 
+#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr)   \
+       .align  7;                                      \
+       .globl label##_common;                          \
+label##_common:                                                \
+       EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);      \
+       DISABLE_INTS;                                   \
+       addi    r3,r1,STACK_FRAME_OVERHEAD;             \
+       bl      hdlr;                                   \
+       b       .ret_from_except_lite
+
 /*
  * Start of pSeries system interrupt routines
  */
@@ -385,9 +404,45 @@ label##_common:                                    \
 __start_interrupts:
 
        STD_EXCEPTION_PSERIES( 0x100, SystemReset )
-       STD_EXCEPTION_PSERIES( 0x200, MachineCheck )
-       STD_EXCEPTION_PSERIES( 0x300, DataAccess )
-       STD_EXCEPTION_PSERIES( 0x380, DataAccessSLB )
+
+       . = 0x200
+       .globl MachineCheck_Pseries
+_MachineCheckPseries:
+       mtspr   SPRG1,r13               /* save r13 */
+       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, MachineCheck_common)
+
+       . = 0x300
+       .globl DataAccess_Pseries
+DataAccess_Pseries:
+       mtspr   SPRG1,r13
+BEGIN_FTR_SECTION
+       mtspr   SPRG2,r12
+       mfspr   r13,DAR
+       mfspr   r12,DSISR
+       srdi    r13,r13,60
+       rlwimi  r13,r12,16,0x20
+       mfcr    r12
+       cmpwi   r13,0x2c
+       beq     .do_stab_bolted_Pseries
+       mtcrf   0x80,r12
+       mfspr   r12,SPRG2
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, DataAccess_common)
+
+       . = 0x380
+       .globl DataAccessSLB_Pseries
+DataAccessSLB_Pseries:
+       mtspr   SPRG1,r13
+       mtspr   SPRG2,r12
+       mfspr   r13,DAR
+       mfcr    r12
+       srdi    r13,r13,60
+       cmpdi   r13,0xc
+       beq     .do_slb_bolted_Pseries
+       mtcrf   0x80,r12
+       mfspr   r12,SPRG2
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, DataAccessSLB_common)
+
        STD_EXCEPTION_PSERIES( 0x400, InstructionAccess )
        STD_EXCEPTION_PSERIES( 0x480, InstructionAccessSLB )
        STD_EXCEPTION_PSERIES( 0x500, HardwareInterrupt )
@@ -397,7 +452,23 @@ __start_interrupts:
        STD_EXCEPTION_PSERIES( 0x900, Decrementer )
        STD_EXCEPTION_PSERIES( 0xa00, Trap_0a )
        STD_EXCEPTION_PSERIES( 0xb00, Trap_0b )
-       STD_EXCEPTION_PSERIES( 0xc00, SystemCall )
+
+       . = 0xc00
+       .globl  SystemCall_Pseries
+SystemCall_Pseries:
+       mr      r9,r13
+       mfmsr   r10
+       mfspr   r13,SPRG3
+       mfspr   r11,SRR0
+       clrrdi  r12,r13,32
+       oris    r12,r12,SystemCall_common@h
+       ori     r12,r12,SystemCall_common@l
+       mtspr   SRR0,r12
+       ori     r10,r10,MSR_IR|MSR_DR|MSR_RI
+       mfspr   r12,SRR1
+       mtspr   SRR1,r10
+       rfid
+
        STD_EXCEPTION_PSERIES( 0xd00, SingleStep )
        STD_EXCEPTION_PSERIES( 0xe00, Trap_0e )
 
@@ -407,25 +478,26 @@ __start_interrupts:
         * trickery is thus necessary
         */
        . = 0xf00
-       b       .PerformanceMonitor_Pseries
-       . = 0xf20
-       b       .AltivecUnavailable_Pseries
+       b       PerformanceMonitor_Pseries
+
+       STD_EXCEPTION_PSERIES(0xf20, AltivecUnavailable)
 
        STD_EXCEPTION_PSERIES( 0x1300, InstructionBreakpoint )
        STD_EXCEPTION_PSERIES( 0x1700, AltivecAssist )
 
-       /* Here are the "moved" performance monitor and
-        * altivec unavailable exceptions
-        */
-       . = 0x3000
-       .globl PerformanceMonitor_Pseries;
-.PerformanceMonitor_Pseries:
-       EXCEPTION_PROLOG_PSERIES(0xf00, PerformanceMonitor_common)
+       /* moved from 0xf00 */
+       STD_EXCEPTION_PSERIES(0x3000, PerformanceMonitor)
        
        . = 0x3100
-       .globl AltivecUnavailable_Pseries;
-.AltivecUnavailable_Pseries:
-       EXCEPTION_PROLOG_PSERIES(0xf20, AltivecUnavailable_common)
+_GLOBAL(do_stab_bolted_Pseries)
+       mtcrf   0x80,r12
+       mfspr   r12,SPRG2
+       EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
+
+_GLOBAL(do_slb_bolted_Pseries)
+       mtcrf   0x80,r12
+       mfspr   r12,SPRG2
+       EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_slb_bolted)
        
                
        /* Space for the naca.  Architected to be located at real address
@@ -484,31 +556,82 @@ __end_systemcfg:
 
 /***  ISeries-LPAR interrupt handlers ***/
 
-       STD_EXCEPTION_ISERIES( 0x200, MachineCheck )
-       STD_EXCEPTION_ISERIES( 0x300, DataAccess )
-       STD_EXCEPTION_ISERIES( 0x380, DataAccessSLB )
-       STD_EXCEPTION_ISERIES( 0x400, InstructionAccess )
-       STD_EXCEPTION_ISERIES( 0x480, InstructionAccessSLB )
-       MASKABLE_EXCEPTION_ISERIES( 0x500, HardwareInterrupt )
-       STD_EXCEPTION_ISERIES( 0x600, Alignment )
-       STD_EXCEPTION_ISERIES( 0x700, ProgramCheck )
-       STD_EXCEPTION_ISERIES( 0x800, FPUnavailable )
-       MASKABLE_EXCEPTION_ISERIES( 0x900, Decrementer )
-       STD_EXCEPTION_ISERIES( 0xa00, Trap_0a )
-       STD_EXCEPTION_ISERIES( 0xb00, Trap_0b )
-       STD_EXCEPTION_ISERIES( 0xc00, SystemCall )
-       STD_EXCEPTION_ISERIES( 0xd00, SingleStep )
-       STD_EXCEPTION_ISERIES( 0xe00, Trap_0e )
-       STD_EXCEPTION_ISERIES( 0xf00, PerformanceMonitor )
+       STD_EXCEPTION_ISERIES(0x200, MachineCheck, PACA_EXMC)
+
+       .globl DataAccess_Iseries
+DataAccess_Iseries:
+       mtspr   SPRG1,r13
+BEGIN_FTR_SECTION
+       mtspr   SPRG2,r12
+       mfspr   r13,DAR
+       mfspr   r12,DSISR
+       srdi    r13,r13,60
+       rlwimi  r13,r12,16,0x20
+       mfcr    r12
+       cmpwi   r13,0x2c
+       beq     .do_stab_bolted_Iseries
+       mtcrf   0x80,r12
+       mfspr   r12,SPRG2
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+       EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
+       EXCEPTION_PROLOG_ISERIES_2
+       b       DataAccess_common
+
+.do_stab_bolted_Iseries:
+       mtcrf   0x80,r12
+       mfspr   r12,SPRG2
+       EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
+       EXCEPTION_PROLOG_ISERIES_2
+       b       .do_stab_bolted
+
+       .globl  DataAccessSLB_Iseries
+DataAccessSLB_Iseries:
+       mtspr   SPRG1,r13               /* save r13 */
+       mtspr   SPRG2,r12
+       mfspr   r13,DAR
+       mfcr    r12
+       srdi    r13,r13,60
+       cmpdi   r13,0xc
+       beq     .do_slb_bolted_Iseries
+       mtcrf   0x80,r12
+       mfspr   r12,SPRG2
+       EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
+       EXCEPTION_PROLOG_ISERIES_2
+       b       DataAccessSLB_common
+
+.do_slb_bolted_Iseries:
+       mtcrf   0x80,r12
+       mfspr   r12,SPRG2
+       EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
+       EXCEPTION_PROLOG_ISERIES_2
+       b       .do_slb_bolted
+
+       STD_EXCEPTION_ISERIES(0x400, InstructionAccess, PACA_EXGEN)
+       STD_EXCEPTION_ISERIES(0x480, InstructionAccessSLB, PACA_EXGEN)
+       MASKABLE_EXCEPTION_ISERIES(0x500, HardwareInterrupt)
+       STD_EXCEPTION_ISERIES(0x600, Alignment, PACA_EXGEN)
+       STD_EXCEPTION_ISERIES(0x700, ProgramCheck, PACA_EXGEN)
+       STD_EXCEPTION_ISERIES(0x800, FPUnavailable, PACA_EXGEN)
+       MASKABLE_EXCEPTION_ISERIES(0x900, Decrementer)
+       STD_EXCEPTION_ISERIES(0xa00, Trap_0a, PACA_EXGEN)
+       STD_EXCEPTION_ISERIES(0xb00, Trap_0b, PACA_EXGEN)
+
+       .globl  SystemCall_Iseries
+SystemCall_Iseries:
+       mr      r9,r13
+       mfspr   r13,SPRG3
+       EXCEPTION_PROLOG_ISERIES_2
+       b       SystemCall_common
+
+       STD_EXCEPTION_ISERIES( 0xd00, SingleStep, PACA_EXGEN)
+       STD_EXCEPTION_ISERIES( 0xe00, Trap_0e, PACA_EXGEN)
+       STD_EXCEPTION_ISERIES( 0xf00, PerformanceMonitor, PACA_EXGEN)
 
        .globl SystemReset_Iseries
 SystemReset_Iseries:
        mfspr   r13,SPRG3               /* Get paca address */
-       mfmsr   r24
-       ori     r24,r24,MSR_RI
-       mtmsrd  r24                     /* RI on */
        lhz     r24,PACAPACAINDEX(r13)  /* Get processor # */
-       cmp   0,r24,0                 /* Are we processor 0? */
+       cmpwi   0,r24,0                 /* Are we processor 0? */
        beq     .__start_initialization_iSeries /* Start up the first processor */
        mfspr   r4,CTRLF
        li      r5,RUNLATCH             /* Turn off the run light */
@@ -527,7 +650,7 @@ SystemReset_Iseries:
        addi    r1,r3,THREAD_SIZE
        subi    r1,r1,STACK_FRAME_OVERHEAD
 
-       cmp   0,r23,0
+       cmpwi   0,r23,0
        beq     iseries_secondary_smp_loop      /* Loop until told to go */
 #ifdef SECONDARY_PROCESSORS
        bne     .__secondary_start              /* Loop until told to go */
@@ -552,28 +675,29 @@ iseries_secondary_smp_loop:
        b       1b                      /* If SMP not configured, secondaries
                                         * loop forever */
 
-       .globl HardwareInterrupt_Iseries_masked
-HardwareInterrupt_Iseries_masked:
-       b       maskable_exception_exit
-
        .globl Decrementer_Iseries_masked
 Decrementer_Iseries_masked:
-       li      r22,1
-       stb     r22,PACALPPACA+LPPACADECRINT(r20)
-       lwz     r22,PACADEFAULTDECR(r20)
-       mtspr   DEC,r22
-maskable_exception_exit:
-       mtcrf   0xff,r23                /* Restore regs and free exception frame */
-       ld      r22,EX_SRR0(r21)
-       ld      r23,EX_SRR1(r21)
-       mtspr   SRR0,r22
-       mtspr   SRR1,r23
-       ld      r22,EX_R22(r21)
-       ld      r23,EX_R23(r21)
-       mfspr   r21,SPRG1
-       mfspr   r20,SPRG2
+       li      r11,1
+       stb     r11,PACALPPACA+LPPACADECRINT(r13)
+       lwz     r12,PACADEFAULTDECR(r13)
+       mtspr   DEC,r12
+       /* fall through */
+
+       .globl HardwareInterrupt_Iseries_masked
+HardwareInterrupt_Iseries_masked:
+       mtcrf   0x80,r9         /* Restore regs */
+       ld      r11,LPPACA+LPPACASRR0(r13)
+       ld      r12,LPPACA+LPPACASRR1(r13)
+       mtspr   SRR0,r11
+       mtspr   SRR1,r12
+       ld      r9,PACA_EXGEN+EX_R9(r13)
+       ld      r10,PACA_EXGEN+EX_R10(r13)
+       ld      r11,PACA_EXGEN+EX_R11(r13)
+       ld      r12,PACA_EXGEN+EX_R12(r13)
+       ld      r13,PACA_EXGEN+EX_R13(r13)
        rfid
 #endif
+
 /*
  * Data area reserved for FWNMI option.
  */
@@ -587,10 +711,12 @@ fwnmi_data_area:
        . = 0x8000
        .globl SystemReset_FWNMI
 SystemReset_FWNMI:
-       EXCEPTION_PROLOG_PSERIES(0x100, SystemReset_common)
+       mtspr   SPRG1,r13               /* save r13 */
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, SystemReset_common)
        .globl MachineCheck_FWNMI
 MachineCheck_FWNMI:
-       EXCEPTION_PROLOG_PSERIES(0x200, MachineCheck_common)
+       mtspr   SPRG1,r13               /* save r13 */
+       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, MachineCheck_common)
 
        /*
         * Space for the initial segment table
@@ -609,8 +735,22 @@ __end_stab:
 /*** Common interrupt handlers ***/
 
        STD_EXCEPTION_COMMON( 0x100, SystemReset, .SystemResetException )
-       STD_EXCEPTION_COMMON( 0x200, MachineCheck, .MachineCheckException )
-       STD_EXCEPTION_COMMON( 0x900, Decrementer, .timer_interrupt )
+
+       /*
+        * Machine check is different because we use a different
+        * save area: PACA_EXMC instead of PACA_EXGEN.
+        */
+       .align  7
+       .globl MachineCheck_common
+MachineCheck_common:
+       EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
+       DISABLE_INTS
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .MachineCheckException
+       b       .ret_from_except
+
+       STD_EXCEPTION_COMMON_LITE(0x900, Decrementer, .timer_interrupt)
        STD_EXCEPTION_COMMON( 0xa00, Trap_0a, .UnknownException )
        STD_EXCEPTION_COMMON( 0xb00, Trap_0b, .UnknownException )
        STD_EXCEPTION_COMMON( 0xd00, SingleStep, .SingleStepException )
@@ -624,65 +764,56 @@ __end_stab:
 #endif
 
 /*
- * Here the exception frame is filled out and we have detected that
- * the kernel stack pointer is bad.  R23 contains the saved CR, r20
- * points to the paca, r21 points to the exception frame, and r22
- * contains the (bad) kernel stack pointer.
+ * Here we have detected that the kernel stack pointer is bad.
+ * R9 contains the saved CR, r13 points to the paca,
+ * r10 contains the (bad) kernel stack pointer,
+ * r11 and r12 contain the saved SRR0 and SRR1.
  * We switch to using the paca guard page as an emergency stack,
- * save the registers on there, and call kernel_bad_stack(),
- * which panics.
+ * save the registers there, and call kernel_bad_stack(), which panics.
  */
 bad_stack:
-       addi    r1,r20,8192-64-INT_FRAME_SIZE
-       std     r22,GPR1(r1)
-       std     r23,_CCR(r1)
-       ld      r22,EX_R20(r21)
-       std     r22,GPR20(r1)
-       ld      r23,EX_R21(r21)
-       std     r23,GPR21(r1)
-       ld      r22,EX_R22(r21)
-       std     r22,GPR22(r1)
-       ld      r23,EX_R23(r21)
-       std     r23,GPR23(r1)
-       ld      r23,EX_DAR(r21)
-       std     r23,_DAR(r1)
-       lwz     r22,EX_DSISR(r21)
-       std     r22,_DSISR(r1)
-       lwz     r23,EX_TRAP(r21)
-       std     r23,TRAP(r1)
-       ld      r22,EX_SRR0(r21)
-       ld      r23,EX_SRR1(r21)
-       std     r22,_NIP(r1)
-       std     r23,_MSR(r1)
-       addi    r21,r21,-EXC_FRAME_SIZE
-       std     r21,PACAEXCSP(r20)
-       mflr    r22
-       std     r22,_LINK(r1)
-       mfctr   r23
-       std     r23,_CTR(r1)
-       mfspr   r22,XER
-       std     r22,_XER(r1)
+       addi    r1,r13,8192-64-INT_FRAME_SIZE
+       std     r9,_CCR(r1)
+       std     r10,GPR1(r1)
+       std     r11,_NIP(r1)
+       std     r12,_MSR(r1)
+       mfspr   r11,DAR
+       mfspr   r12,DSISR
+       std     r11,_DAR(r1)
+       std     r12,_DSISR(r1)
+       mflr    r10
+       mfctr   r11
+       mfxer   r12
+       std     r10,_LINK(r1)
+       std     r11,_CTR(r1)
+       std     r12,_XER(r1)
        SAVE_GPR(0, r1)
-       SAVE_10GPRS(2, r1)
-       SAVE_8GPRS(12, r1)
-       SAVE_8GPRS(24, r1)
-       addi    r21,r1,INT_FRAME_SIZE
-       std     r21,0(r1)
-       li      r22,0
-       std     r22,0(r21)
-       ld      r2,PACATOC(r20)
-       mr      r13,r20
+       SAVE_GPR(2,r1)
+       SAVE_4GPRS(3,r1)
+       SAVE_2GPRS(7,r1)
+       SAVE_10GPRS(12,r1)
+       SAVE_10GPRS(22,r1)
+       addi    r11,r1,INT_FRAME_SIZE
+       std     r11,0(r1)
+       li      r12,0
+       std     r12,0(r11)
+       ld      r2,PACATOC(r13)
 1:     addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      .kernel_bad_stack
        b       1b
 
 /*
- * Return from an exception which is handled without calling
- * save_remaining_regs.  The caller is assumed to have done
- * EXCEPTION_PROLOG_COMMON.
+ * Return from an exception with minimal checks.
+ * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
+ * If interrupts have been enabled, or anything has been
+ * done that might have changed the scheduling status of
+ * any task or sent any task a signal, you should use
+ * ret_from_except or ret_from_except_lite instead of this.
  */
 fast_exception_return:
-       andi.   r3,r23,MSR_RI           /* check if RI is set */
+       ld      r12,_MSR(r1)
+       ld      r11,_NIP(r1)
+       andi.   r3,r12,MSR_RI           /* check if RI is set */
        beq-    unrecov_fer
        ld      r3,_CCR(r1)
        ld      r4,_LINK(r1)
@@ -691,244 +822,178 @@ fast_exception_return:
        mtcr    r3
        mtlr    r4
        mtctr   r5
-       mtspr   XER,r6
+       mtxer   r6
        REST_GPR(0, r1)
        REST_8GPRS(2, r1)
-       REST_4GPRS(10, r1)
 
-       mfmsr   r20
-       li      r21, MSR_RI
-       andc    r20,r20,r21
-       mtmsrd  r20,1
+       mfmsr   r10
+       clrrdi  r10,r10,2               /* clear RI (LE is 0 already) */
+       mtmsrd  r10,1
 
-       mtspr   SRR1,r23
-       mtspr   SRR0,r22
-       REST_4GPRS(20, r1)
+       mtspr   SRR1,r12
+       mtspr   SRR0,r11
+       REST_4GPRS(10, r1)
        ld      r1,GPR1(r1)
        rfid
 
 unrecov_fer:
-       li      r6,0x4000
-       li      r20,0
-       bl      .save_remaining_regs
+       bl      .save_nvgprs
 1:     addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      .unrecoverable_exception
        b       1b
 
 /*
- * Here r20 points to the PACA, r21 to the exception frame,
- * r23 contains the saved CR.
- * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
+ * Here r13 points to the paca, r9 contains the saved CR,
+ * SRR0 and SRR1 are saved in r11 and r12,
+ * r9 - r13 are saved in paca->exgen.
  */
+       .align  7
        .globl DataAccess_common
 DataAccess_common:
-BEGIN_FTR_SECTION
-       mfspr   r22,DAR
-       srdi    r22,r22,60
-       cmpi    0,r22,0xc
-
-       /* Segment fault on a bolted segment. Go off and map that segment. */
-       beq-    .do_stab_bolted
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-stab_bolted_user_return:
-       EXCEPTION_PROLOG_COMMON
-       ld      r3,_DSISR(r1)
-       andis.  r0,r3,0xa450            /* weird error? */
-       bne     1f                      /* if not, try to put a PTE */
-       andis.  r0,r3,0x0020            /* Is it a page table fault? */
-       rlwinm  r4,r3,32-23,29,29       /* DSISR_STORE -> _PAGE_RW */
-       ld      r3,_DAR(r1)             /* into the hash table */
-
-BEGIN_FTR_SECTION
-       beq+    2f                      /* If so handle it */
-       li      r4,0x300                /* Trap number */
-       bl      .do_stab_SI
-       b       1f
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-
-2:     li      r5,0x300
-       bl      .do_hash_page_DSI       /* Try to handle as hpte fault */
-1:
-       ld      r4,_DAR(r1)
-       ld      r5,_DSISR(r1)
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       DO_COPY_EE()
-       li      r6,0x300
-       bl      .save_remaining_regs
-       bl      .do_page_fault
-       b       .ret_from_except
-
+       mfspr   r10,DAR
+       std     r10,PACA_EXGEN+EX_DAR(r13)
+       mfspr   r10,DSISR
+       stw     r10,PACA_EXGEN+EX_DSISR(r13)
+       EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
+       ld      r3,PACA_EXGEN+EX_DAR(r13)
+       lwz     r4,PACA_EXGEN+EX_DSISR(r13)
+       li      r5,0x300
+       b       .do_hash_page           /* Try to handle as hpte fault */
+
+       .align  7
        .globl DataAccessSLB_common
 DataAccessSLB_common:
-       mfspr   r22,DAR
-       srdi    r22,r22,60
-       cmpi    0,r22,0xc
-
-       /* Segment fault on a bolted segment. Go off and map that segment. */
-       beq     .do_slb_bolted
-
-       EXCEPTION_PROLOG_COMMON
-       ld      r3,_DAR(r1)
-       li      r4,0x380                /* Exception vector  */
+       mfspr   r10,DAR
+       std     r10,PACA_EXGEN+EX_DAR(r13)
+       EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
+       ld      r3,PACA_EXGEN+EX_DAR(r13)
+       std     r3,_DAR(r1)
        bl      .slb_allocate
-       or.     r3,r3,r3                /* Check return code */
+       cmpdi   r3,0                    /* Check return code */
        beq     fast_exception_return   /* Return if we succeeded */
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       DO_COPY_EE()
-       ld      r4,_DAR(r1)
-       li      r6,0x380
        li      r5,0
-       bl      .save_remaining_regs
-       bl      .do_page_fault
-       b       .ret_from_except
+       std     r5,_DSISR(r1)
+       b       .handle_page_fault
 
+       .align  7
        .globl InstructionAccess_common
 InstructionAccess_common:
-       EXCEPTION_PROLOG_COMMON
-
-BEGIN_FTR_SECTION
-       andis.  r0,r23,0x0020           /* no ste found? */
-       beq+    2f
-       mr      r3,r22                  /* SRR0 at interrupt */
-       li      r4,0x400                /* Trap number       */
-       bl      .do_stab_SI
-       b       1f
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-
-2:     mr      r3,r22
+       EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
+       ld      r3,_NIP(r1)
+       andis.  r4,r12,0x5820
        li      r5,0x400
-       bl      .do_hash_page_ISI       /* Try to handle as hpte fault */
-1:
-       mr      r4,r22
-       rlwinm  r5,r23,0,4,4            /* We only care about PR in error_code */
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       DO_COPY_EE()
-       li      r6,0x400
-       bl      .save_remaining_regs
-       bl      .do_page_fault
-       b       .ret_from_except
+       b       .do_hash_page           /* Try to handle as hpte fault */
 
+       .align  7
        .globl InstructionAccessSLB_common
 InstructionAccessSLB_common:
-       EXCEPTION_PROLOG_COMMON
-       mr      r3,r22                  /* SRR0 = NIA        */
-       li      r4,0x480                /* Exception vector  */
+       EXCEPTION_PROLOG_COMMON(0x480, PACA_EXGEN)
+       ld      r3,_NIP(r1)             /* SRR0 = NIA   */
        bl      .slb_allocate
        or.     r3,r3,r3                /* Check return code */
        beq+    fast_exception_return   /* Return if we succeeded */
 
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       DO_COPY_EE()
-       mr      r4,r22                  /* SRR0 = NIA        */
-       li      r6,0x480
+       ld      r4,_NIP(r1)
        li      r5,0
-       bl      .save_remaining_regs
-       bl      .do_page_fault
-       b       .ret_from_except
+       std     r4,_DAR(r1)
+       std     r5,_DSISR(r1)
+       b      .handle_page_fault
 
+       .align  7
        .globl HardwareInterrupt_common
+       .globl HardwareInterrupt_entry
 HardwareInterrupt_common:
-       EXCEPTION_PROLOG_COMMON
+       EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
 HardwareInterrupt_entry:
+       DISABLE_INTS
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       li      r20,0
-       li      r6,0x500
-       bl      .save_remaining_regs
        bl      .do_IRQ
-       b       .ret_from_except
+       b       .ret_from_except_lite
 
+       .align  7
        .globl Alignment_common
 Alignment_common:
-       EXCEPTION_PROLOG_COMMON
+       mfspr   r10,DAR
+       std     r10,PACA_EXGEN+EX_DAR(r13)
+       mfspr   r10,DSISR
+       stw     r10,PACA_EXGEN+EX_DSISR(r13)
+       EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
+       ld      r3,PACA_EXGEN+EX_DAR(r13)
+       lwz     r4,PACA_EXGEN+EX_DSISR(r13)
+       std     r3,_DAR(r1)
+       std     r4,_DSISR(r1)
+       bl      .save_nvgprs
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       DO_COPY_EE()
-       li      r6,0x600
-       bl      .save_remaining_regs
+       ENABLE_INTS
        bl      .AlignmentException
        b       .ret_from_except
 
+       .align  7
        .globl ProgramCheck_common
 ProgramCheck_common:
-       EXCEPTION_PROLOG_COMMON
+       EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
+       bl      .save_nvgprs
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       DO_COPY_EE()
-       li      r6,0x700
-       bl      .save_remaining_regs
+       ENABLE_INTS
        bl      .ProgramCheckException
        b       .ret_from_except
 
+       .align  7
        .globl FPUnavailable_common
 FPUnavailable_common:
-       EXCEPTION_PROLOG_COMMON
+       EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
        bne     .load_up_fpu            /* if from user, just load it up */
+       bl      .save_nvgprs
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       DO_COPY_EE()
-       li      r6,0x800
-       bl      .save_remaining_regs
+       ENABLE_INTS
        bl      .KernelFPUnavailableException
        BUG_OPCODE
 
+       .align  7
        .globl AltivecUnavailable_common
 AltivecUnavailable_common:
-       EXCEPTION_PROLOG_COMMON
+       EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
 #ifdef CONFIG_ALTIVEC
-       bne     .load_up_altivec                /* if from user, just load it up */
+       bne     .load_up_altivec        /* if from user, just load it up */
 #endif
+       bl      .save_nvgprs
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       DO_COPY_EE()
-       li      r6,0xf20
-       bl      .save_remaining_regs
-#ifdef CONFIG_ALTIVEC
-       bl      .KernelAltivecUnavailableException
-#else
-       bl      .UnknownException
-#endif
-       BUG_OPCODE
+       ENABLE_INTS
+       bl      .AltivecUnavailableException
+       b       .ret_from_except
                
-       .globl SystemCall_common
-SystemCall_common:
-       EXCEPTION_PROLOG_COMMON
-#ifdef CONFIG_PPC_ISERIES
-       cmpi    0,r0,0x5555             /* Special syscall to handle pending */
-       bne+    1f                      /* interrupts */
-       andi.   r6,r23,MSR_PR           /* Only allowed from kernel */
-       beq+    HardwareInterrupt_entry
-1:
-#endif
-       DO_COPY_EE()
-       li      r6,0xC00
-       bl      .save_remaining_regs
-       bl      .DoSyscall
-       b       .ret_from_except
+/*
+ * Hash table stuff
+ */
+       .align  7
+_GLOBAL(do_hash_page)
+       std     r3,_DAR(r1)
+       std     r4,_DSISR(r1)
+
+       andis.  r0,r4,0xa450            /* weird error? */
+       bne-    .handle_page_fault      /* if not, try to insert a HPTE */
+BEGIN_FTR_SECTION
+       andis.  r0,r4,0x0020            /* Is it a segment table fault? */
+       bne-    .do_ste_alloc           /* If so handle it */
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
 
-_GLOBAL(do_hash_page_ISI)
-       li      r4,0
-_GLOBAL(do_hash_page_DSI)
        /*
         * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
         * accessing a userspace segment (even from the kernel). We assume
         * kernel addresses always have the high bit set.
         */
-       rotldi  r0,r3,15                /* Move high bit into MSR_PR position */
-       orc     r0,r23,r0
-       rlwimi  r4,r0,32-13,30,30       /* Insert into _PAGE_USER */
+       rlwinm  r4,r4,32-23,29,29       /* DSISR_STORE -> _PAGE_RW */
+       rotldi  r0,r3,15                /* Move high bit into MSR_PR posn */
+       orc     r0,r12,r0               /* MSR_PR | ~high_bit */
+       rlwimi  r4,r0,32-13,30,30       /* becomes _PAGE_USER access bit */
        ori     r4,r4,1                 /* add _PAGE_PRESENT */
 
-       mflr    r21                     /* Save LR in r21 */
-
-#ifdef DO_SOFT_DISABLE
        /*
-        * We hard enable here (but first soft disable) so that the hash_page
-        * code can spin on the hash_table_lock with problem on a shared
-        * processor.
+        * On iSeries, we soft-disable interrupts here, then
+        * hard-enable interrupts so that the hash_page code can spin on
+        * the hash_table_lock without problems on a shared processor.
         */
-       li      r0,0
-       stb     r0,PACAPROCENABLED(r20) /* Soft Disabled */
-
-       mfmsr   r0
-       ori     r0,r0,MSR_EE+MSR_RI
-       mtmsrd  r0                      /* Hard Enable, RI on */
-#endif
+       DISABLE_INTS
 
        /*
         * r3 contains the faulting address
@@ -937,184 +1002,159 @@ _GLOBAL(do_hash_page_DSI)
         *
         * at return r3 = 0 for success
         */
-
        bl      .hash_page              /* build HPTE if possible */
+       cmpdi   r3,0                    /* see if hash_page succeeded */
 
 #ifdef DO_SOFT_DISABLE
        /*
-        * Now go back to hard disabled.
+        * If we had interrupts soft-enabled at the point where the
+        * DSI/ISI occurred, and an interrupt came in during hash_page,
+        * handle it now.
+        * We jump to ret_from_except_lite rather than fast_exception_return
+        * because ret_from_except_lite will check for and handle pending
+        * interrupts if necessary.
         */
-       mfmsr   r0
-       li      r4,0
-       ori     r4,r4,MSR_EE+MSR_RI
-       andc    r0,r0,r4
-       mtmsrd  r0                      /* Hard Disable, RI off */
-
-       ld      r0,SOFTE(r1)
-       cmpdi   0,r0,0                  /* See if we will soft enable in */
-                                       /* save_remaining_regs */
-       beq     5f
-       CHECKANYINT(r4,r5)
-       bne-    HardwareInterrupt_entry /* Convert this DSI into an External */
-                                       /* to process interrupts which occurred */
-                                       /* during hash_page */
-5:
-       stb     r0,PACAPROCENABLED(r20) /* Restore soft enable/disable status */
+       beq     .ret_from_except_lite
+       /*
+        * hash_page couldn't handle it, set soft interrupt enable back
+        * to what it was before the trap.  Note that .local_irq_restore
+        * handles any interrupts pending at this point.
+        */
+       ld      r3,SOFTE(r1)
+       bl      .local_irq_restore
+       b       11f
+#else
+       beq+    fast_exception_return   /* Return from exception on success */
+       /* fall through */
 #endif
-       or.     r3,r3,r3                /* Check return code */
-       beq     fast_exception_return   /* Return from exception on success */
 
-       mtlr    r21                     /* restore LR */
-       blr                             /* Return to DSI or ISI on failure */
+/* Here we have a page fault that hash_page can't handle. */
+_GLOBAL(handle_page_fault)
+       ENABLE_INTS
+11:    ld      r4,_DAR(r1)
+       ld      r5,_DSISR(r1)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .do_page_fault
+       cmpdi   r3,0
+       beq+    .ret_from_except_lite
+       bl      .save_nvgprs
+       mr      r5,r3
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       lwz     r4,_DAR(r1)
+       bl      .bad_page_fault
+       b       .ret_from_except
+
+       /* here we have a segment miss */
+_GLOBAL(do_ste_alloc)
+       bl      .ste_allocate           /* try to insert stab entry */
+       cmpdi   r3,0
+       beq+    fast_exception_return
+       b       .handle_page_fault
 
 /*
- * r20 points to the PACA, r21 to the exception frame,
- * r23 contains the saved CR.
- * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r11 and r12 contain the saved SRR0 and SRR1.
+ * r9 - r13 are saved in paca->exslb.
  * We assume we aren't going to take any exceptions during this procedure.
+ * We assume (DAR >> 60) == 0xc.
  */
+       .align  7
 _GLOBAL(do_stab_bolted)
-       stw     r23,EX_CCR(r21) /* save CR in exc. frame */
+       stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
+       std     r11,PACA_EXSLB+EX_SRR0(r13)     /* save SRR0 in exc. frame */
 
-       mfspr   r22,DSISR
-       andis.  r22,r22,0x0020
-       beq-    stab_bolted_user_return
+       /* Hash to the primary group */
+       ld      r10,PACASTABVIRT(r13)
+       mfspr   r11,DAR
+       srdi    r11,r11,28
+       rldimi  r10,r11,7,52    /* r10 = first ste of the group */
 
+       /* Calculate VSID */
        /* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
-       mfspr   r21,DAR
-       rldicl  r20,r21,36,51
-       sldi    r20,r20,15
-       srdi    r21,r21,60
-       or      r20,r20,r21
+       rldic   r11,r11,15,36
+       ori     r11,r11,0xc
 
        /* VSID_RANDOMIZER */
-       li      r21,9
-       sldi    r21,r21,32
-       oris    r21,r21,58231
-       ori     r21,r21,39831
-
-       mulld   r20,r20,r21
-       clrldi  r20,r20,28      /* r20 = vsid */
+       li      r9,9
+       sldi    r9,r9,32
+       oris    r9,r9,58231
+       ori     r9,r9,39831
 
-       mfsprg  r21,3
-       ld      r21,PACASTABVIRT(r21)
-
-       /* Hash to the primary group */
-       mfspr   r22,DAR
-       rldicl  r22,r22,36,59
-       rldicr  r22,r22,7,56
-       or      r21,r21,r22     /* r21 = first ste of the group */
+       mulld   r9,r11,r9
+       rldic   r9,r9,12,16     /* r9 = vsid << 12 */
 
        /* Search the primary group for a free entry */
-       li      r22,0
-1:
-       ld      r23,0(r21)      /* Test valid bit of the current ste   */
-       rldicl  r23,r23,57,63
-       cmpwi   r23,0
-       bne     2f
-       li      r23,0
-       rldimi  r23,r20,12,0    /* Insert the new vsid value            */
-       std     r23,8(r21)      /* Put new entry back into the stab     */
-       eieio                  /* Order vsid update                    */
-       li      r23,0
-       mfspr   r20,DAR        /* Get the new esid                     */
-       rldicl  r20,r20,36,28  /* Permits a full 36b of ESID           */
-       rldimi  r23,r20,28,0    /* Insert the new esid value            */
-       ori     r23,r23,144      /* Turn on valid and kp                 */
-       std     r23,0(r21)      /* Put new entry back into the stab     */
-       sync                   /* Order the update                     */
-       b       3f
-2:
-       addi    r22,r22,1
-       addi    r21,r21,16
-       cmpldi  r22,7
-       ble     1b
+1:     ld      r11,0(r10)      /* Test valid bit of the current ste    */
+       andi.   r11,r11,0x80
+       beq     2f
+       addi    r10,r10,16
+       andi.   r11,r10,0x70
+       bne     1b
 
        /* Stick for only searching the primary group for now.          */
        /* At least for now, we use a very simple random castout scheme */
        /* Use the TB as a random number ;  OR in 1 to avoid entry 0    */
-       mftb    r22
-       andi.   r22,r22,7
-       ori     r22,r22,1
-       sldi    r22,r22,4
+       mftb    r11
+       rldic   r11,r11,4,57    /* r11 = (r11 << 4) & 0x70 */
+       ori     r11,r11,0x10
 
-       /* r21 currently points to and ste one past the group of interest */
+       /* r10 currently points to an ste one past the group of interest */
        /* make it point to the randomly selected entry                   */
-       subi    r21,r21,128
-       or      r21,r21,r22      /* r21 is the entry to invalidate        */
+       subi    r10,r10,128
+       or      r10,r10,r11     /* r10 is the entry to invalidate       */
 
        isync                    /* mark the entry invalid                */
-       ld      r23,0(r21)
-       li      r22,-129
-       and     r23,r23,r22
-       std     r23,0(r21)
+       ld      r11,0(r10)
+       rldicl  r11,r11,56,1    /* clear the valid bit */
+       rotldi  r11,r11,8
+       std     r11,0(r10)
        sync
 
-       li      r23,0
-       rldimi  r23,r20,12,0
-       std     r23,8(r21)
+       clrrdi  r11,r11,28      /* Get the esid part of the ste         */
+       slbie   r11
+
+2:     std     r9,8(r10)       /* Store the vsid part of the ste       */
        eieio
 
-       ld      r22,0(r21)      /* Get the esid part of the ste         */
-       li      r23,0
-       mfspr   r20,DAR         /* Get the new esid                     */
-       rldicl  r20,r20,36,28   /* Permits a full 32b of ESID           */
-       rldimi  r23,r20,28,0    /* Insert the new esid value            */
-       ori     r23,r23,144     /* Turn on valid and kp                 */
-       std     r23,0(r21)      /* Put new entry back into the stab     */
-
-       rldicl  r22,r22,36,28
-       rldicr  r22,r22,28,35
-       slbie   r22
+       mfspr   r11,DAR         /* Get the new esid                     */
+       clrrdi  r11,r11,28      /* Permits a full 32b of ESID           */
+       ori     r11,r11,0x90    /* Turn on valid and kp                 */
+       std     r11,0(r10)      /* Put new entry back into the stab     */
+
        sync
 
-3:
        /* All done -- return from exception. */
-       mfsprg  r20,3                   /* Load the PACA pointer  */
-       ld      r21,PACAEXCSP(r20)      /* Get the exception frame pointer */
-       addi    r21,r21,EXC_FRAME_SIZE
-       lwz     r23,EX_CCR(r21)         /* get saved CR */
-
-       ld      r22,EX_SRR1(r21)
-       andi.   r22,r22,MSR_RI
-       beq-    unrecov_stab
-
-       /* note that this is almost identical to maskable_exception_exit */
-       mtcr    r23                     /* restore CR */
-
-       mfmsr   r22
-       li      r23, MSR_RI
-       andc    r22,r22,r23
-       mtmsrd  r22,1
-
-       ld      r22,EX_SRR0(r21)        /* Get SRR0 from exc. frame */
-       ld      r23,EX_SRR1(r21)        /* Get SRR1 from exc. frame */
-       mtspr   SRR0,r22
-       mtspr   SRR1,r23
-       ld      r22,EX_R22(r21)         /* restore r22 and r23 */
-       ld      r23,EX_R23(r21)
-       mfspr   r20,SPRG2
-       mfspr   r21,SPRG1
-       rfid
+       lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
+       ld      r11,PACA_EXSLB+EX_SRR0(r13)     /* get saved SRR0 */
 
-unrecov_stab:
-       EXCEPTION_PROLOG_COMMON
-       li      r6,0x4100
-       li      r20,0
-       bl      .save_remaining_regs
-1:     addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .unrecoverable_exception
-       b       1b
+       andi.   r10,r12,MSR_RI
+       beq-    unrecov_slb
+
+       mtcrf   0x80,r9                 /* restore CR */
+
+       mfmsr   r10
+       clrrdi  r10,r10,2
+       mtmsrd  r10,1
+
+       mtspr   SRR0,r11
+       mtspr   SRR1,r12
+       ld      r9,PACA_EXSLB+EX_R9(r13)
+       ld      r10,PACA_EXSLB+EX_R10(r13)
+       ld      r11,PACA_EXSLB+EX_R11(r13)
+       ld      r12,PACA_EXSLB+EX_R12(r13)
+       ld      r13,PACA_EXSLB+EX_R13(r13)
+       rfid
 
 /*
- * r20 points to the PACA, r21 to the exception frame,
- * r23 contains the saved CR.
- * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r11 and r12 contain the saved SRR0 and SRR1.
+ * r9 - r13 are saved in paca->exslb.
  * We assume we aren't going to take any exceptions during this procedure.
  */
 /* XXX note fix masking in get_kernel_vsid to match */
 _GLOBAL(do_slb_bolted)
-       stw     r23,EX_CCR(r21)         /* save CR in exc. frame */
+       stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
+       std     r11,PACA_EXSLB+EX_SRR0(r13)     /* save SRR0 in exc. frame */
 
        /*
         * We take the next entry, round robin. Previously we tried
@@ -1122,15 +1162,15 @@ _GLOBAL(do_slb_bolted)
         * we dont have any LRU information to help us choose a slot.
         */
 
-       /* r20 = paca */
-1:     ld      r22,PACASTABRR(r20)
-       addi    r21,r22,1
-       cmpdi   r21,SLB_NUM_ENTRIES
+       /* r13 = paca */
+1:     ld      r10,PACASTABRR(r13)
+       addi    r9,r10,1
+       cmpdi   r9,SLB_NUM_ENTRIES
        blt+    2f
-       li      r21,2                   /* dont touch slot 0 or 1 */
-2:     std     r21,PACASTABRR(r20)
+       li      r9,2                    /* dont touch slot 0 or 1 */
+2:     std     r9,PACASTABRR(r13)
 
-       /* r20 = paca, r22 = entry */
+       /* r13 = paca, r10 = entry */
 
        /* 
         * Never cast out the segment for our kernel stack. Since we
@@ -1139,8 +1179,8 @@ _GLOBAL(do_slb_bolted)
         * which gets invalidated due to a tlbie from another cpu at a
         * non recoverable point (after setting srr0/1) - Anton
         */
-       slbmfee r21,r22
-       srdi    r21,r21,27
+       slbmfee r9,r10
+       srdi    r9,r9,27
        /*
         * Use paca->ksave as the value of the kernel stack pointer,
         * because this is valid at all times.
@@ -1150,74 +1190,71 @@ _GLOBAL(do_slb_bolted)
         * switch (between updating r1 and updating paca->ksave),
         * we check against both r1 and paca->ksave.
         */
-       srdi    r23,r1,27
-       ori     r23,r23,1
-       cmpd    r23,r21
+       srdi    r11,r1,27
+       ori     r11,r11,1
+       cmpd    r11,r9
        beq-    1b
-       ld      r23,PACAKSAVE(r20)
-       srdi    r23,r23,27
-       ori     r23,r23,1
-       cmpd    r23,r21
+       ld      r11,PACAKSAVE(r13)
+       srdi    r11,r11,27
+       ori     r11,r11,1
+       cmpd    r11,r9
        beq-    1b
 
-       /* r20 = paca, r22 = entry */
+       /* r13 = paca, r10 = entry */
 
        /* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
-       mfspr   r21,DAR
-       rldicl  r23,r21,36,51
-       sldi    r23,r23,15
-       srdi    r21,r21,60
-       or      r23,r23,r21
+       mfspr   r9,DAR
+       rldicl  r11,r9,36,51
+       sldi    r11,r11,15
+       srdi    r9,r9,60
+       or      r11,r11,r9
 
        /* VSID_RANDOMIZER */
-       li      r21,9
-       sldi    r21,r21,32
-       oris    r21,r21,58231
-       ori     r21,r21,39831
+       li      r9,9
+       sldi    r9,r9,32
+       oris    r9,r9,58231
+       ori     r9,r9,39831
 
        /* vsid = (ordinal * VSID_RANDOMIZER) & VSID_MASK */
-       mulld   r23,r23,r21
-       clrldi  r23,r23,28
+       mulld   r11,r11,r9
+       clrldi  r11,r11,28
 
-       /* r20 = paca, r22 = entry, r23 = vsid */
+       /* r13 = paca, r10 = entry, r11 = vsid */
 
        /* Put together slb word1 */
-       sldi    r23,r23,12
+       sldi    r11,r11,12
 
 BEGIN_FTR_SECTION
        /* set kp and c bits */
-       ori     r23,r23,0x480
+       ori     r11,r11,0x480
 END_FTR_SECTION_IFCLR(CPU_FTR_16M_PAGE)
 BEGIN_FTR_SECTION
        /* set kp, l and c bits */
-       ori     r23,r23,0x580
+       ori     r11,r11,0x580
 END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
 
-       /* r20 = paca, r22 = entry, r23 = slb word1 */
+       /* r13 = paca, r10 = entry, r11 = slb word1 */
 
        /* Put together slb word0 */
-       mfspr   r21,DAR
-       rldicr  r21,r21,0,35    /* get the new esid */
-       oris    r21,r21,2048    /* set valid bit */
-       rldimi  r21,r22,0,52    /* insert entry */
+       mfspr   r9,DAR
+       clrrdi  r9,r9,28        /* get the new esid */
+       oris    r9,r9,0x800     /* set valid bit */
+       rldimi  r9,r10,0,52     /* insert entry */
 
-       /* r20 = paca, r21 = slb word0, r23 = slb word1 */
+       /* r13 = paca, r9 = slb word0, r11 = slb word1 */
 
        /* 
         * No need for an isync before or after this slbmte. The exception
         * we enter with and the rfid we exit with are context synchronizing .
         */
-       slbmte  r23,r21
+       slbmte  r11,r9
 
        /* All done -- return from exception. */
-       ld      r21,PACAEXCSP(r20)      /* Get the exception frame pointer */
-       addi    r21,r21,EXC_FRAME_SIZE
-       lwz     r23,EX_CCR(r21)         /* get saved CR */
-       /* note that this is almost identical to maskable_exception_exit */
+       lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
+       ld      r11,PACA_EXSLB+EX_SRR0(r13)     /* get saved SRR0 */
 
-       ld      r22,EX_SRR1(r21)
-       andi.   r22,r22,MSR_RI
-       beq-    unrecov_stab
+       andi.   r10,r12,MSR_RI  /* check for unrecoverable exception */
+       beq-    unrecov_slb
 
        /*
         * Until everyone updates binutils hardwire the POWER4 optimised
@@ -1226,124 +1263,32 @@ END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
 #if 0
        .machine        push
        .machine        "power4"
-       mtcrf   0x80,r23
+       mtcrf   0x80,r9
        .machine        pop
 #else
-       .long 0x7ef80120
+       .long 0x7d380120
 #endif
 
-       mfmsr   r22
-       li      r23, MSR_RI
-       andc    r22,r22,r23
-       mtmsrd  r22,1
-
-       ld      r22,EX_SRR0(r21)        /* Get SRR0 from exc. frame */
-       ld      r23,EX_SRR1(r21)        /* Get SRR1 from exc. frame */
-       mtspr   SRR0,r22
-       mtspr   SRR1,r23
-       ld      r22,EX_R22(r21)         /* restore r22 and r23 */
-       ld      r23,EX_R23(r21)
-       ld      r20,EX_R20(r21)
-       mfspr   r21,SPRG1
+       mfmsr   r10
+       clrrdi  r10,r10,2
+       mtmsrd  r10,1
+
+       mtspr   SRR0,r11
+       mtspr   SRR1,r12
+       ld      r9,PACA_EXSLB+EX_R9(r13)
+       ld      r10,PACA_EXSLB+EX_R10(r13)
+       ld      r11,PACA_EXSLB+EX_R11(r13)
+       ld      r12,PACA_EXSLB+EX_R12(r13)
+       ld      r13,PACA_EXSLB+EX_R13(r13)
        rfid
 
-_GLOBAL(do_stab_SI)
-       mflr    r21                     /* Save LR in r21 */
-
-       /*
-        * r3 contains the faulting address
-        * r4 contains the required access permissions
-        *
-        * at return r3 = 0 for success
-        */
-
-       bl      .ste_allocate           /* build STE if possible */
-       or.     r3,r3,r3                /* Check return code */
-       beq     fast_exception_return   /* Return from exception on success */
-       mtlr    r21                     /* restore LR */
-       blr                             /* Return to DSI or ISI on failure */
-
-/*
- * This code finishes saving the registers to the exception frame.
- * Address translation is already on.
- */
-_GLOBAL(save_remaining_regs)
-       /*
-        * Save the rest of the registers into the pt_regs structure
-        */
-       std     r22,_NIP(r1)
-       std     r23,_MSR(r1)
-       std     r6,TRAP(r1)
-       ld      r6,GPR6(r1)
-       SAVE_2GPRS(14, r1)
-       SAVE_4GPRS(16, r1)
-       SAVE_8GPRS(24, r1)
-
-       /* Set the marker value "regshere" just before the reg values */
-       SET_REG_TO_CONST(r22, 0x7265677368657265)
-       std     r22,STACK_FRAME_OVERHEAD-16(r1)
-
-       /*
-        * Clear the RESULT field
-        */
-       li      r22,0
-       std     r22,RESULT(r1)
-
-       /*
-        * Test if from user state; result will be tested later
-        */
-       andi.   r23,r23,MSR_PR          /* Set CR for later branch */
-
-       /*
-        * Indicate that r1 contains the kernel stack and
-        * get the Kernel TOC pointer from the paca
-        */
-       ld      r2,PACATOC(r13)         /* Get Kernel TOC pointer */
-
-       /*
-        * If from user state, update THREAD.regs
-        */
-       beq     2f                      /* Modify THREAD.regs if from user */
-       addi    r23,r1,STACK_FRAME_OVERHEAD
-       ld      r22, PACACURRENT(r13)
-       std     r23,THREAD+PT_REGS(r22)
-2:
-       SET_REG_TO_CONST(r22, MSR_KERNEL)
-
-#ifdef DO_SOFT_DISABLE
-       stb     r20,PACAPROCENABLED(r13) /* possibly soft enable */
-       ori     r22,r22,MSR_EE          /* always hard enable */
-#else
-       rldimi  r22,r20,15,48           /* Insert desired EE value */
-#endif
-
-       mtmsrd  r22,1
-       blr
-
-/*
- * Kernel profiling with soft disable on iSeries
- */
-do_profile:
-       ld      r22,8(r21)              /* Get SRR1 */
-       andi.   r22,r22,MSR_PR          /* Test if in kernel */
-       bnelr                           /* return if not in kernel */
-       ld      r22,0(r21)              /* Get SRR0 */
-       ld      r25,PACAPROFSTEXT(r20)  /* _stext */
-       subf    r22,r25,r22             /* offset into kernel */
-       lwz     r25,PACAPROFSHIFT(r20)
-       srd     r22,r22,r25
-       lwz     r25,PACAPROFLEN(r20)    /* length of profile table (-1) */
-       cmp     0,r22,r25               /* off end? */
-       ble     1f
-       mr      r22,r25                 /* force into last entry */
-1:     sldi    r22,r22,2               /* convert to offset into buffer */
-       ld      r25,PACAPROFBUFFER(r20) /* profile buffer */
-       add     r25,r25,r22
-2:     lwarx   r22,0,r25               /* atomically increment */
-       addi    r22,r22,1
-       stwcx.  r22,0,r25
-       bne-    2b
-       blr
+unrecov_slb:
+       EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
+       DISABLE_INTS
+       bl      .save_nvgprs
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .unrecoverable_exception
+       b       1b
 
 
 /*
@@ -1375,7 +1320,7 @@ _GLOBAL(pseries_secondary_smp_init)
         addi    r1,r1,0x1000
         subi    r1,r1,STACK_FRAME_OVERHEAD
 
-       cmp   0,r23,0
+       cmpwi   0,r23,0
 #ifdef CONFIG_SMP
 #ifdef SECONDARY_PROCESSORS
        bne     .__secondary_start
@@ -1594,9 +1539,9 @@ _STATIC(load_up_fpu)
  *
  */
 #ifndef CONFIG_SMP
-       LOADBASE(r3,last_task_used_math)
-       ld      r4,last_task_used_math@l(r3)
-       cmp   0,r4,0
+       ld      r3,last_task_used_math@got(r2)
+       ld      r4,0(r3)
+       cmpdi   0,r4,0
        beq     1f
        /* Save FP state to last_task_used_math's THREAD struct */
        addi    r4,r4,THREAD
@@ -1606,8 +1551,8 @@ _STATIC(load_up_fpu)
        /* Disable FP for last_task_used_math */
        ld      r5,PT_REGS(r4)
        ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-       li      r20,MSR_FP|MSR_FE0|MSR_FE1
-       andc    r4,r4,r20
+       li      r6,MSR_FP|MSR_FE0|MSR_FE1
+       andc    r4,r4,r6
        std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 1:
 #endif /* CONFIG_SMP */
@@ -1615,15 +1560,16 @@ _STATIC(load_up_fpu)
        ld      r4,PACACURRENT(r13)
        addi    r5,r4,THREAD            /* Get THREAD */
        ld      r4,THREAD_FPEXC_MODE(r5)
-       ori     r23,r23,MSR_FP
-       or      r23,r23,r4
+       ori     r12,r12,MSR_FP
+       or      r12,r12,r4
+       std     r12,_MSR(r1)
        lfd     fr0,THREAD_FPSCR(r5)
        mtfsf   0xff,fr0
        REST_32FPRS(0, r5)
 #ifndef CONFIG_SMP
        /* Update last_task_used_math to 'current' */
        subi    r4,r5,THREAD            /* Back to 'current' */
-       std     r4,last_task_used_math@l(r3)
+       std     r4,0(r3)
 #endif /* CONFIG_SMP */
        /* restore registers and return */
        b       fast_exception_return
@@ -1651,11 +1597,11 @@ _GLOBAL(giveup_fpu)
        ori     r5,r5,MSR_FP
        mtmsrd  r5                      /* enable use of fpu now */
        isync
-       cmp   0,r3,0
+       cmpdi   0,r3,0
        beqlr-                          /* if no previous owner, done */
        addi    r3,r3,THREAD            /* want THREAD of task */
        ld      r5,PT_REGS(r3)
-       cmp   0,r5,0
+       cmpdi   0,r5,0
        SAVE_32FPRS(0, r3)
        mffs    fr0
        stfd    fr0,THREAD_FPSCR(r3)
@@ -1667,8 +1613,8 @@ _GLOBAL(giveup_fpu)
 1:
 #ifndef CONFIG_SMP
        li      r5,0
-       LOADBASE(r4,last_task_used_math)
-       std     r5,last_task_used_math@l(r4)
+       ld      r4,last_task_used_math@got(r2)
+       std     r5,0(r4)
 #endif /* CONFIG_SMP */
        blr
 
@@ -1699,9 +1645,9 @@ _STATIC(load_up_altivec)
  * avoid saving all of the VREGs here...
  */
 #ifndef CONFIG_SMP
-       LOADBASE(r3,last_task_used_altivec)
-       ld      r4,last_task_used_altivec@l(r3)
-       cmp   0,r4,0
+       ld      r3,last_task_used_altivec@got(r2)
+       ld      r4,0(r3)
+       cmpdi   0,r4,0
        beq     1f
        /* Save VMX state to last_task_used_altivec's THREAD struct */
        addi    r4,r4,THREAD
@@ -1712,8 +1658,8 @@ _STATIC(load_up_altivec)
        /* Disable VMX for last_task_used_altivec */
        ld      r5,PT_REGS(r4)
        ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-       lis     r20,MSR_VEC@h
-       andc    r4,r4,r20
+       lis     r6,MSR_VEC@h
+       andc    r4,r4,r6
        std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 1:
 #endif /* CONFIG_SMP */
@@ -1723,7 +1669,7 @@ _STATIC(load_up_altivec)
         * all 1's
         */
        mfspr   r4,SPRN_VRSAVE
-       cmp   0,r4,0
+       cmpdi   0,r4,0
        bne+    1f
        li      r4,-1
        mtspr   SPRN_VRSAVE,r4
@@ -1731,7 +1677,8 @@ _STATIC(load_up_altivec)
        /* enable use of VMX after return */
        ld      r4,PACACURRENT(r13)
        addi    r5,r4,THREAD            /* Get THREAD */
-       oris    r23,r23,MSR_VEC@h
+       oris    r12,r12,MSR_VEC@h
+       std     r12,_MSR(r1)
        li      r4,1
        li      r10,THREAD_VSCR
        stw     r4,THREAD_USED_VR(r5)
@@ -1740,7 +1687,7 @@ _STATIC(load_up_altivec)
 #ifndef CONFIG_SMP
        /* Update last_task_used_math to 'current' */
        subi    r4,r5,THREAD            /* Back to 'current' */
-       std     r4,last_task_used_altivec@l(r3)
+       std     r4,0(r3)
 #endif /* CONFIG_SMP */
        /* restore registers and return */
        b       fast_exception_return
@@ -1768,11 +1715,11 @@ _GLOBAL(giveup_altivec)
        oris    r5,r5,MSR_VEC@h
        mtmsrd  r5                      /* enable use of VMX now */
        isync
-       cmp   0,r3,0
+       cmpdi   0,r3,0
        beqlr-                          /* if no previous owner, done */
        addi    r3,r3,THREAD            /* want THREAD of task */
        ld      r5,PT_REGS(r3)
-       cmp   0,r5,0
+       cmpdi   0,r5,0
        SAVE_32VRS(0,r4,r3)
        mfvscr  vr0
        li      r4,THREAD_VSCR
@@ -1785,8 +1732,8 @@ _GLOBAL(giveup_altivec)
 1:
 #ifndef CONFIG_SMP
        li      r5,0
-       LOADBASE(r4,last_task_used_altivec)
-       std     r5,last_task_used_altivec@l(r4)
+       ld      r4,last_task_used_altivec@got(r2)
+       std     r5,0(r4)
 #endif /* CONFIG_SMP */
        blr
 
@@ -1885,8 +1832,9 @@ _GLOBAL(__secondary_start)
        LOADADDR(r3,current_set)
        sldi    r28,r24,3               /* get current_set[cpu#] */
        ldx     r1,r3,r28
-       addi    r1,r1,THREAD_SIZE
-       subi    r1,r1,STACK_FRAME_OVERHEAD
+       addi    r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+       li      r0,0
+       std     r0,0(r1)
        std     r1,PACAKSAVE(r13)
 
        ld      r3,PACASTABREAL(r13)    /* get raddr of segment table       */
@@ -1943,7 +1891,7 @@ _GLOBAL(start_secondary_prolog)
 #endif
 
 /*
- * This subroutine clobbers r11, r12 and the LR
+ * This subroutine clobbers r11 and r12
  */
 _GLOBAL(enable_64b_mode)
        mfmsr   r11                      /* grab the current MSR */
@@ -2144,7 +2092,6 @@ _STATIC(start_here_common)
        std     r4,PACACURRENT(r13)
 
        std     r2,PACATOC(r13)
-       li      r5,0
        std     r1,PACAKSAVE(r13)
 
        /* Restore the parms passed in from the bootloader. */
index 3f17d5e..a354980 100644 (file)
@@ -357,15 +357,14 @@ void __init iSeries_init(unsigned long r3, unsigned long r4, unsigned long r5,
        HvCallEvent_dmaToSp(cmd_line, 2 * 64* 1024, 256,
                        HvLpDma_Direction_RemoteToLocal);
 
-       p = q = cmd_line + 255;
-       while (p > cmd_line) {
-               if ((*p == 0) || (*p == ' ') || (*p == '\n'))
-                       --p;
-               else
+       p = cmd_line;
+       q = cmd_line + 255;
+       while( p < q ) {
+               if (!*p || *p == '\n')
                        break;
+               ++p;
        }
-       if (p < q)
-               *(p + 1) = 0;
+       *p = 0;
 
         if (strstr(cmd_line, "dprofile=")) {
                 for (q = cmd_line; (p = strstr(q, "dprofile=")) != 0; ) {
index 38cb7ae..941043a 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/init.h>
 #include <linux/init_task.h>
 #include <linux/fs.h>
+#include <linux/mqueue.h>
 #include <asm/uaccess.h>
 
 static struct fs_struct init_fs = INIT_FS;
index 5d48ce8..3ac36a5 100644 (file)
@@ -25,33 +25,26 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
 {
        int len = count;
        char *p;
-    
+
+       if (off) {
+               *eof = 1;
+               return 0;
+       }
+
        len = mf_getCmdLine(page, &len, (u64)data);
    
-       p = page + len - 1;
-       while (p > page) {
-               if ((*p == 0) || (*p == ' '))
-                       --p;
-               else
+       p = page;
+       while (len < (count - 1)) {
+               if (!*p || *p == '\n')
                        break;
+               p++;
+               len++;
        }
-       if (*p != '\n') {
-               ++p;
-               *p = '\n';
-       }
-       ++p;
+       *p = '\n';
+       p++;
        *p = 0;
-       len = p - page;
-    
-       len -= off;                     
-       if (len < count) {              
-               *eof = 1;               
-               if (len <= 0)           
-                       return 0;       
-       } else                          
-               len = count;            
-       *start = page + off;            
-       return len;                     
+
+       return p - page;
 }
 
 #if 0
index 3cdd1a0..e0417ed 100644 (file)
@@ -85,16 +85,17 @@ _GLOBAL(local_irq_restore)
        cmpw    0,r3,r5
        beqlr
        /* are we enabling interrupts? */
-       cmp   0,r3,0
+       cmpdi   0,r3,0
        stb     r3,PACAPROCENABLED(r13)
        beqlr
        /* Check pending interrupts */
        /*   A decrementer, IPI or PMC interrupt may have occurred
         *   while we were in the hypervisor (which enables) */
-       CHECKANYINT(r4,r5)
+       ld      r4,PACALPPACA+LPPACAANYINT(r13)
+       cmpdi   r4,0
        beqlr
 
-       /* 
+       /*
         * Handle pending interrupts in interrupt context
         */
        li      r0,0x5555
@@ -608,7 +609,7 @@ _GLOBAL(kernel_thread)
 _GLOBAL(sys_call_table32)
        .llong .sys_restart_syscall     /* 0 */
        .llong .sys_exit
-       .llong .sys_fork
+       .llong .ppc_fork
        .llong .sys_read
        .llong .sys_write
        .llong .sys32_open              /* 5 */
@@ -678,7 +679,7 @@ _GLOBAL(sys_call_table32)
        .llong .sys32_ssetmask
        .llong .sys_setreuid            /* 70 */
        .llong .sys_setregid
-       .llong .sys32_sigsuspend
+       .llong .ppc32_sigsuspend
        .llong .compat_sys_sigpending
        .llong .sys32_sethostname
        .llong .compat_sys_setrlimit            /* 75 */
@@ -726,7 +727,7 @@ _GLOBAL(sys_call_table32)
        .llong .sys32_ipc
        .llong .sys_fsync
        .llong .ppc32_sigreturn
-       .llong .sys_clone               /* 120 */
+       .llong .ppc_clone               /* 120 */
        .llong .sys32_setdomainname
        .llong .ppc64_newuname
        .llong .sys_ni_syscall          /* old modify_ldt syscall */
@@ -784,7 +785,7 @@ _GLOBAL(sys_call_table32)
        .llong .sys32_rt_sigpending     /* 175 */
        .llong .sys32_rt_sigtimedwait
        .llong .sys32_rt_sigqueueinfo
-       .llong .sys32_rt_sigsuspend
+       .llong .ppc32_rt_sigsuspend
        .llong .sys32_pread64
        .llong .sys32_pwrite64          /* 180 */
        .llong .sys_chown
@@ -795,7 +796,7 @@ _GLOBAL(sys_call_table32)
        .llong .sys32_sendfile
        .llong .sys_ni_syscall          /* reserved for streams1 */
        .llong .sys_ni_syscall          /* reserved for streams2 */
-       .llong .sys_vfork
+       .llong .ppc_vfork
        .llong .compat_sys_getrlimit            /* 190 */
        .llong .sys32_readahead
        .llong .sys32_mmap2
@@ -888,7 +889,7 @@ _GLOBAL(sys_call_table32)
 _GLOBAL(sys_call_table)
        .llong .sys_restart_syscall     /* 0 */
        .llong .sys_exit
-       .llong .sys_fork
+       .llong .ppc_fork
        .llong .sys_read
        .llong .sys_write
        .llong .sys_open                /* 5 */
@@ -1006,7 +1007,7 @@ _GLOBAL(sys_call_table)
        .llong .sys_ipc
        .llong .sys_fsync
        .llong .sys_ni_syscall
-       .llong .sys_clone               /* 120 */
+       .llong .ppc_clone               /* 120 */
        .llong .sys_setdomainname
        .llong .ppc64_newuname
        .llong .sys_ni_syscall          /* old modify_ldt syscall */
@@ -1064,7 +1065,7 @@ _GLOBAL(sys_call_table)
        .llong .sys_rt_sigpending       /* 175 */
        .llong .sys_rt_sigtimedwait
        .llong .sys_rt_sigqueueinfo
-       .llong .sys_rt_sigsuspend
+       .llong .ppc64_rt_sigsuspend
        .llong .sys_pread64
        .llong .sys_pwrite64            /* 180 */
        .llong .sys_chown
@@ -1075,7 +1076,7 @@ _GLOBAL(sys_call_table)
        .llong .sys_sendfile64
        .llong .sys_ni_syscall          /* reserved for streams1 */
        .llong .sys_ni_syscall          /* reserved for streams2 */
-       .llong .sys_vfork
+       .llong .ppc_vfork
        .llong .sys_getrlimit           /* 190 */
        .llong .sys_readahead
        .llong .sys_ni_syscall          /* 32bit only mmap2 */
index d283f48..2cf631b 100644 (file)
@@ -62,8 +62,6 @@ struct systemcfg *systemcfg;
                .xDesc = 0xd397d9e2,    /* "LpRS" */                        \
                .xSize = sizeof(struct ItLpRegSave)                         \
        },                                                                  \
-       .exception_sp =                                                     \
-               (&paca[number].exception_stack[0]) - EXC_FRAME_SIZE,        \
 }
 
 struct paca_struct paca[] __page_aligned = {
index dbc9484..c059a76 100644 (file)
@@ -343,6 +343,10 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
                PMAC_TYPE_POWERMAC_G5,          g5_features,
                0,
        },
+       {       "RackMac3,1",                   "XServe G5",
+               PMAC_TYPE_POWERMAC_G5,          g5_features,
+               0,
+       },
 };
 
 /*
index be153b9..5acc567 100644 (file)
@@ -65,8 +65,43 @@ struct mm_struct ioremap_mm = {
        .page_table_lock = SPIN_LOCK_UNLOCKED,
 };
 
+/*
+ * Make sure the floating-point register state in the
+ * the thread_struct is up to date for task tsk.
+ */
+void flush_fp_to_thread(struct task_struct *tsk)
+{
+       if (tsk->thread.regs) {
+               /*
+                * We need to disable preemption here because if we didn't,
+                * another process could get scheduled after the regs->msr
+                * test but before we have finished saving the FP registers
+                * to the thread_struct.  That process could take over the
+                * FPU, and then when we get scheduled again we would store
+                * bogus values for the remaining FP registers.
+                */
+               preempt_disable();
+               if (tsk->thread.regs->msr & MSR_FP) {
+#ifdef CONFIG_SMP
+                       /*
+                        * This should only ever be called for current or
+                        * for a stopped child process.  Since we save away
+                        * the FP register state on context switch on SMP,
+                        * there is something wrong if a stopped child appears
+                        * to still have its FP state in the CPU registers.
+                        */
+                       BUG_ON(tsk != current);
+#endif
+                       giveup_fpu(current);
+               }
+               preempt_enable();
+       }
+}
+
 void enable_kernel_fp(void)
 {
+       WARN_ON(preemptible());
+
 #ifdef CONFIG_SMP
        if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
                giveup_fpu(current);
@@ -80,12 +115,9 @@ EXPORT_SYMBOL(enable_kernel_fp);
 
 int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
 {
-       struct pt_regs *regs = tsk->thread.regs;
-
-       if (!regs)
+       if (!tsk->thread.regs)
                return 0;
-       if (tsk == current && (regs->msr & MSR_FP))
-               giveup_fpu(current);
+       flush_fp_to_thread(current);
 
        memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
 
@@ -96,6 +128,8 @@ int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
 
 void enable_kernel_altivec(void)
 {
+       WARN_ON(preemptible());
+
 #ifdef CONFIG_SMP
        if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
                giveup_altivec(current);
@@ -107,10 +141,29 @@ void enable_kernel_altivec(void)
 }
 EXPORT_SYMBOL(enable_kernel_altivec);
 
+/*
+ * Make sure the VMX/Altivec register state in the
+ * the thread_struct is up to date for task tsk.
+ */
+void flush_altivec_to_thread(struct task_struct *tsk)
+{
+#ifdef CONFIG_ALTIVEC
+       if (tsk->thread.regs) {
+               preempt_disable();
+               if (tsk->thread.regs->msr & MSR_VEC) {
+#ifdef CONFIG_SMP
+                       BUG_ON(tsk != current);
+#endif
+                       giveup_altivec(current);
+               }
+               preempt_enable();
+       }
+#endif
+}
+
 int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
 {
-       if (regs->msr & MSR_VEC)
-               giveup_altivec(current);
+       flush_altivec_to_thread(current);
        memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
        return 1;
 }
@@ -166,6 +219,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
 void show_regs(struct pt_regs * regs)
 {
        int i;
+       unsigned long trap;
 
        printk("NIP: %016lX XER: %016lX LR: %016lX\n",
               regs->nip, regs->xer, regs->link);
@@ -176,7 +230,8 @@ void show_regs(struct pt_regs * regs)
               regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
               regs->msr&MSR_IR ? 1 : 0,
               regs->msr&MSR_DR ? 1 : 0);
-       if (regs->trap == 0x300 || regs->trap == 0x380 || regs->trap == 0x600)
+       trap = TRAP(regs);
+       if (trap == 0x300 || trap == 0x380 || trap == 0x600)
                printk("DAR: %016lx, DSISR: %016lx\n", regs->dar, regs->dsisr);
        printk("TASK: %p[%d] '%s' THREAD: %p",
               current, current->pid, current->comm, current->thread_info);
@@ -191,6 +246,8 @@ void show_regs(struct pt_regs * regs)
                }
 
                printk("%016lX ", regs->gpr[i]);
+               if (i == 13 && !FULL_REGS(regs))
+                       break;
        }
        printk("\n");
        /*
@@ -245,16 +302,8 @@ release_thread(struct task_struct *t)
  */
 void prepare_to_copy(struct task_struct *tsk)
 {
-       struct pt_regs *regs = tsk->thread.regs;
-
-       if (regs == NULL)
-               return;
-       if (regs->msr & MSR_FP)
-               giveup_fpu(current);
-#ifdef CONFIG_ALTIVEC
-       if (regs->msr & MSR_VEC)
-               giveup_altivec(current);
-#endif /* CONFIG_ALTIVEC */
+       flush_fp_to_thread(current);
+       flush_altivec_to_thread(current);
 }
 
 /*
@@ -439,12 +488,8 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       if (regs->msr & MSR_FP)
-               giveup_fpu(current);
-#ifdef CONFIG_ALTIVEC
-       if (regs->msr & MSR_VEC)
-               giveup_altivec(current);
-#endif /* CONFIG_ALTIVEC */
+       flush_fp_to_thread(current);
+       flush_altivec_to_thread(current);
        error = do_execve(filename, (char __user * __user *) a1,
                                    (char __user * __user *) a2, regs);
   
index efc9dbd..aeead83 100644 (file)
@@ -119,8 +119,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
                if (index < PT_FPR0) {
                        tmp = get_reg(child, (int)index);
                } else {
-                       if (child->thread.regs->msr & MSR_FP)
-                               giveup_fpu(child);
+                       flush_fp_to_thread(child);
                        tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
                }
                ret = put_user(tmp,(unsigned long __user *) data);
@@ -152,8 +151,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
                if (index < PT_FPR0) {
                        ret = put_reg(child, index, data);
                } else {
-                       if (child->thread.regs->msr & MSR_FP)
-                               giveup_fpu(child);
+                       flush_fp_to_thread(child);
                        ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
                        ret = 0;
                }
@@ -245,8 +243,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
                unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
                unsigned long __user *tmp = (unsigned long __user *)addr;
 
-               if (child->thread.regs->msr & MSR_FP)
-                       giveup_fpu(child);
+               flush_fp_to_thread(child);
 
                for (i = 0; i < 32; i++) {
                        ret = put_user(*reg, tmp);
@@ -263,8 +260,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
                unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
                unsigned long __user *tmp = (unsigned long __user *)addr;
 
-               if (child->thread.regs->msr & MSR_FP)
-                       giveup_fpu(child);
+               flush_fp_to_thread(child);
 
                for (i = 0; i < 32; i++) {
                        ret = get_user(*reg, tmp);
index 309db1c..3484e48 100644 (file)
@@ -136,8 +136,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
                if (index < PT_FPR0) {
                        tmp = get_reg(child, index);
                } else {
-                       if (child->thread.regs->msr & MSR_FP)
-                               giveup_fpu(child);
+                       flush_fp_to_thread(child);
                        /*
                         * the user space code considers the floating point
                         * to be an array of unsigned int (32 bits) - the
@@ -179,8 +178,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
                        break;
 
                if (numReg >= PT_FPR0) {
-                       if (child->thread.regs->msr & MSR_FP)
-                               giveup_fpu(child);
+                       flush_fp_to_thread(child);
                        tmp = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0];
                } else { /* register within PT_REGS struct */
                        tmp = get_reg(child, numReg);
@@ -244,8 +242,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
                if (index < PT_FPR0) {
                        ret = put_reg(child, index, data);
                } else {
-                       if (child->thread.regs->msr & MSR_FP)
-                               giveup_fpu(child);
+                       flush_fp_to_thread(child);
                        /*
                         * the user space code considers the floating point
                         * to be an array of unsigned int (32 bits) - the
@@ -283,8 +280,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
                                || ((numReg > PT_CCR) && (numReg < PT_FPR0)))
                        break;
                if (numReg >= PT_FPR0) {
-                       if (child->thread.regs->msr & MSR_FP)
-                               giveup_fpu(child);
+                       flush_fp_to_thread(child);
                }
                if (numReg == PT_MSR)
                        data = (data & MSR_DEBUGCHANGE)
@@ -379,8 +375,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
                unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
                unsigned int __user *tmp = (unsigned int __user *)addr;
 
-               if (child->thread.regs->msr & MSR_FP)
-                       giveup_fpu(child);
+               flush_fp_to_thread(child);
 
                for (i = 0; i < 32; i++) {
                        ret = put_user(*reg, tmp);
@@ -397,8 +392,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
                unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
                unsigned int __user *tmp = (unsigned int __user *)addr;
 
-               if (child->thread.regs->msr & MSR_FP)
-                       giveup_fpu(child);
+               flush_fp_to_thread(child);
 
                for (i = 0; i < 32; i++) {
                        ret = get_user(*reg, tmp);
index 603c9db..77c2400 100644 (file)
@@ -70,10 +70,11 @@ char rtas_data_buf[RTAS_DATA_BUF_SIZE]__page_aligned;
 void
 call_rtas_display_status(char c)
 {
-       struct rtas_args *args = &(get_paca()->xRtas);
+       struct rtas_args *args;
        unsigned long s;
 
        spin_lock_irqsave(&rtas.lock, s);
+       args = &(get_paca()->xRtas);
 
        args->token = 10;
        args->nargs = 1;
@@ -147,7 +148,7 @@ rtas_call(int token, int nargs, int nret,
        va_list list;
        int i, logit = 0;
        unsigned long s;
-       struct rtas_args *rtas_args = &(get_paca()->xRtas);
+       struct rtas_args *rtas_args;
        long ret;
 
        PPCDBG(PPCDBG_RTAS, "Entering rtas_call\n");
@@ -160,6 +161,7 @@ rtas_call(int token, int nargs, int nret,
 
        /* Gotta do something different here, use global lock for now... */
        spin_lock_irqsave(&rtas.lock, s);
+       rtas_args = &(get_paca()->xRtas);
 
        rtas_args->token = token;
        rtas_args->nargs = nargs;
index ce06678..8323d73 100644 (file)
@@ -131,8 +131,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
 #endif
        long err = 0;
 
-       if (regs->msr & MSR_FP)
-               giveup_fpu(current);
+       flush_fp_to_thread(current);
 
        /* Make sure signal doesn't get spurrious FP exceptions */
        current->thread.fpscr = 0;
@@ -141,9 +140,8 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
        err |= __put_user(v_regs, &sc->v_regs);
 
        /* save altivec registers */
-       if (current->thread.used_vr) {          
-               if (regs->msr & MSR_VEC)
-                       giveup_altivec(current);
+       if (current->thread.used_vr) {
+               flush_altivec_to_thread(current);
                /* Copy 33 vec registers (vr0..31 and vscr) to the stack */
                err |= __copy_to_user(v_regs, current->thread.vr, 33 * sizeof(vector128));
                /* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg)
@@ -530,13 +528,13 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
                struct k_sigaction *ka = &current->sighand->action[signr-1];
 
                /* Whee!  Actually deliver the signal.  */
-               if (regs->trap == 0x0C00)
+               if (TRAP(regs) == 0x0C00)
                        syscall_restart(regs, ka);
                handle_signal(signr, ka, &info, oldset, regs);
                return 1;
        }
 
-       if (regs->trap == 0x0C00) {     /* System Call! */
+       if (TRAP(regs) == 0x0C00) {     /* System Call! */
                if ((int)regs->result == -ERESTARTNOHAND ||
                    (int)regs->result == -ERESTARTSYS ||
                    (int)regs->result == -ERESTARTNOINTR) {
index c8f6294..ba2c8f7 100644 (file)
@@ -130,11 +130,10 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame,
 {
        elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
        int i, err = 0;
-       
-       /* Make sure floating point registers are stored in regs */ 
-       if (regs->msr & MSR_FP)
-               giveup_fpu(current);
-       
+
+       /* Make sure floating point registers are stored in regs */
+       flush_fp_to_thread(current);
+
        /* save general and floating-point registers */
        for (i = 0; i <= PT_RESULT; i ++)
                err |= __put_user((unsigned int)gregs[i], &frame->mc_gregs[i]);
@@ -148,8 +147,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame,
 #ifdef CONFIG_ALTIVEC
        /* save altivec registers */
        if (current->thread.used_vr) {
-               if (regs->msr & MSR_VEC)
-                       giveup_altivec(current);
+               flush_altivec_to_thread(current);
                if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
                                   ELF_NVRREG32 * sizeof(vector128)))
                        return 1;
@@ -934,7 +932,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
 
        ka = (signr == 0)? NULL: &current->sighand->action[signr-1];
 
-       if (regs->trap == 0x0C00                /* System Call! */
+       if (TRAP(regs) == 0x0C00                /* System Call! */
            && regs->ccr & 0x10000000           /* error signalled */
            && ((ret = regs->gpr[3]) == ERESTARTSYS
                || ret == ERESTARTNOHAND || ret == ERESTARTNOINTR
index ae52b20..6624375 100644 (file)
@@ -390,8 +390,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
        }
 
        /* Fixup atomic count: it exited inside IRQ handler. */
-       ((struct task_struct *)paca[lcpu].xCurrent)->thread_info->preempt_count
-               = 0;
+       paca[lcpu].xCurrent->thread_info->preempt_count = 0;
        /* Fixup SLB round-robin so next segment (kernel) goes in segment 0 */
        paca[lcpu].xStab_data.next_round_robin = 0;
 
@@ -819,7 +818,7 @@ static void __init smp_create_idle(unsigned int cpu)
        init_idle(p, cpu);
        unhash_process(p);
 
-       paca[cpu].xCurrent = (u64)p;
+       paca[cpu].xCurrent = p;
        current_set[cpu] = p->thread_info;
 }
 
@@ -871,7 +870,7 @@ void __devinit smp_prepare_boot_cpu(void)
        /* cpu_possible is set up in prom.c */
        cpu_set(boot_cpuid, cpu_online_map);
 
-       paca[boot_cpuid].xCurrent = (u64)current;
+       paca[boot_cpuid].xCurrent = current;
        current_set[boot_cpuid] = current->thread_info;
 }
 
@@ -914,8 +913,20 @@ int __devinit __cpu_up(unsigned int cpu)
         * use this value that I found through experimentation.
         * -- Cort
         */
-       for (c = 5000; c && !cpu_callin_map[cpu]; c--)
-               udelay(100);
+       if (system_state == SYSTEM_BOOTING)
+               for (c = 5000; c && !cpu_callin_map[cpu]; c--)
+                       udelay(100);
+#ifdef CONFIG_HOTPLUG_CPU
+       else
+               /*
+                * CPUs can take much longer to come up in the
+                * hotplug case.  Wait five seconds.
+                */
+               for (c = 25; c && !cpu_callin_map[cpu]; c--) {
+                       set_current_state(TASK_UNINTERRUPTIBLE);
+                       schedule_timeout(HZ/5);
+               }
+#endif
 
        if (!cpu_callin_map[cpu]) {
                printk("Processor %u is stuck.\n", cpu);
index ca80142..26e5e8d 100644 (file)
@@ -617,12 +617,8 @@ long sys32_execve(unsigned long a0, unsigned long a1, unsigned long a2,
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       if (regs->msr & MSR_FP)
-               giveup_fpu(current);
-#ifdef CONFIG_ALTIVEC
-       if (regs->msr & MSR_VEC)
-               giveup_altivec(current);
-#endif /* CONFIG_ALTIVEC */
+       flush_fp_to_thread(current);
+       flush_altivec_to_thread(current);
 
        error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs);
 
index 4ae0825..930b93f 100644 (file)
@@ -237,5 +237,19 @@ asmlinkage time_t sys64_time(time_t __user * tloc)
        return secs;
 }
 
+void do_show_syscall(unsigned long r3, unsigned long r4, unsigned long r5,
+                    unsigned long r6, unsigned long r7, unsigned long r8,
+                    struct pt_regs *regs)
+{
+       printk("syscall %ld(%lx, %lx, %lx, %lx, %lx, %lx) regs=%p current=%p"
+              " cpu=%d\n", regs->gpr[0], r3, r4, r5, r6, r7, r8, regs,
+              current, smp_processor_id());
+}
+
+void do_show_syscall_exit(unsigned long r3)
+{
+       printk(" -> %lx, current=%p cpu=%d\n", r3, current, smp_processor_id());
+}
+
 /* Only exists on P-series. */
 cond_syscall(ppc_rtas);
index 2445502..97a83ff 100644 (file)
@@ -328,6 +328,16 @@ static int __init topology_init(void)
 #ifdef CONFIG_NUMA
                parent = &node_devices[cpu_to_node(cpu)];
 #endif
+               /*
+                * For now, we just see if the system supports making
+                * the RTAS calls for CPU hotplug.  But, there may be a
+                * more comprehensive way to do this for an individual
+                * CPU.  For instance, the boot cpu might never be valid
+                * for hotplugging.
+                */
+               if (systemcfg->platform != PLATFORM_PSERIES_LPAR)
+                       c->no_control = 1;
+
                register_cpu(c, cpu, parent);
 
                register_cpu_pmc(&c->sysdev);
index 7c1594d..5933197 100644 (file)
@@ -308,8 +308,7 @@ static void parse_fpe(struct pt_regs *regs)
        siginfo_t info;
        unsigned long fpscr;
 
-       if (regs->msr & MSR_FP)
-               giveup_fpu(current);
+       flush_fp_to_thread(current);
 
        fpscr = current->thread.fpscr;
 
@@ -442,8 +441,22 @@ void KernelFPUnavailableException(struct pt_regs *regs)
        die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
 }
 
-void KernelAltivecUnavailableException(struct pt_regs *regs)
+void AltivecUnavailableException(struct pt_regs *regs)
 {
+#ifndef CONFIG_ALTIVEC
+       if (user_mode(regs)) {
+               /* A user program has executed an altivec instruction,
+                  but this kernel doesn't support altivec. */
+               siginfo_t info;
+
+               memset(&info, 0, sizeof(info));
+               info.si_signo = SIGILL;
+               info.si_code = ILL_ILLOPC;
+               info.si_addr = (void *) regs->nip;
+               _exception(SIGILL, &info, regs);
+               return;
+       }
+#endif
        printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
                          "%lx at %lx\n", regs->trap, regs->nip);
        die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
@@ -466,6 +479,18 @@ SingleStepException(struct pt_regs *regs)
        _exception(SIGTRAP, &info, regs);       
 }
 
+/*
+ * After we have successfully emulated an instruction, we have to
+ * check if the instruction was being single-stepped, and if so,
+ * pretend we got a single-step exception.  This was pointed out
+ * by Kumar Gala.  -- paulus
+ */
+static inline void emulate_single_step(struct pt_regs *regs)
+{
+       if (regs->msr & MSR_SE)
+               SingleStepException(regs);
+}
+
 static void dummy_perf(struct pt_regs *regs)
 {
 }
@@ -487,10 +512,8 @@ AlignmentException(struct pt_regs *regs)
        fixed = fix_alignment(regs);
 
        if (fixed == 1) {
-               if (!user_mode(regs))
-                       PPCDBG(PPCDBG_ALIGNFIXUP, "fix alignment at %lx\n",
-                              regs->nip);
                regs->nip += 4; /* skip over emulated instruction */
+               emulate_single_step(regs);
                return;
        }
 
@@ -521,8 +544,7 @@ AlignmentException(struct pt_regs *regs)
 void
 AltivecAssistException(struct pt_regs *regs)
 {
-       if (regs->msr & MSR_VEC)
-               giveup_altivec(current);
+       flush_altivec_to_thread(current);
        /* XXX quick hack for now: set the non-Java bit in the VSCR */
        current->thread.vscr.u[3] |= 0x10000;
 }
index ce758a3..78b05df 100644 (file)
@@ -32,7 +32,9 @@
 
 extern struct subsystem devices_subsys; /* needed for vio_find_name() */
 
-struct iommu_table *vio_build_iommu_table(struct vio_dev *dev);
+static struct iommu_table *vio_build_iommu_table(struct vio_dev *);
+static const struct vio_device_id *vio_match_device(
+               const struct vio_device_id *, const struct vio_dev *);
 
 #ifdef CONFIG_PPC_PSERIES
 static int vio_num_address_cells;
@@ -136,15 +138,15 @@ EXPORT_SYMBOL(vio_unregister_driver);
  * system is in its list of supported devices. Returns the matching
  * vio_device_id structure or NULL if there is no match.
  */
-const struct vio_device_id * vio_match_device(const struct vio_device_id *ids,
+static const struct vio_device_id * vio_match_device(const struct vio_device_id *ids,
        const struct vio_dev *dev)
 {
        DBGENTER();
 
 #ifdef CONFIG_PPC_PSERIES
        while (ids->type) {
-               if ((strncmp(dev->archdata->type, ids->type, strlen(ids->type)) == 0) &&
-                       device_is_compatible((struct device_node*)dev->archdata, ids->compat))
+               if ((strncmp(((struct device_node *)dev->dev.platform_data)->type, ids->type, strlen(ids->type)) == 0) &&
+                       device_is_compatible(dev->dev.platform_data, ids->compat))
                        return ids;
                ids++;
        }
@@ -263,14 +265,13 @@ static void __devinit vio_dev_release(struct device *dev)
        DBGENTER();
 
        /* XXX free TCE table */
-       of_node_put(viodev->archdata);
+       of_node_put(viodev->dev.platform_data);
        kfree(viodev);
 }
 
 static ssize_t viodev_show_devspec(struct device *dev, char *buf)
 {
-       struct vio_dev *viodev = to_vio_dev(dev);
-       struct device_node *of_node = viodev->archdata;
+       struct device_node *of_node = dev->platform_data;
 
        return sprintf(buf, "%s\n", of_node->full_name);
 }
@@ -278,8 +279,7 @@ DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL);
 
 static ssize_t viodev_show_name(struct device *dev, char *buf)
 {
-       struct vio_dev *viodev = to_vio_dev(dev);
-       struct device_node *of_node = viodev->archdata;
+       struct device_node *of_node = dev->platform_data;
 
        return sprintf(buf, "%s\n", of_node->name);
 }
@@ -290,7 +290,7 @@ DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_name, NULL);
  * @of_node:   The OF node for this device.
  *
  * Creates and initializes a vio_dev structure from the data in
- * of_node (archdata) and adds it to the list of virtual devices.
+ * of_node (dev.platform_data) and adds it to the list of virtual devices.
  * Returns a pointer to the created vio_dev or NULL if node has
  * NULL device_type or compatible fields.
  */
@@ -324,7 +324,7 @@ struct vio_dev * __devinit vio_register_device(struct device_node *of_node)
        }
        memset(viodev, 0, sizeof(struct vio_dev));
 
-       viodev->archdata = (void *)of_node_get(of_node);
+       viodev->dev.platform_data = of_node_get(of_node);
        viodev->unit_address = *unit_address;
        viodev->iommu_table = vio_build_iommu_table(viodev);
 
@@ -380,7 +380,7 @@ EXPORT_SYMBOL(vio_unregister_device);
 */
 const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length)
 {
-       return get_property((struct device_node *)vdev->archdata, (char*)which, length);
+       return get_property(vdev->dev.platform_data, (char*)which, length);
 }
 EXPORT_SYMBOL(vio_get_attribute);
 
@@ -427,7 +427,7 @@ EXPORT_SYMBOL(vio_find_node);
  * Returns a pointer to the built tce tree, or NULL if it can't
  * find property.
 */
-struct iommu_table * vio_build_iommu_table(struct vio_dev *dev)
+static struct iommu_table * vio_build_iommu_table(struct vio_dev *dev)
 {
        unsigned int *dma_window;
        struct iommu_table *newTceTable;
@@ -435,7 +435,7 @@ struct iommu_table * vio_build_iommu_table(struct vio_dev *dev)
        unsigned long size;
        int dma_window_property_size;
 
-       dma_window = (unsigned int *) get_property((struct device_node *)dev->archdata, "ibm,my-dma-window", &dma_window_property_size);
+       dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size);
        if(!dma_window) {
                return NULL;
        }
index f0cb2d7..3fbdd00 100644 (file)
@@ -191,7 +191,6 @@ static int proc_viopath_show(struct seq_file *m, void *v)
 {
        char *buf;
        u16 vlanMap;
-       int vlanIndex;
        dma_addr_t handle;
        HvLpEvent_Rc hvrc;
        DECLARE_MUTEX_LOCKED(Semaphore);
@@ -219,17 +218,10 @@ static int proc_viopath_show(struct seq_file *m, void *v)
        down(&Semaphore);
 
        vlanMap = HvLpConfig_getVirtualLanIndexMap();
-       vlanIndex = 0;
-       while (vlanMap != 0){
-               if (vlanMap & 0x8000)
-                       vlanIndex++;;
-               vlanMap = vlanMap << 1;
-       }
 
        buf[PAGE_SIZE-1] = '\0';
        seq_printf(m, "%s", buf);
-
-       seq_printf(m, "AVAILABLE_VETH=%d\n", vlanIndex );
+       seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap);
        seq_printf(m, "SRLNBR=%c%c%c%c%c%c%c\n",
                   e2a(xItExtVpdPanel.mfgID[2]),
                   e2a(xItExtVpdPanel.mfgID[3]),
index ca2b86d..72eba98 100644 (file)
@@ -80,36 +80,45 @@ static int store_updates_sp(struct pt_regs *regs)
  *  - DSISR for a non-SLB data access fault,
  *  - SRR1 & 0x08000000 for a non-SLB instruction access fault
  *  - 0 any SLB fault.
+ * The return value is 0 if the fault was handled, or the signal
+ * number if this is a kernel fault that can't be handled here.
  */
-void do_page_fault(struct pt_regs *regs, unsigned long address,
-                  unsigned long error_code)
+int do_page_fault(struct pt_regs *regs, unsigned long address,
+                 unsigned long error_code)
 {
        struct vm_area_struct * vma;
        struct mm_struct *mm = current->mm;
        siginfo_t info;
        unsigned long code = SEGV_MAPERR;
        unsigned long is_write = error_code & 0x02000000;
+       unsigned long trap = TRAP(regs);
 
-       if (regs->trap == 0x300 || regs->trap == 0x380) {
+       if (trap == 0x300 || trap == 0x380) {
                if (debugger_fault_handler(regs))
-                       return;
+                       return 0;
        }
 
        /* On a kernel SLB miss we can only check for a valid exception entry */
-       if (!user_mode(regs) && (regs->trap == 0x380)) {
-               bad_page_fault(regs, address, SIGSEGV);
-               return;
-       }
+       if (!user_mode(regs) && (trap == 0x380 || address >= TASK_SIZE))
+               return SIGSEGV;
 
        if (error_code & 0x00400000) {
                if (debugger_dabr_match(regs))
-                       return;
+                       return 0;
        }
 
        if (in_atomic() || mm == NULL) {
-               bad_page_fault(regs, address, SIGSEGV);
-               return;
+               if (!user_mode(regs))
+                       return SIGSEGV;
+               /* in_atomic() in user mode is really bad,
+                  as is current->mm == NULL. */
+               printk(KERN_EMERG "Page fault in user mode with"
+                      "in_atomic() = %d mm = %p\n", in_atomic(), mm);
+               printk(KERN_EMERG "NIP = %lx  MSR = %lx\n",
+                      regs->nip, regs->msr);
+               die("Weird page fault", regs, SIGSEGV);
        }
+
        down_read(&mm->mmap_sem);
        vma = find_vma(mm, address);
        if (!vma)
@@ -195,7 +204,7 @@ good_area:
        }
 
        up_read(&mm->mmap_sem);
-       return;
+       return 0;
 
 bad_area:
        up_read(&mm->mmap_sem);
@@ -207,11 +216,10 @@ bad_area:
                info.si_code = code;
                info.si_addr = (void *) address;
                force_sig_info(SIGSEGV, &info, current);
-               return;
+               return 0;
        }
 
-       bad_page_fault(regs, address, SIGSEGV);
-       return;
+       return SIGSEGV;
 
 /*
  * We ran out of memory, or some other thing happened to us that made
@@ -227,18 +235,19 @@ out_of_memory:
        printk("VM: killing process %s\n", current->comm);
        if (user_mode(regs))
                do_exit(SIGKILL);
-       bad_page_fault(regs, address, SIGKILL);
-       return;
+       return SIGKILL;
 
 do_sigbus:
        up_read(&mm->mmap_sem);
-       info.si_signo = SIGBUS;
-       info.si_errno = 0;
-       info.si_code = BUS_ADRERR;
-       info.si_addr = (void *)address;
-       force_sig_info (SIGBUS, &info, current);
-       if (!user_mode(regs))
-               bad_page_fault(regs, address, SIGBUS);
+       if (user_mode(regs)) {
+               info.si_signo = SIGBUS;
+               info.si_errno = 0;
+               info.si_code = BUS_ADRERR;
+               info.si_addr = (void *)address;
+               force_sig_info(SIGBUS, &info, current);
+               return 0;
+       }
+       return SIGBUS;
 }
 
 /*
index 1df6d97..4e6b529 100644 (file)
@@ -251,6 +251,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
        struct mm_struct *mm;
        pte_t *ptep;
        int ret;
+       int cpu;
        int user_region = 0;
        int local = 0;
        cpumask_t tmp;
@@ -302,7 +303,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
        if (pgdir == NULL)
                return 1;
 
-       tmp = cpumask_of_cpu(smp_processor_id());
+       cpu = get_cpu();
+       tmp = cpumask_of_cpu(cpu);
        if (user_region && cpus_equal(mm->cpu_vm_mask, tmp))
                local = 1;
 
@@ -311,11 +313,13 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
                ret = hash_huge_page(mm, access, ea, vsid, local);
        else {
                ptep = find_linux_pte(pgdir, ea);
-               if (ptep == NULL)
+               if (ptep == NULL) {
+                       put_cpu();
                        return 1;
+               }
                ret = __hash_page(ea, access, vsid, ptep, trap, local);
        }
-
+       put_cpu();
 
        return ret;
 }
index d660b0d..b704e00 100644 (file)
@@ -375,6 +375,7 @@ void unmap_hugepage_range(struct vm_area_struct *vma,
        unsigned long addr;
        hugepte_t *ptep;
        struct page *page;
+       int cpu;
        int local = 0;
        cpumask_t tmp;
 
@@ -383,7 +384,8 @@ void unmap_hugepage_range(struct vm_area_struct *vma,
        BUG_ON((end % HPAGE_SIZE) != 0);
 
        /* XXX are there races with checking cpu_vm_mask? - Anton */
-       tmp = cpumask_of_cpu(smp_processor_id());
+       cpu = get_cpu();
+       tmp = cpumask_of_cpu(cpu);
        if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
                local = 1;
 
@@ -406,6 +408,7 @@ void unmap_hugepage_range(struct vm_area_struct *vma,
 
                put_page(page);
        }
+       put_cpu();
 
        mm->rss -= (end - start) >> PAGE_SHIFT;
 }
index 84ceb2d..5043702 100644 (file)
@@ -764,6 +764,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long ea,
        void *pgdir;
        pte_t *ptep;
        int local = 0;
+       int cpu;
        cpumask_t tmp;
 
        /* handle i-cache coherency */
@@ -794,12 +795,14 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long ea,
 
        vsid = get_vsid(vma->vm_mm->context.id, ea);
 
-       tmp = cpumask_of_cpu(smp_processor_id());
+       cpu = get_cpu();
+       tmp = cpumask_of_cpu(cpu);
        if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
                local = 1;
 
        __hash_page(ea, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep,
                    0x300, local);
+       put_cpu();
 }
 
 void * reserve_phb_iospace(unsigned long size)
index b616f9a..980443b 100644 (file)
@@ -41,6 +41,33 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
 unsigned long pte_freelist_forced_free;
 
+void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage)
+{
+       /* This is safe as we are holding page_table_lock */
+        cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id());
+       struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
+
+       if (atomic_read(&tlb->mm->mm_users) < 2 ||
+           cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) {
+               pte_free(ptepage);
+               return;
+       }
+
+       if (*batchp == NULL) {
+               *batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC);
+               if (*batchp == NULL) {
+                       pte_free_now(ptepage);
+                       return;
+               }
+               (*batchp)->index = 0;
+       }
+       (*batchp)->pages[(*batchp)->index++] = ptepage;
+       if ((*batchp)->index == PTE_FREELIST_SIZE) {
+               pte_free_submit(*batchp);
+               *batchp = NULL;
+       }
+}
+
 /*
  * Update the MMU hash table to correspond with a change to
  * a Linux PTE.  If wrprot is true, it is permissible to
@@ -91,12 +118,15 @@ void hpte_update(pte_t *ptep, unsigned long pte, int wrprot)
 void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
 {
        int i;
-       cpumask_t tmp = cpumask_of_cpu(smp_processor_id());
+       int cpu;
+       cpumask_t tmp;
        int local = 0;
 
        BUG_ON(in_interrupt());
 
+       cpu = get_cpu();
        i = batch->index;
+       tmp = cpumask_of_cpu(cpu);
        if (cpus_equal(batch->mm->cpu_vm_mask, tmp))
                local = 1;
 
@@ -106,6 +136,7 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
        else
                flush_hash_range(batch->context, i, local);
        batch->index = 0;
+       put_cpu();
 }
 
 #ifdef CONFIG_SMP
index 97b1509..679a484 100644 (file)
@@ -44,9 +44,6 @@ static int xmon_owner;
 static int xmon_gate;
 #endif /* CONFIG_SMP */
 
-#define TRAP(regs)     ((regs)->trap)
-#define FULL_REGS(regs)        1
-
 static unsigned long in_xmon = 0;
 
 static unsigned long adrs;
index 2d7efbf..0f8c08a 100644 (file)
@@ -85,9 +85,10 @@ struct appldata_parameter_list {
  */
 static const char appldata_proc_name[APPLDATA_PROC_NAME_LENGTH] = "appldata";
 static int appldata_timer_handler(ctl_table *ctl, int write, struct file *filp,
-                                 void *buffer, size_t *lenp);
+                                 void __user *buffer, size_t *lenp);
 static int appldata_interval_handler(ctl_table *ctl, int write,
-                                        struct file *filp, void *buffer,
+                                        struct file *filp,
+                                        void __user *buffer,
                                         size_t *lenp);
 
 static struct ctl_table_header *appldata_sysctl_header;
@@ -192,7 +193,8 @@ static void appldata_tasklet_function(unsigned long data)
  * wrapper function for mod_virt_timer(), because smp_call_function_on()
  * accepts only one parameter.
  */
-static void appldata_mod_vtimer_wrap(struct appldata_mod_vtimer_args *args) {
+static void appldata_mod_vtimer_wrap(void *p) {
+       struct appldata_mod_vtimer_args *args = p;
        mod_virt_timer(args->timer, args->expires);
 }
 
@@ -252,7 +254,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer,
  */
 static int
 appldata_timer_handler(ctl_table *ctl, int write, struct file *filp,
-                          void *buffer, size_t *lenp)
+                          void __user *buffer, size_t *lenp)
 {
        int len, i;
        char buf[2];
@@ -309,7 +311,7 @@ out:
  */
 static int
 appldata_interval_handler(ctl_table *ctl, int write, struct file *filp,
-                          void *buffer, size_t *lenp)
+                          void __user *buffer, size_t *lenp)
 {
        int len, i, interval;
        char buf[16];
@@ -347,7 +349,7 @@ appldata_interval_handler(ctl_table *ctl, int write, struct file *filp,
                        appldata_mod_vtimer_args.expires =
                                        per_cpu_interval;
                        smp_call_function_on(
-                               (void *) appldata_mod_vtimer_wrap,
+                               appldata_mod_vtimer_wrap,
                                &appldata_mod_vtimer_args,
                                0, 1, i);
                }
@@ -370,7 +372,7 @@ out:
  */
 static int
 appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
-                          void *buffer, size_t *lenp)
+                          void __user *buffer, size_t *lenp)
 {
        struct appldata_ops *ops = NULL, *tmp_ops;
        int rc, len, found;
index 3fb8223..c694ae5 100644 (file)
@@ -28,6 +28,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_IOSCHED_NOOP=y
@@ -112,7 +113,6 @@ CONFIG_CHR_DEV_SG=y
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
 CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_REPORT_LUNS is not set
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
 
@@ -126,6 +126,7 @@ CONFIG_SCSI_LOGGING=y
 # SCSI low-level drivers
 #
 # CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -310,11 +311,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 
 #
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
+# Gigabit Ethernet (1000/10000 Mbit)
 #
 
 #
index a35e11a..ce2b035 100644 (file)
@@ -32,6 +32,7 @@ int main(void)
        DEFINE(__TI_cpu, offsetof(struct thread_info, cpu),);
        DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count),);
        BLANK();
+       DEFINE(__PT_ARGS, offsetof(struct pt_regs, args),);
        DEFINE(__PT_PSW, offsetof(struct pt_regs, psw),);
        DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs),);
        DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2),);
index 3886a27..67134ee 100644 (file)
@@ -53,7 +53,7 @@ typedef struct
 
 asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
 
-int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from)
+int copy_siginfo_to_user32(siginfo_t32 __user *to, siginfo_t *from)
 {
        int err;
 
@@ -130,7 +130,8 @@ sys32_sigsuspend(struct pt_regs * regs,int history0, int history1, old_sigset_t
 }
 
 asmlinkage int
-sys32_rt_sigsuspend(struct pt_regs * regs,compat_sigset_t *unewset, size_t sigsetsize)
+sys32_rt_sigsuspend(struct pt_regs * regs, compat_sigset_t __user *unewset,
+                                                               size_t sigsetsize)
 {
        sigset_t saveset, newset;
        compat_sigset_t set32;
@@ -162,11 +163,11 @@ sys32_rt_sigsuspend(struct pt_regs * regs,compat_sigset_t *unewset, size_t sigse
                 if (do_signal(regs, &saveset))
                         return -EINTR;
         }
-}                                                         
+}
 
 asmlinkage long
-sys32_sigaction(int sig, const struct old_sigaction32 *act,
-                struct old_sigaction32 *oact)
+sys32_sigaction(int sig, const struct old_sigaction32 __user *act,
+                struct old_sigaction32 __user *oact)
 {
         struct k_sigaction new_ka, old_ka;
         int ret;
@@ -199,9 +200,9 @@ sys32_sigaction(int sig, const struct old_sigaction32 *act,
 int
 do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact);
 
-asmlinkage long 
-sys32_rt_sigaction(int sig, const struct sigaction32 *act,
-          struct sigaction32 *oact,  size_t sigsetsize)
+asmlinkage long
+sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
+          struct sigaction32 __user *oact,  size_t sigsetsize)
 {
        struct k_sigaction new_ka, old_ka;
        int ret;
@@ -258,7 +259,8 @@ sys32_rt_sigaction(int sig, const struct sigaction32 *act,
 }
 
 asmlinkage long
-sys32_sigaltstack(const stack_t32 *uss, stack_t32 *uoss, struct pt_regs *regs)
+sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss,
+                                                       struct pt_regs *regs)
 {
        stack_t kss, koss;
        int ret, err = 0;
@@ -275,7 +277,9 @@ sys32_sigaltstack(const stack_t32 *uss, stack_t32 *uoss, struct pt_regs *regs)
        }
 
        set_fs (KERNEL_DS);
-       ret = do_sigaltstack(uss ? &kss : NULL , uoss ? &koss : NULL, regs->gprs[15]);
+       ret = do_sigaltstack((stack_t __user *) (uss ? &kss : NULL),
+                            (stack_t __user *) (uoss ? &koss : NULL),
+                            regs->gprs[15]);
        set_fs (old_fs);
 
        if (!ret && uoss) {
@@ -290,7 +294,7 @@ sys32_sigaltstack(const stack_t32 *uss, stack_t32 *uoss, struct pt_regs *regs)
        return ret;
 }
 
-static int save_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
+static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
 {
        _s390_regs_common32 regs32;
        int err, i;
@@ -311,7 +315,7 @@ static int save_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
                              sizeof(_s390_fp_regs32));
 }
 
-static int restore_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
+static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
 {
        _s390_regs_common32 regs32;
        int err, i;
@@ -343,7 +347,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
 
 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
 {
-       sigframe32 *frame = (sigframe32 *)regs->gprs[15];
+       sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
        sigset_t set;
 
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
@@ -365,11 +369,11 @@ asmlinkage long sys32_sigreturn(struct pt_regs *regs)
 badframe:
        force_sig(SIGSEGV, current);
        return 0;
-}      
+}
 
 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
 {
-       rt_sigframe32 *frame = (rt_sigframe32 *)regs->gprs[15];
+       rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
        sigset_t set;
        stack_t st;
        __u32 ss_sp;
@@ -399,8 +403,8 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
 
        /* It is more difficult to avoid calling this function than to
           call it and ignore errors.  */
-       set_fs (KERNEL_DS);   
-       do_sigaltstack(&st, NULL, regs->gprs[15]);
+       set_fs (KERNEL_DS);
+       do_sigaltstack((stack_t __user *)&st, NULL, regs->gprs[15]);
        set_fs (old_fs);
 
        return regs->gprs[2];
@@ -418,7 +422,7 @@ badframe:
 /*
  * Determine which stack to use..
  */
-static inline void *
+static inline void __user *
 get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
 {
        unsigned long sp;
@@ -439,7 +443,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
                sp = (unsigned long) ka->sa.sa_restorer;
        }
 
-       return (void *)((sp - frame_size) & -8ul);
+       return (void __user *)((sp - frame_size) & -8ul);
 }
 
 static inline int map_signal(int sig)
@@ -455,7 +459,7 @@ static inline int map_signal(int sig)
 static void setup_frame32(int sig, struct k_sigaction *ka,
                        sigset_t *set, struct pt_regs * regs)
 {
-       sigframe32 *frame = get_sigframe(ka, regs, sizeof(sigframe32));
+       sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32));
        if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32)))
                goto give_sigsegv;
 
@@ -474,12 +478,12 @@ static void setup_frame32(int sig, struct k_sigaction *ka,
        } else {
                regs->gprs[14] = (__u64) frame->retcode;
                if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
-                              (u16 *)(frame->retcode)))
+                              (u16 __user *)(frame->retcode)))
                        goto give_sigsegv;
         }
 
        /* Set up backchain. */
-       if (__put_user(regs->gprs[15], (unsigned int *) frame))
+       if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
                goto give_sigsegv;
 
        /* Set up registers for signal handler */
@@ -505,7 +509,7 @@ static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
                           sigset_t *set, struct pt_regs * regs)
 {
        int err = 0;
-       rt_sigframe32 *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
+       rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
        if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32)))
                goto give_sigsegv;
 
@@ -531,11 +535,11 @@ static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
        } else {
                regs->gprs[14] = (__u64) frame->retcode;
                err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
-                                 (u16 *)(frame->retcode));
+                                 (u16 __user *)(frame->retcode));
        }
 
        /* Set up backchain. */
-       if (__put_user(regs->gprs[15], (unsigned int *) frame))
+       if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
                goto give_sigsegv;
 
        /* Set up registers for signal handler */
index a0c4366..41adc61 100644 (file)
@@ -1097,6 +1097,8 @@ compat_sys_futex_wrapper:
        lgfr    %r4,%r4                 # int
        llgtr   %r5,%r5                 # struct compat_timespec *
        llgtr   %r6,%r6                 # u32 *
+       lgf     %r0,164(%r15)           # int
+       stg     %r0,160(%r15)
        jg      compat_sys_futex        # branch to system call
 
        .globl  sys32_setxattr_wrapper
index d2980b6..540a9a8 100644 (file)
@@ -62,9 +62,9 @@ extern void tod_to_timeval(uint64_t todval, struct timeval *xtime);
 /* internal function prototyes */
 
 static int debug_init(void);
-static ssize_t debug_output(struct file *file, char *user_buf,
+static ssize_t debug_output(struct file *file, char __user *user_buf,
                            size_t user_len, loff_t * offset);
-static ssize_t debug_input(struct file *file, const char *user_buf,
+static ssize_t debug_input(struct file *file, const char __user *user_buf,
                           size_t user_len, loff_t * offset);
 static int debug_open(struct inode *inode, struct file *file);
 static int debug_close(struct inode *inode, struct file *file);
@@ -74,10 +74,10 @@ static void debug_info_put(debug_info_t *);
 static int debug_prolog_level_fn(debug_info_t * id,
                                 struct debug_view *view, char *out_buf);
 static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
-                               struct file *file, const char *user_buf,
+                               struct file *file, const char __user *user_buf,
                                size_t user_buf_size, loff_t * offset);
 static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
-                                struct file *file, const char *user_buf,
+                                struct file *file, const char __user *user_buf,
                                 size_t user_buf_size, loff_t * offset);
 static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
                                 char *out_buf, const char *in_buf);
@@ -416,10 +416,10 @@ out:
  * - copies formated debug entries to the user buffer
  */
 
-static ssize_t debug_output(struct file *file, /* file descriptor */
-                           char *user_buf,     /* user buffer */
-                           size_t  len,        /* length of buffer */
-                           loff_t *offset      /* offset in the file */ )
+static ssize_t debug_output(struct file *file,         /* file descriptor */
+                           char __user *user_buf,      /* user buffer */
+                           size_t  len,                /* length of buffer */
+                           loff_t *offset)           /* offset in the file */
 {
        size_t count = 0;
        size_t entry_offset, size = 0;
@@ -462,7 +462,7 @@ out:
  */
 
 static ssize_t debug_input(struct file *file,
-                          const char *user_buf, size_t length,
+                          const char __user *user_buf, size_t length,
                           loff_t *offset)
 {
        int rc = 0;
@@ -942,7 +942,7 @@ static int debug_prolog_level_fn(debug_info_t * id,
  */
 
 static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
-                               struct file *file, const char *user_buf,
+                               struct file *file, const char __user *user_buf,
                                size_t in_buf_size, loff_t * offset)
 {
        char input_buf[1];
@@ -1004,9 +1004,9 @@ void debug_flush(debug_info_t* id, int area)
 /*
  * view function: flushes debug areas 
  */
+
 static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
-                                struct file *file, const char *user_buf,
+                                struct file *file, const char __user *user_buf,
                                 size_t in_buf_size, loff_t * offset)
 {
         char input_buf[1];
index 4cce894..f716b41 100644 (file)
@@ -24,7 +24,8 @@
  * Stack layout for the system_call stack entry.
  * The first few entries are identical to the user_regs_struct.
  */
-SP_PTREGS    =  STACK_FRAME_OVERHEAD 
+SP_PTREGS    =  STACK_FRAME_OVERHEAD
+SP_ARGS      =  STACK_FRAME_OVERHEAD + __PT_ARGS
 SP_PSW       =  STACK_FRAME_OVERHEAD + __PT_PSW
 SP_R0        =  STACK_FRAME_OVERHEAD + __PT_GPRS
 SP_R1        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 4
@@ -47,7 +48,8 @@ SP_ILC       =  STACK_FRAME_OVERHEAD + __PT_ILC
 SP_TRAP      =  STACK_FRAME_OVERHEAD + __PT_TRAP
 SP_SIZE      =  STACK_FRAME_OVERHEAD + __PT_SIZE
 
-_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC)
+_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+                _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
 _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
 
 #define BASED(name) name-system_call(%r13)
@@ -229,13 +231,16 @@ system_call:
        lh      %r7,0x8a          # get svc number from lowcore
 sysc_enter:
         GET_THREAD_INFO           # load pointer to task_struct to R9
+sysc_do_svc:
        sla     %r7,2             # *4 and test for svc 0
-       bnz     BASED(sysc_do_restart)  # svc number > 0
+       bnz     BASED(sysc_nr_ok) # svc number > 0
        # svc 0: system call number in %r1
        cl      %r1,BASED(.Lnr_syscalls)
-       bnl     BASED(sysc_do_restart)
+       bnl     BASED(sysc_nr_ok)
        lr      %r7,%r1           # copy svc number to %r7
        sla     %r7,2             # *4
+sysc_nr_ok:
+       mvc     SP_ARGS(4,%r15),SP_R7(%r15)
 sysc_do_restart:
        tm      __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
         l       %r8,sys_call_table-system_call(%r7,%r13) # get system call addr.
@@ -262,7 +267,6 @@ sysc_work_loop:
        bz      BASED(sysc_leave)      # there is no work to do
 #
 # One of the work bits is on. Find out which one.
-# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED
 #
 sysc_work:
        tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
@@ -271,6 +275,8 @@ sysc_work:
        bo      BASED(sysc_sigpending)
        tm      __TI_flags+3(%r9),_TIF_RESTART_SVC
        bo      BASED(sysc_restart)
+       tm      __TI_flags+3(%r9),_TIF_SINGLE_STEP
+       bo      BASED(sysc_singlestep)
        b       BASED(sysc_leave)
 
 #
@@ -304,6 +310,17 @@ sysc_restart:
        lm      %r2,%r6,SP_R2(%r15)    # load svc arguments
        b       BASED(sysc_do_restart) # restart svc
 
+#
+# _TIF_SINGLE_STEP is set, call do_debugger_trap
+#
+sysc_singlestep:
+       ni      __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
+       mvi     SP_TRAP+1(%r15),0x28    # set trap indication to pgm check
+       la      %r2,SP_PTREGS(%r15)     # address of register-save area
+       l       %r1,BASED(.Lhandle_per) # load adr. of per handler
+       la      %r14,BASED(sysc_return) # load adr. of system return
+       br      %r1                     # branch to do_debugger_trap
+
 __critical_end:
 
 #
@@ -495,71 +512,15 @@ pgm_per_only:
 #
 pgm_svcper:
        SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
-       lh      %r7,0x8a          # get svc number from lowcore
-        GET_THREAD_INFO           # load pointer to task_struct to R9
+       lh      %r7,0x8a                # get svc number from lowcore
+       GET_THREAD_INFO                 # load pointer to task_struct to R9
        l       %r1,__TI_task(%r9)
        mvc     __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
        mvc     __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
        mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
-        stosm   24(%r15),0x03     # reenable interrupts
-        sla     %r7,2             # *4 and test for svc 0
-       bnz     BASED(pgm_svcstd) # svc number > 0 ?
-       # svc 0: system call number in %r1
-       cl      %r1,BASED(.Lnr_syscalls)
-       bnl     BASED(pgm_svcstd)
-       lr      %r7,%r1           # copy svc number to %r7
-       sla     %r7,2             # *4
-pgm_svcstd:
-       tm      __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
-        l       %r8,sys_call_table-system_call(%r7,%r13) # get system call addr.
-        bnz     BASED(pgm_tracesys)
-        basr    %r14,%r8          # call sys_xxxx
-        st      %r2,SP_R2(%r15)   # store return value (change R2 on stack)
-                                  # ATTENTION: check sys_execve_glue before
-                                  # changing anything here !!
-
-pgm_svcret:
-       tm      __TI_flags+3(%r9),_TIF_SIGPENDING
-       bno     BASED(pgm_svcper_nosig)
-       la      %r2,SP_PTREGS(%r15) # load pt_regs
-       sr      %r3,%r3           # clear *oldset
-       l       %r1,BASED(.Ldo_signal)
-       basr    %r14,%r1          # call do_signal
-       
-pgm_svcper_nosig:
-        mvi     SP_TRAP+3(%r15),0x28     # set trap indication to pgm check
-       la      %r2,SP_PTREGS(15)        # address of register-save area
-        l       %r1,BASED(.Lhandle_per)  # load adr. of per handler
-        la      %r14,BASED(sysc_return)  # load adr. of system return
-        br      %r1                      # branch to do_debugger_trap
-#
-# call trace before and after sys_call
-#
-pgm_tracesys:
-        l       %r1,BASED(.Ltrace)
-       la      %r2,SP_PTREGS(%r15)    # load pt_regs
-       la      %r3,0
-       srl     %r7,2
-       st      %r7,SP_R2(%r15)
-        basr    %r14,%r1
-       clc     SP_R2(4,%r15),BASED(.Lnr_syscalls)
-       bnl     BASED(pgm_svc_nogo)
-       l       %r7,SP_R2(%r15)   # strace changed the syscall
-       sll     %r7,2
-       l       %r8,sys_call_table-system_call(%r7,%r13)
-pgm_svc_go:
-       lm      %r3,%r6,SP_R3(%r15)
-       l       %r2,SP_ORIG_R2(%r15)
-        basr    %r14,%r8          # call sys_xxx
-        st      %r2,SP_R2(%r15)   # store return value
-pgm_svc_nogo:
-       tm      __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
-        bz      BASED(pgm_svcret)
-        l       %r1,BASED(.Ltrace)
-       la      %r2,SP_PTREGS(%r15)    # load pt_regs
-       la      %r3,1
-       la      %r14,BASED(pgm_svcret)
-        br      %r1
+       oi      __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+       stosm   24(%r15),0x03           # reenable interrupts
+       b       BASED(sysc_do_svc)
 
 /*
  * IO interrupt handler routine
index 85a9876..533fa85 100644 (file)
@@ -24,7 +24,8 @@
  * Stack layout for the system_call stack entry.
  * The first few entries are identical to the user_regs_struct.
  */
-SP_PTREGS    =  STACK_FRAME_OVERHEAD 
+SP_PTREGS    =  STACK_FRAME_OVERHEAD
+SP_ARGS      =  STACK_FRAME_OVERHEAD + __PT_ARGS
 SP_PSW       =  STACK_FRAME_OVERHEAD + __PT_PSW
 SP_R0        =  STACK_FRAME_OVERHEAD + __PT_GPRS
 SP_R1        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 8
@@ -47,7 +48,8 @@ SP_ILC       =  STACK_FRAME_OVERHEAD + __PT_ILC
 SP_TRAP      =  STACK_FRAME_OVERHEAD + __PT_TRAP
 SP_SIZE      =  STACK_FRAME_OVERHEAD + __PT_SIZE
 
-_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC)
+_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+                _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
 _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
 
 /*
@@ -213,14 +215,17 @@ system_call:
        llgh    %r7,__LC_SVC_INT_CODE # get svc number from lowcore
 sysc_enter:
         GET_THREAD_INFO           # load pointer to task_struct to R9
+sysc_do_svc:
         slag    %r7,%r7,2         # *4 and test for svc 0
-       jnz     sysc_do_restart
+       jnz     sysc_nr_ok
        # svc 0: system call number in %r1
        lghi    %r0,NR_syscalls
        clr     %r1,%r0
-       jnl     sysc_do_restart
+       jnl     sysc_nr_ok
        lgfr    %r7,%r1           # clear high word in r1
        slag    %r7,%r7,2         # svc 0: system call number in %r1
+sysc_nr_ok:
+       mvc     SP_ARGS(8,%r15),SP_R7(%r15)
 sysc_do_restart:
        larl    %r10,sys_call_table
 #ifdef CONFIG_S390_SUPPORT
@@ -254,7 +259,6 @@ sysc_work_loop:
        jz      sysc_leave        # there is no work to do
 #
 # One of the work bits is on. Find out which one.
-# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED
 #
 sysc_work:
        tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
@@ -263,6 +267,8 @@ sysc_work:
        jo      sysc_sigpending
        tm      __TI_flags+7(%r9),_TIF_RESTART_SVC
        jo      sysc_restart
+       tm      __TI_flags+7(%r9),_TIF_SINGLE_STEP
+       jo      sysc_singlestep
        j       sysc_leave
 
 #
@@ -294,6 +300,17 @@ sysc_restart:
        lmg     %r2,%r6,SP_R2(%r15)    # load svc arguments
        j       sysc_do_restart        # restart svc
 
+#
+# _TIF_SINGLE_STEP is set, call do_debugger_trap
+#
+sysc_singlestep:
+       ni      __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
+       mvi     SP_TRAP+1(%r15),0x28    # set trap indication to pgm check
+       la      %r2,SP_PTREGS(%r15)     # address of register-save area
+       larl    %r14,sysc_return        # load adr. of system return
+       jg      do_debugger_trap        # branch to do_debugger_trap
+
+
 __critical_end:
 
 #
@@ -528,75 +545,15 @@ pgm_per_only:
 #
 pgm_svcper:
        SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
-       llgh    %r7,__LC_SVC_INT_CODE # get svc number from lowcore
-        GET_THREAD_INFO           # load pointer to task_struct to R9
+       llgh    %r7,__LC_SVC_INT_CODE   # get svc number from lowcore
+       GET_THREAD_INFO                 # load pointer to task_struct to R9
        lg      %r1,__TI_task(%r9)
        mvc     __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
        mvc     __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
        mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
-       stosm   48(%r15),0x03     # reenable interrupts
-       slag    %r7,%r7,2         # *4 and test for svc 0
-       jnz     pgm_svcstd
-       # svc 0: system call number in %r1
-       lghi    %r0,NR_syscalls
-       clr     %r1,%r0
-       slag    %r7,%r1,2
-pgm_svcstd:
-       larl    %r10,sys_call_table
-#ifdef CONFIG_S390_SUPPORT
-        tm      SP_PSW+3(%r15),0x01  # are we running in 31 bit mode ?
-        jo      pgm_svcper_noemu
-       larl    %r10,sys_call_table_emu # use 31 bit emulation system calls
-pgm_svcper_noemu:
-#endif
-       tm      __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
-        lgf     %r8,0(%r7,%r10)   # load address of system call routine
-        jnz     pgm_tracesys
-        basr    %r14,%r8          # call sys_xxxx
-        stg     %r2,SP_R2(%r15)   # store return value (change R2 on stack)
-                                  # ATTENTION: check sys_execve_glue before
-                                  # changing anything here !!
-
-pgm_svcret:
-       tm      __TI_flags+7(%r9),_TIF_SIGPENDING
-       jno     pgm_svcper_nosig
-        la      %r2,SP_PTREGS(%r15) # load pt_regs
-        sgr     %r3,%r3             # clear *oldset
-       brasl   %r14,do_signal
-       
-pgm_svcper_nosig:
-       lhi     %r0,__LC_PGM_OLD_PSW     # set trap indication back to pgm_chk
-       st      %r0,SP_TRAP(%r15)
-        la      %r2,SP_PTREGS(15) # address of register-save area
-        larl    %r14,sysc_return  # load adr. of system return
-        jg      do_debugger_trap
-#
-# call trace before and after sys_call
-#
-pgm_tracesys:
-       la      %r2,SP_PTREGS(%r15)    # load pt_regs
-       la      %r3,0
-       srlg    %r7,%r7,2
-       stg     %r7,SP_R2(%r15)
-        brasl   %r14,syscall_trace
-       lghi    %r0,NR_syscalls
-       clg     %r0,SP_R2(%r15)
-       jnh     pgm_svc_nogo
-       lg      %r7,SP_R2(%r15)
-       sllg    %r7,%r7,2           # strace wants to change the syscall
-       lgf     %r8,0(%r7,%r10)
-pgm_svc_go:
-       lmg     %r3,%r6,SP_R3(%r15)
-       lg      %r2,SP_ORIG_R2(%r15)
-        basr    %r14,%r8            # call sys_xxx
-        stg     %r2,SP_R2(%r15)     # store return value
-pgm_svc_nogo:
-       tm      __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
-        jz      pgm_svcret
-       la      %r2,SP_PTREGS(%r15)    # load pt_regs
-       la      %r3,1
-       larl    %r14,pgm_svcret     # return point is sysc_return
-       jg      syscall_trace
+       oi      __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+       stosm   48(%r15),0x03           # reenable interrupts
+       j       sysc_do_svc
 
 /*
  * IO interrupt handler routine
index 229f4af..068653a 100644 (file)
@@ -478,9 +478,80 @@ startup:basr  %r13,0                     # get base
         mvcle %r2,%r4,0                 # clear mem
         jo    .-4                       # branch back, if not finish
 
+       l     %r2,.Lrcp-.LPG1(%r13)     # Read SCP forced command word
+.Lservicecall:
+       stosm .Lpmask-.LPG1(%r13),0x01  # authorize ext interrupts
+
+       stctl %r0, %r0,.Lcr-.LPG1(%r13) # get cr0
+       la    %r1,0x200                 # set bit 22
+       o     %r1,.Lcr-.LPG1(%r13)      # or old cr0 with r1
+       st    %r1,.Lcr-.LPG1(%r13)
+       lctl  %r0, %r0,.Lcr-.LPG1(%r13) # load modified cr0
+
+       mvc   __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
+       la    %r1, .Lsclph-.LPG1(%r13)
+       a     %r1,__LC_EXT_NEW_PSW+4    # set handler
+       st    %r1,__LC_EXT_NEW_PSW+4
+
+       la    %r4,_pstart-.LPG1(%r13)   # %r4 is our index for sccb stuff
+       la    %r1, .Lsccb-PARMAREA(%r4) # our sccb
+       .insn rre,0xb2200000,%r2,%r1    # service call
+       ipm   %r1
+       srl   %r1,28                    # get cc code
+       xr    %r3, %r3
+       chi   %r1,3
+       be    .Lfchunk-.LPG1(%r13)      # leave
+       chi   %r1,2
+       be    .Lservicecall-.LPG1(%r13)
+       lpsw  .Lwaitsclp-.LPG1(%r13)
+.Lsclph:
+       lh    %r1,.Lsccbr-PARMAREA(%r4)
+       chi   %r1,0x10                  # 0x0010 is the sucess code
+       je    .Lprocsccb                # let's process the sccb
+       chi   %r1,0x1f0
+       bne   .Lfchunk-.LPG1(%r13)      # unhandled error code
+       c     %r2, .Lrcp-.LPG1(%r13)    # Did we try Read SCP forced
+       bne   .Lfchunk-.LPG1(%r13)      # if no, give up
+       l     %r2, .Lrcp2-.LPG1(%r13)   # try with Read SCP
+       b     .Lservicecall-.LPG1(%r13)
+.Lprocsccb:
+       lh    %r1,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
+       chi   %r1,0x00
+       jne   .Lscnd
+       l     %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one
+.Lscnd:
+       xr    %r3,%r3                   # same logic
+       ic    %r3,.Lscpa1-PARMAREA(%r4)
+       chi   %r3,0x00
+       jne   .Lcompmem
+       l     %r3,.Lscpa2-PARMAREA(%r13)
+.Lcompmem:
+       mr    %r2,%r1                   # mem in MB on 128-bit
+       l     %r1,.Lonemb-.LPG1(%r13)
+       mr    %r2,%r1                   # mem size in bytes in %r3
+       b     .Lfchunk-.LPG1(%r13)
+
+.Lpmask:
+       .byte 0
+.align 8
+.Lpcext:.long  0x00080000,0x80000000
+.Lcr:
+       .long 0x00                      # place holder for cr0
+.Lwaitsclp:
+       .long 0x020A0000
+       .long .Lsclph
+.Lrcp:
+       .int 0x00120001                 # Read SCP forced code
+.Lrcp2:
+       .int 0x00020001                 # Read SCP code
+.Lonemb:
+       .int 0x100000
+.Lfchunk:
+
 #
 # find memory chunks.
 #
+       lr    %r9,%r3                    # end of mem
        mvc   __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
        la    %r1,1                      # test in increments of 128KB
        sll   %r1,17
@@ -488,38 +559,46 @@ startup:basr  %r13,0                     # get base
        slr   %r4,%r4                    # set start of chunk to zero
        slr   %r5,%r5                    # set end of chunk to zero
        slr   %r6,%r6                    # set access code to zero
+       la    %r10, MEMORY_CHUNKS        # number of chunks
 .Lloop:
        tprot 0(%r5),0                   # test protection of first byte
        ipm   %r7
        srl   %r7,28
        clr   %r6,%r7                    # compare cc with last access code
        be    .Lsame-.LPG1(%r13)
-       clr   %r4,%r5                    # chunk size > 0?
-       be    .Lsize0-.LPG1(%r13)
-       st    %r4,0(%r3)                 # store start address of chunk
-       lr    %r0,%r5
-       slr   %r0,%r4
-       st    %r0,4(%r3)                 # store size of chunk
-       st    %r6,8(%r3)                 # store type of chunk
-       la    %r3,12(%r3)
-       lr    %r4,%r5                    # set start to end
-.Lsize0:
-       lr    %r6,%r7                    # set access code to last cc
+       b     .Lchkmem-.LPG1(%r13)
 .Lsame:
        ar    %r5,%r1                    # add 128KB to end of chunk
        bno   .Lloop-.LPG1(%r13)         # r1 < 0x80000000 -> loop
 .Lchkmem:                               # > 2GB or tprot got a program check
        clr   %r4,%r5                    # chunk size > 0?
-       be    .Ldonemem-.LPG1(%r13)
+       be    .Lchkloop-.LPG1(%r13)
        st    %r4,0(%r3)                 # store start address of chunk
        lr    %r0,%r5
        slr   %r0,%r4
        st    %r0,4(%r3)                 # store size of chunk
        st    %r6,8(%r3)                 # store type of chunk
+       la    %r3,12(%r3)
+       l     %r4,.Lmemsize-.LPG1(%r13)  # address of variable memory_size
+       st    %r5,0(%r4)                 # store last end to memory size
+       ahi   %r10,-1                    # update chunk number
+.Lchkloop:
+       lr    %r6,%r7                    # set access code to last cc
+       # we got an exception or we're starting a new
+       # chunk , we must check if we should
+       # still try to find valid memory (if we detected
+       # the amount of available storage), and if we
+       # have chunks left
+       xr    %r0,%r0
+       clr   %r0,%r9                    # did we detect memory?
+       je    .Ldonemem                  # if not, leave
+       chi   %r10,0                     # do we have chunks left?
+       je    .Ldonemem
+       alr   %r5,%r1                    # add 128KB to end of chunk
+       lr    %r4,%r5                    # potential new chunk
+       clr    %r5,%r9                   # should we go on?
+       jl     .Lloop
 .Ldonemem:             
-        l     %r1,.Lmemsize-.LPG1(%r13)  # address of variable memory_size
-       st    %r5,0(%r1)                 # store last end to memory size
-       
         l      %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
 #
 # find out if we are running under VM
@@ -631,6 +710,23 @@ _pstart:
        .byte  "root=/dev/ram0 ro"
         .byte  0
        .org   0x11000
+.Lsccb:
+       .hword 0x1000                   # length, one page
+       .byte 0x00,0x00,0x00
+       .byte 0x80                      # variable response bit set
+.Lsccbr:
+       .hword 0x00                     # response code
+.Lscpincr1:
+       .hword 0x00
+.Lscpa1:
+       .byte 0x00
+       .fill 89,1,0
+.Lscpa2:
+       .int 0x00
+.Lscpincr2:
+       .quad 0x00
+       .fill 3984,1,0
+       .org 0x12000
        .global _pend
 _pend: 
 
index c380e2b..26caebd 100644 (file)
@@ -480,12 +480,81 @@ startup:basr  %r13,0                     # get base
         mvcle %r2,%r4,0                 # clear mem
         jo    .-4                       # branch back, if not finish
 
+       l     %r2,.Lrcp-.LPG1(%r13)     # Read SCP forced command word
+.Lservicecall:
+       stosm .Lpmask-.LPG1(%r13),0x01  # authorize ext interrupts
+
+       stctg %r0,%r0,.Lcr-.LPG1(%r13)  # get cr0
+       la    %r1,0x200                 # set bit 22
+       og    %r1,.Lcr-.LPG1(%r13)      # or old cr0 with r1
+       stg   %r1,.Lcr-.LPG1(%r13)
+       lctlg %r0,%r0,.Lcr-.LPG1(%r13)  # load modified cr0
+
+       mvc   __LC_EXT_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # set postcall psw
+       larl  %r1,.Lsclph
+       stg   %r1,__LC_EXT_NEW_PSW+8    # set handler
+
+       larl  %r4,_pstart               # %r4 is our index for sccb stuff
+       la    %r1,.Lsccb-PARMAREA(%r4)  # our sccb
+       .insn rre,0xb2200000,%r2,%r1    # service call
+       ipm   %r1
+       srl   %r1,28                    # get cc code
+       xr    %r3,%r3
+       chi   %r1,3
+       be    .Lfchunk-.LPG1(%r13)      # leave
+       chi   %r1,2
+       be    .Lservicecall-.LPG1(%r13)
+       lpsw  .Lwaitsclp-.LPG1(%r13)
+.Lsclph:
+       lh    %r1,.Lsccbr-PARMAREA(%r4)
+       chi   %r1,0x10                  # 0x0010 is the sucess code
+       je    .Lprocsccb                # let's process the sccb
+       chi   %r1,0x1f0
+       bne   .Lfchunk-.LPG1(%r13)      # unhandled error code
+       c     %r2,.Lrcp-.LPG1(%r13)     # Did we try Read SCP forced
+       bne   .Lfchunk-.LPG1(%r13)      # if no, give up
+       l     %r2,.Lrcp2-.LPG1(%r13)    # try with Read SCP
+       b     .Lservicecall-.LPG1(%r13)
+.Lprocsccb:
+       lh    %r1,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
+       chi   %r1,0x00
+       jne   .Lscnd
+       lg    %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one
+.Lscnd:
+       xr    %r3,%r3                   # same logic
+       ic    %r3,.Lscpa1-PARMAREA(%r4)
+       chi   %r3,0x00
+       jne   .Lcompmem
+       l     %r3,.Lscpa2-PARMAREA(%r13)
+.Lcompmem:
+       mlgr  %r2,%r1                   # mem in MB on 128-bit
+       l     %r1,.Lonemb-.LPG1(%r13)
+       mlgr  %r2,%r1                   # mem size in bytes in %r3
+       b     .Lfchunk-.LPG1(%r13)
+
+.Lpmask:
+       .byte 0
+       .align 8
+.Lcr:
+       .quad 0x00  # place holder for cr0
+.Lwaitsclp:
+       .long 0x020A0000
+       .quad .Lsclph
+.Lrcp:
+       .int 0x00120001 # Read SCP forced code
+.Lrcp2:
+       .int 0x00020001 # Read SCP code
+.Lonemb:
+       .int 0x100000
+
+.Lfchunk:
                                         # set program check new psw mask
        mvc   __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13)
 
 #
 # find memory chunks.
 #
+       lgr   %r9,%r3                    # end of mem
        larl  %r1,.Lchkmem               # set program check address
        stg   %r1,__LC_PGM_NEW_PSW+8
        la    %r1,1                      # test in increments of 128KB
@@ -494,51 +563,51 @@ startup:basr  %r13,0                     # get base
        slgr  %r4,%r4                    # set start of chunk to zero
        slgr  %r5,%r5                    # set end of chunk to zero
        slr  %r6,%r6                     # set access code to zero
+       la    %r10,MEMORY_CHUNKS         # number of chunks
 .Lloop:
        tprot 0(%r5),0                   # test protection of first byte
        ipm   %r7
        srl   %r7,28
        clr   %r6,%r7                    # compare cc with last access code
        je    .Lsame
-       clgr  %r4,%r5                    # chunk size > 0?
-       je    .Lsize0
-       stg   %r4,0(%r3)                 # store start address of chunk
-       lgr   %r0,%r5
-       slgr  %r0,%r4
-       stg   %r0,8(%r3)                 # store size of chunk
-       st    %r6,20(%r3)                # store type of chunk
-       la    %r3,24(%r3)
-       lgr   %r4,%r5                    # set start to end
-       larl  %r8,memory_size
-       stg   %r5,0(%r8)                 # store memory size
-.Lsize0:
-       lr    %r6,%r7                    # set access code to last cc
+       j     .Lchkmem
 .Lsame:
        algr  %r5,%r1                    # add 128KB to end of chunk
-       brc   12,.Lloop
+                                        # no need to check here,
+       brc   12,.Lloop                  # this is the same chunk
 .Lchkmem:                               # > 16EB or tprot got a program check
        clgr  %r4,%r5                    # chunk size > 0?
-       je    .Ldonemem
+       je    .Lchkloop
        stg   %r4,0(%r3)                 # store start address of chunk
        lgr   %r0,%r5
        slgr  %r0,%r4
        stg   %r0,8(%r3)                 # store size of chunk
        st    %r6,20(%r3)                # store type of chunk
        la    %r3,24(%r3)
-       lgr   %r4,%r5
        larl  %r8,memory_size
        stg   %r5,0(%r8)                 # store memory size
-#
-# Running native the HSA is located at 2GB and we will get an
-# addressing exception trying to access it. We have to restart
-# the scan at 2GB to find out if the machine has more than 2GB.
-#
+       ahi   %r10,-1                    # update chunk number
+.Lchkloop:
+       lr    %r6,%r7                    # set access code to last cc
+       # we got an exception or we're starting a new
+       # chunk , we must check if we should
+       # still try to find valid memory (if we detected
+       # the amount of available storage), and if we
+       # have chunks left
        lghi  %r4,1
        sllg  %r4,%r4,31
        clgr  %r5,%r4
-       jhe   .Ldonemem
-       lgr   %r5,%r4
-       j     .Lloop
+       je    .Lhsaskip
+       xr    %r0, %r0
+       clgr  %r0, %r9                   # did we detect memory?
+       je    .Ldonemem                  # if not, leave
+       chi   %r10, 0                    # do we have chunks left?
+       je    .Ldonemem
+.Lhsaskip:
+       algr  %r5,%r1                    # add 128KB to end of chunk
+       lgr   %r4,%r5                    # potential new chunk
+       clgr  %r5,%r9                    # should we go on?
+       jl    .Lloop
 .Ldonemem:             
 
        larl  %r12,machine_flags
@@ -640,6 +709,23 @@ _pstart:
        .byte  "root=/dev/ram0 ro"
         .byte  0
        .org   0x11000
+.Lsccb:
+       .hword 0x1000                   # length, one page
+       .byte 0x00,0x00,0x00
+       .byte 0x80                      # variable response bit set
+.Lsccbr:
+       .hword 0x00                     # response code
+.Lscpincr1:
+       .hword 0x00
+.Lscpa1:
+       .byte 0x00
+       .fill 89,1,0
+.Lscpa2:
+       .int 0x00
+.Lscpincr2:
+       .quad 0x00
+       .fill 3984,1,0
+       .org 0x12000
        .global _pend
 _pend: 
 
index 652c423..d73a740 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/init_task.h>
+#include <linux/mqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
index a18d5f4..63818a5 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -292,12 +293,12 @@ asmlinkage long sys_clone(struct pt_regs regs)
 {
         unsigned long clone_flags;
         unsigned long newsp;
-       int *parent_tidptr, *child_tidptr;
+       int __user *parent_tidptr, *child_tidptr;
 
         clone_flags = regs.gprs[3];
         newsp = regs.orig_gpr2;
-       parent_tidptr = (int *) regs.gprs[4];
-       child_tidptr = (int *) regs.gprs[5];
+       parent_tidptr = (int __user *) regs.gprs[4];
+       child_tidptr = (int __user *) regs.gprs[5];
         if (!newsp)
                 newsp = regs.gprs[15];
         return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0,
@@ -328,12 +329,12 @@ asmlinkage long sys_execve(struct pt_regs regs)
         int error;
         char * filename;
 
-        filename = getname((char *) regs.orig_gpr2);
+        filename = getname((char __user *) regs.orig_gpr2);
         error = PTR_ERR(filename);
         if (IS_ERR(filename))
                 goto out;
-        error = do_execve(filename, (char **) regs.gprs[3],
-                         (char **) regs.gprs[4], &regs);
+        error = do_execve(filename, (char __user * __user *) regs.gprs[3],
+                         (char __user * __user *) regs.gprs[4], &regs);
        if (error == 0) {
                current->ptrace &= ~PT_DTRACE;
                current->thread.fp_regs.fpc = 0;
index a6fad9c..f219748 100644 (file)
@@ -19,7 +19,8 @@ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
        return len;
 }
 
-static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
+static int prof_cpu_mask_write_proc (struct file *file,
+                                       const char __user *buffer,
                                        unsigned long count, void *data)
 {
        cpumask_t *mask = (cpumask_t *)data;
index 1176b4f..a0ddc4f 100644 (file)
@@ -141,7 +141,7 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
                /*
                 * psw and gprs are stored on the stack
                 */
-               tmp = *(addr_t *)((addr_t) __KSTK_PTREGS(child) + addr);
+               tmp = *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr);
                if (addr == (addr_t) &dummy->regs.psw.mask)
                        /* Remove per bit from user psw. */
                        tmp &= ~PSW_MASK_PER;
@@ -176,7 +176,7 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
        } else
                tmp = 0;
 
-       return put_user(tmp, (addr_t *) data);
+       return put_user(tmp, (addr_t __user *) data);
 }
 
 /*
@@ -215,7 +215,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
                           high order bit but older gdb's rely on it */
                        data |= PSW_ADDR_AMODE;
 #endif
-               *(addr_t *)((addr_t) __KSTK_PTREGS(child) + addr) = data;
+               *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr) = data;
 
        } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
                /*
@@ -269,7 +269,7 @@ do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
                copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
                if (copied != sizeof(tmp))
                        return -EIO;
-               return put_user(tmp, (unsigned long *) data);
+               return put_user(tmp, (unsigned long __user *) data);
 
        case PTRACE_PEEKUSR:
                /* read the word at location addr in the USER area. */
@@ -291,7 +291,8 @@ do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
 
        case PTRACE_PEEKUSR_AREA:
        case PTRACE_POKEUSR_AREA:
-               if (copy_from_user(&parea, (void *) addr, sizeof(parea)))
+               if (copy_from_user(&parea, (void __user *) addr,
+                                                       sizeof(parea)))
                        return -EFAULT;
                addr = parea.kernel_addr;
                data = parea.process_addr;
@@ -301,7 +302,7 @@ do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
                                ret = peek_user(child, addr, data);
                        else {
                                addr_t tmp;
-                               if (get_user (tmp, (addr_t *) data))
+                               if (get_user (tmp, (addr_t __user *) data))
                                        return -EFAULT;
                                ret = poke_user(child, addr, tmp);
                        }
@@ -360,7 +361,7 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
                                PSW32_ADDR_AMODE31;
                } else {
                        /* gpr 0-15 */
-                       tmp = *(__u32 *)((addr_t) __KSTK_PTREGS(child) + 
+                       tmp = *(__u32 *)((addr_t) &__KSTK_PTREGS(child)->psw +
                                         addr*2 + 4);
                }
        } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
@@ -402,7 +403,7 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
        } else
                tmp = 0;
 
-       return put_user(tmp, (__u32 *) data);
+       return put_user(tmp, (__u32 __user *) data);
 }
 
 /*
@@ -439,8 +440,8 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
                                (__u64) tmp & PSW32_ADDR_INSN;
                } else {
                        /* gpr 0-15 */
-                       *(__u32*)((addr_t) __KSTK_PTREGS(child) + addr*2 + 4) =
-                               tmp;
+                       *(__u32*)((addr_t) &__KSTK_PTREGS(child)->psw
+                                 + addr*2 + 4) = tmp;
                }
        } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
                /*
@@ -509,7 +510,7 @@ do_ptrace_emu31(struct task_struct *child, long request, long addr, long data)
                copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
                if (copied != sizeof(tmp))
                        return -EIO;
-               return put_user(tmp, (unsigned int *) data);
+               return put_user(tmp, (unsigned int __user *) data);
 
        case PTRACE_PEEKUSR:
                /* read the word at location addr in the USER area. */
@@ -530,7 +531,8 @@ do_ptrace_emu31(struct task_struct *child, long request, long addr, long data)
 
        case PTRACE_PEEKUSR_AREA:
        case PTRACE_POKEUSR_AREA:
-               if (copy_from_user(&parea, (void *) addr, sizeof(parea)))
+               if (copy_from_user(&parea, (void __user *) addr,
+                                                       sizeof(parea)))
                        return -EFAULT;
                addr = parea.kernel_addr;
                data = parea.process_addr;
@@ -540,7 +542,7 @@ do_ptrace_emu31(struct task_struct *child, long request, long addr, long data)
                                ret = peek_user_emu31(child, addr, data);
                        else {
                                __u32 tmp;
-                               if (get_user (tmp, (__u32 *) data))
+                               if (get_user (tmp, (__u32 __user *) data))
                                        return -EFAULT;
                                ret = poke_user_emu31(child, addr, tmp);
                        }
index 832e758..5ba86ba 100644 (file)
@@ -44,25 +44,6 @@ EXPORT_SYMBOL(__up);
 EXPORT_SYMBOL(__down);
 EXPORT_SYMBOL(__down_interruptible);
 
-/*
- * string functions
- */
-EXPORT_SYMBOL_NOVERS(memcmp);
-EXPORT_SYMBOL_NOVERS(memset);
-EXPORT_SYMBOL_NOVERS(memmove);
-EXPORT_SYMBOL_NOVERS(memscan);
-EXPORT_SYMBOL_NOVERS(strlen);
-EXPORT_SYMBOL_NOVERS(strchr);
-EXPORT_SYMBOL_NOVERS(strcmp);
-EXPORT_SYMBOL_NOVERS(strncat);
-EXPORT_SYMBOL_NOVERS(strncmp);
-EXPORT_SYMBOL_NOVERS(strncpy);
-EXPORT_SYMBOL_NOVERS(strnlen);
-EXPORT_SYMBOL_NOVERS(strrchr);
-EXPORT_SYMBOL_NOVERS(strstr);
-EXPORT_SYMBOL_NOVERS(strpbrk);
-EXPORT_SYMBOL_NOVERS(strcpy);
-
 /*
  * binfmt_elf loader 
  */
index 7ca8a87..d549ad5 100644 (file)
@@ -53,7 +53,9 @@ unsigned int console_device = -1;
 unsigned int console_irq = -1;
 unsigned long memory_size = 0;
 unsigned long machine_flags = 0;
-struct { unsigned long addr, size, type; } memory_chunk[16] = { { 0 } };
+struct {
+       unsigned long addr, size, type;
+} memory_chunk[MEMORY_CHUNKS] = { { 0 } };
 #define CHUNK_READ_WRITE 0
 #define CHUNK_READ_ONLY 1
 int cpus_initialized = 0;
index 2379b67..d32b2c4 100644 (file)
@@ -77,8 +77,9 @@ sys_sigsuspend(struct pt_regs * regs, int history0, int history1,
        }
 }
 
-asmlinkage int
-sys_rt_sigsuspend(struct pt_regs * regs,sigset_t *unewset, size_t sigsetsize)
+asmlinkage long
+sys_rt_sigsuspend(struct pt_regs *regs, sigset_t __user *unewset,
+                                               size_t sigsetsize)
 {
        sigset_t saveset, newset;
 
@@ -105,9 +106,9 @@ sys_rt_sigsuspend(struct pt_regs * regs,sigset_t *unewset, size_t sigsetsize)
        }
 }
 
-asmlinkage int 
-sys_sigaction(int sig, const struct old_sigaction *act,
-             struct old_sigaction *oact)
+asmlinkage long
+sys_sigaction(int sig, const struct old_sigaction __user *act,
+             struct old_sigaction __user *oact)
 {
        struct k_sigaction new_ka, old_ka;
        int ret;
@@ -137,8 +138,9 @@ sys_sigaction(int sig, const struct old_sigaction *act,
        return ret;
 }
 
-asmlinkage int
-sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs *regs)
+asmlinkage long
+sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
+                                       struct pt_regs *regs)
 {
        return do_sigaltstack(uss, uoss, regs->gprs[15]);
 }
@@ -146,7 +148,7 @@ sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs *regs)
 
 
 /* Returns non-zero on fault. */
-static int save_sigregs(struct pt_regs *regs, _sigregs *sregs)
+static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
 {
        unsigned long old_mask = regs->psw.mask;
        int err;
@@ -175,7 +177,7 @@ static int save_sigregs(struct pt_regs *regs, _sigregs *sregs)
 }
 
 /* Returns positive number on error */
-static int restore_sigregs(struct pt_regs *regs, _sigregs *sregs)
+static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
 {
        unsigned long old_mask = regs->psw.mask;
        int err;
@@ -208,7 +210,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs *sregs)
 
 asmlinkage long sys_sigreturn(struct pt_regs *regs)
 {
-       sigframe *frame = (sigframe *)regs->gprs[15];
+       sigframe __user *frame = (sigframe __user *)regs->gprs[15];
        sigset_t set;
 
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
@@ -234,7 +236,7 @@ badframe:
 
 asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 {
-       rt_sigframe *frame = (rt_sigframe *)regs->gprs[15];
+       rt_sigframe __user *frame = (rt_sigframe __user *)regs->gprs[15];
        sigset_t set;
 
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
@@ -269,7 +271,7 @@ badframe:
 /*
  * Determine which stack to use..
  */
-static inline void *
+static inline void __user *
 get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
 {
        unsigned long sp;
@@ -290,7 +292,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
                sp = (unsigned long) ka->sa.sa_restorer;
        }
 
-       return (void *)((sp - frame_size) & -8ul);
+       return (void __user *)((sp - frame_size) & -8ul);
 }
 
 static inline int map_signal(int sig)
@@ -306,7 +308,9 @@ static inline int map_signal(int sig)
 static void setup_frame(int sig, struct k_sigaction *ka,
                        sigset_t *set, struct pt_regs * regs)
 {
-       sigframe *frame = get_sigframe(ka, regs, sizeof(sigframe));
+       sigframe __user *frame;
+
+       frame = get_sigframe(ka, regs, sizeof(sigframe));
        if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe)))
                goto give_sigsegv;
 
@@ -326,13 +330,13 @@ static void setup_frame(int sig, struct k_sigaction *ka,
        } else {
                 regs->gprs[14] = (unsigned long)
                        frame->retcode | PSW_ADDR_AMODE;
-               if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, 
-                              (u16 *)(frame->retcode)))
+               if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
+                              (u16 __user *)(frame->retcode)))
                        goto give_sigsegv;
        }
 
        /* Set up backchain. */
-       if (__put_user(regs->gprs[15], (addr_t *) frame))
+       if (__put_user(regs->gprs[15], (addr_t __user *) frame))
                goto give_sigsegv;
 
        /* Set up registers for signal handler */
@@ -358,7 +362,9 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                           sigset_t *set, struct pt_regs * regs)
 {
        int err = 0;
-       rt_sigframe *frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
+       rt_sigframe __user *frame;
+
+       frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
        if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe)))
                goto give_sigsegv;
 
@@ -385,12 +391,12 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        } else {
                 regs->gprs[14] = (unsigned long)
                        frame->retcode | PSW_ADDR_AMODE;
-               err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, 
-                                 (u16 *)(frame->retcode));
+               err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
+                                 (u16 __user *)(frame->retcode));
        }
 
        /* Set up backchain. */
-       if (__put_user(regs->gprs[15], (addr_t *) frame))
+       if (__put_user(regs->gprs[15], (addr_t __user *) frame))
                goto give_sigsegv;
 
        /* Set up registers for signal handler */
index c51ff0d..9ea8bec 100644 (file)
@@ -37,7 +37,7 @@
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way Unix traditionally does this, though.
  */
-asmlinkage long sys_pipe(unsigned long fildes)
+asmlinkage long sys_pipe(unsigned long __user *fildes)
 {
        int fd[2];
        int error;
@@ -92,7 +92,7 @@ struct mmap_arg_struct {
        unsigned long offset;
 };
 
-asmlinkage long sys_mmap2(struct mmap_arg_struct *arg)
+asmlinkage long sys_mmap2(struct mmap_arg_struct __user  *arg)
 {
        struct mmap_arg_struct a;
        int error = -EFAULT;
@@ -104,7 +104,7 @@ out:
        return error;
 }
 
-asmlinkage long old_mmap(struct mmap_arg_struct *arg)
+asmlinkage long old_mmap(struct mmap_arg_struct __user *arg)
 {
        struct mmap_arg_struct a;
        long error = -EFAULT;
@@ -128,7 +128,7 @@ struct sel_arg_struct {
        struct timeval *tvp;
 };
 
-asmlinkage long old_select(struct sel_arg_struct *arg)
+asmlinkage long old_select(struct sel_arg_struct __user *arg)
 {
        struct sel_arg_struct a;
 
@@ -145,37 +145,37 @@ asmlinkage long old_select(struct sel_arg_struct *arg)
  *
  * This is really horribly ugly.
  */
-asmlinkage long sys_ipc (uint call, int first, int second,
-                                 unsigned long third, void *ptr)
+asmlinkage long sys_ipc(uint call, int first, int second,
+                                 unsigned long third, void __user *ptr)
 {
         struct ipc_kludge tmp;
        int ret;
 
         switch (call) {
         case SEMOP:
-               return sys_semtimedop (first, (struct sembuf *) ptr, second,
+               return sys_semtimedop (first, (struct sembuf __user *) ptr, second,
                                       NULL);
        case SEMTIMEDOP:
-               return sys_semtimedop (first, (struct sembuf *) ptr, second,
-                                      (const struct timespec *) third);
+               return sys_semtimedop (first, (struct sembuf __user *) ptr, second,
+                                      (const struct timespec __user *) third);
         case SEMGET:
                 return sys_semget (first, second, third);
         case SEMCTL: {
                 union semun fourth;
                 if (!ptr)
                         return -EINVAL;
-                if (get_user(fourth.__pad, (void **) ptr))
+                if (get_user(fourth.__pad, (void __user * __user *) ptr))
                         return -EFAULT;
                 return sys_semctl (first, second, third, fourth);
-        } 
+        }
         case MSGSND:
-               return sys_msgsnd (first, (struct msgbuf *) ptr, 
+               return sys_msgsnd (first, (struct msgbuf __user *) ptr,
                                    second, third);
                break;
         case MSGRCV:
                 if (!ptr)
                         return -EINVAL;
-                if (copy_from_user (&tmp, (struct ipc_kludge *) ptr,
+                if (copy_from_user (&tmp, (struct ipc_kludge __user *) ptr,
                                     sizeof (struct ipc_kludge)))
                         return -EFAULT;
                 return sys_msgrcv (first, tmp.msgp,
@@ -183,33 +183,33 @@ asmlinkage long sys_ipc (uint call, int first, int second,
         case MSGGET:
                 return sys_msgget ((key_t) first, second);
         case MSGCTL:
-                return sys_msgctl (first, second, (struct msqid_ds *) ptr);
-                
+                return sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
+
        case SHMAT: {
                ulong raddr;
-               ret = do_shmat (first, (char *) ptr, second, &raddr);
+               ret = do_shmat (first, (char __user *) ptr, second, &raddr);
                if (ret)
                        return ret;
-               return put_user (raddr, (ulong *) third);
+               return put_user (raddr, (ulong __user *) third);
                break;
         }
-       case SHMDT: 
-               return sys_shmdt ((char *)ptr);
+       case SHMDT:
+               return sys_shmdt ((char __user *)ptr);
        case SHMGET:
                return sys_shmget (first, second, third);
        case SHMCTL:
                return sys_shmctl (first, second,
-                                   (struct shmid_ds *) ptr);
+                                   (struct shmid_ds __user *) ptr);
        default:
                return -ENOSYS;
 
        }
-        
+
        return -EINVAL;
 }
 
 #ifdef CONFIG_ARCH_S390X
-asmlinkage long s390x_newuname(struct new_utsname name)
+asmlinkage long s390x_newuname(struct new_utsname __user *name)
 {
        int ret = sys_newuname(name);
 
@@ -256,7 +256,7 @@ struct fadvise64_64_args {
 };
 
 asmlinkage long
-s390_fadvise64_64(struct fadvise64_64_args *args)
+s390_fadvise64_64(struct fadvise64_64_args __user *args)
 {
        struct fadvise64_64_args a;
 
index b2e8387..537700f 100644 (file)
@@ -188,7 +188,7 @@ void show_registers(struct pt_regs *regs)
        printk("%s Code: ", mode);
        for (i = 0; i < 20; i++) {
                unsigned char c;
-               if (__get_user(c, (char *)(regs->psw.addr + i))) {
+               if (__get_user(c, (char __user *)(regs->psw.addr + i))) {
                        printk(" Bad PSW.");
                        break;
                }
@@ -391,7 +391,7 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
                local_irq_enable();
 
        if (regs->psw.mask & PSW_MASK_PSTATE)
-               get_user(*((__u16 *) opcode), location);
+               get_user(*((__u16 *) opcode), (__u16 __user *)location);
        else
                *((__u16 *)opcode)=*((__u16 *)location);
        if (*((__u16 *)opcode)==S390_BREAKPOINT_U16)
index 3cf8418..a8758b1 100644 (file)
@@ -4,6 +4,6 @@
 
 EXTRA_AFLAGS := -traditional
 
-lib-y += delay.o 
-lib-$(CONFIG_ARCH_S390_31) += memset.o strcmp.o strcpy.o strncpy.o uaccess.o
-lib-$(CONFIG_ARCH_S390X) += memset64.o strcmp64.o strcpy64.o strncpy64.o uaccess64.o
+lib-y += delay.o string.o
+lib-$(CONFIG_ARCH_S390_31) += uaccess.o
+lib-$(CONFIG_ARCH_S390X) += uaccess64.o
index ef26df4..e8029ef 100644 (file)
@@ -154,46 +154,57 @@ __clear_user_asm:
         .align 4
         .text
         .globl __strncpy_from_user_asm
-       # %r2 = dst, %r3 = src, %r4 = count
+       # %r2 = count, %r3 = dst, %r4 = src
 __strncpy_from_user_asm:
        lhi     %r0,0
-       lhi     %r1,1
-       lhi     %r5,0
-0:     mvcp    0(%r1,%r2),0(%r3),%r0
-       tm      0(%r2),0xff
-       jz      1f
-       la      %r2,1(%r2)
-       la      %r3,1(%r3)
-       ahi     %r5,1
-       clr     %r5,%r4
-       jl      0b
-1:     lr      %r2,%r5
+       lr      %r1,%r4
+       la      %r4,0(%r4)      # clear high order bit from %r4
+       la      %r2,0(%r2,%r4)  # %r2 points to first byte after string
+       sacf    256
+0:     srst    %r2,%r1
+       jo      0b
+       sacf    0
+       lr      %r1,%r2
+       jh      1f              # \0 found in string ?
+       ahi     %r1,1           # include \0 in copy
+1:     slr     %r1,%r4         # %r1 = copy length (without \0)
+       slr     %r2,%r4         # %r2 = return length (including \0)
+2:     mvcp    0(%r1,%r3),0(%r4),%r0
+       jnz     3f
        br      %r14
-2:     lhi     %r2,-EFAULT
+3:     la      %r3,256(%r3)
+       la      %r4,256(%r4)
+       ahi     %r1,-256
+       mvcp    0(%r1,%r3),0(%r4),%r0
+       jnz     3b
        br      %r14
-        .section __ex_table,"a"
-       .long   0b,2b
+4:     sacf    0
+       lhi     %r2,-EFAULT
+       br      %r14
+       .section __ex_table,"a"
+       .long   0b,4b
        .previous
 
         .align 4
         .text
         .globl __strnlen_user_asm
-       # %r2 = src, %r3 = count
+       # %r2 = count, %r3 = src
 __strnlen_user_asm:
        lhi     %r0,0
-       lhi     %r1,1
-       lhi     %r5,0
-0:     mvcp    24(%r1,%r15),0(%r2),%r0
-       ahi     %r5,1
-       tm      24(%r15),0xff
-       jz      1f
-       la      %r2,1(%r2)
-       clr     %r5,%r3
-       jl      0b
-1:     lr      %r2,%r5
+       lr      %r1,%r3
+       la      %r3,0(%r3)      # clear high order bit from %r4
+       la      %r2,0(%r2,%r3)  # %r2 points to first byte after string
+       sacf    256
+0:     srst    %r2,%r1
+       jo      0b
+       sacf    0
+       jh      1f              # \0 found in string ?
+       ahi     %r2,1           # strnlen_user result includes the \0
+1:     slr     %r2,%r3
        br      %r14
-2:     lhi     %r2,-EFAULT
+2:     sacf    0
+       lhi     %r2,-EFAULT
        br      %r14
-        .section __ex_table,"a"
+       .section __ex_table,"a"
        .long   0b,2b
        .previous
index c12f70a..0ca5697 100644 (file)
@@ -152,46 +152,55 @@ __clear_user_asm:
         .align 4
         .text
         .globl __strncpy_from_user_asm
-       # %r2 = dst, %r3 = src, %r4 = count
+       # %r2 = count, %r3 = dst, %r4 = src
 __strncpy_from_user_asm:
        lghi    %r0,0
-       lghi    %r1,1
-       lghi    %r5,0
-0:     mvcp    0(%r1,%r2),0(%r3),%r0
-       tm      0(%r2),0xff
-       jz      1f
-       la      %r2,1(%r2)
-       la      %r3,1(%r3)
-       aghi    %r5,1
-       clgr    %r5,%r4
-       jl      0b
-1:     lgr     %r2,%r5
+       lgr     %r1,%r4
+       la      %r2,0(%r2,%r4)  # %r2 points to first byte after string
+       sacf    256
+0:     srst    %r2,%r1
+       jo      0b
+       sacf    0
+       lgr     %r1,%r2
+       jh      1f              # \0 found in string ?
+       aghi    %r1,1           # include \0 in copy
+1:     slgr    %r1,%r4         # %r1 = copy length (without \0)
+       slgr    %r2,%r4         # %r2 = return length (including \0)
+2:     mvcp    0(%r1,%r3),0(%r4),%r0
+       jnz     3f
        br      %r14
-2:     lghi    %r2,-EFAULT
+3:     la      %r3,256(%r3)
+       la      %r4,256(%r4)
+       aghi    %r1,-256
+       mvcp    0(%r1,%r3),0(%r4),%r0
+       jnz     3b
        br      %r14
-        .section __ex_table,"a"
-       .quad   0b,2b
+4:     sacf    0
+       lghi    %r2,-EFAULT
+       br      %r14
+       .section __ex_table,"a"
+       .quad   0b,4b
        .previous
 
         .align 4
         .text
         .globl __strnlen_user_asm
-       # %r2 = src, %r3 = count
+       # %r2 = count, %r3 = src
 __strnlen_user_asm:
        lghi    %r0,0
-       lghi    %r1,1
-       lghi    %r5,0
-0:     mvcp    24(%r1,%r15),0(%r2),%r0
-       aghi    %r5,1
-       tm      24(%r15),0xff
-       jz      1f
-       la      %r2,1(%r2)
-       clgr    %r5,%r3
-       jl      0b
-1:     lgr     %r2,%r5
+       lgr     %r1,%r3
+       la      %r2,0(%r2,%r3)  # %r2 points to first byte after string
+       sacf    256
+0:     srst    %r2,%r1
+       jo      0b
+       sacf    0
+       jh      1f              # \0 found in string ?
+       aghi    %r2,1           # strnlen_user result includes the \0
+1:     slgr    %r2,%r3
        br      %r14
-2:     lghi    %r2,-EFAULT
+2:     sacf    0
+       lghi    %r2,-EFAULT
        br      %r14
-        .section __ex_table,"a"
+       .section __ex_table,"a"
        .quad   0b,2b
        .previous
index ea3db12..b0b2714 100644 (file)
@@ -55,7 +55,9 @@ struct dcss_segment {
 
 static spinlock_t dcss_lock = SPIN_LOCK_UNLOCKED;
 static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list);
-extern struct {unsigned long addr, size, type;} memory_chunk[16];
+extern struct {
+       unsigned long addr, size, type;
+} memory_chunk[MEMORY_CHUNKS];
 
 /*
  * Create the 8 bytes, ebcdic VM segment name from
@@ -258,16 +260,16 @@ int segment_load(char *name, int segtype, unsigned long *addr,
                    shared segment */
                 dcss_diag_query(dcss_name, &rwattr, &shattr, &segstart, &segend);
                /* does segment collide with main memory? */
-               for (i=0; i<16; i++) {
-                                       if (memory_chunk[i].type != 0)
-                                               continue;
-                                       if (memory_chunk[i].addr > segend)
-                                               continue;
-                                       if (memory_chunk[i].addr + memory_chunk[i].size <= segstart)
-                                               continue;
-                                       spin_unlock(&dcss_lock);
-                                       return -ENOENT;
-                               }
+               for (i=0; i < MEMORY_CHUNKS; i++) {
+                       if (memory_chunk[i].type != 0)
+                               continue;
+                       if (memory_chunk[i].addr > segend)
+                               continue;
+                       if (memory_chunk[i].addr + memory_chunk[i].size <= segstart)
+                               continue;
+                       spin_unlock(&dcss_lock);
+                       return -ENOENT;
+               }
                /* or does it collide with other (loaded) segments? */
                list_for_each(l, &dcss_list) {
                        tmp = list_entry(l, struct dcss_segment, list);
index b0e1ba5..c6c39d8 100644 (file)
@@ -134,5 +134,5 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
 void iounmap(void *addr)
 {
        if (addr > high_memory)
-               return vfree(addr);
+               vfree(addr);
 }
index 469a988..44053ea 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/init_task.h>
+#include <linux/mqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
index 0b29e5f..af81a99 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/init_task.h>
+#include <linux/mqueue.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -22,6 +23,6 @@ EXPORT_SYMBOL(init_task);
  * in etrap.S which assumes it.
  */
 union thread_union init_thread_union
-       __attribute__((section (".text")))
+       __attribute__((section (".text,#alloc")))
        __attribute__((aligned (THREAD_SIZE)))
        = { INIT_THREAD_INFO(init_task) };
index 3a1ccac..a9a9e0c 100644 (file)
@@ -137,8 +137,8 @@ static inline unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *re
        return &win->locals[reg - 16];
 }
 
-static inline unsigned long compute_effective_address(struct pt_regs *regs,
-                                                     unsigned int insn)
+static unsigned long compute_effective_address(struct pt_regs *regs,
+                                              unsigned int insn)
 {
        unsigned int rs1 = (insn >> 14) & 0x1f;
        unsigned int rs2 = insn & 0x1f;
@@ -153,8 +153,8 @@ static inline unsigned long compute_effective_address(struct pt_regs *regs,
        }
 }
 
-static inline unsigned long safe_compute_effective_address(struct pt_regs *regs,
-                                                          unsigned int insn)
+unsigned long safe_compute_effective_address(struct pt_regs *regs,
+                                            unsigned int insn)
 {
        unsigned int rs1 = (insn >> 14) & 0x1f;
        unsigned int rs2 = insn & 0x1f;
index 44db335..cc857f6 100644 (file)
@@ -201,6 +201,25 @@ asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc,
        return 0;
 }
 
+extern unsigned long safe_compute_effective_address(struct pt_regs *,
+                                                   unsigned int);
+
+static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault)
+{
+       unsigned int insn;
+
+       if (text_fault)
+               return regs->pc;
+
+       if (regs->psr & PSR_PS) {
+               insn = *(unsigned int *) regs->pc;
+       } else {
+               __get_user(insn, (unsigned int *) regs->pc);
+       }
+
+       return safe_compute_effective_address(regs, insn);
+}
+
 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
                               unsigned long address)
 {
@@ -307,7 +326,7 @@ bad_area_nosemaphore:
                info.si_errno = 0;
                /* info.si_code set above to make clear whether
                   this was a SEGV_MAPERR or SEGV_ACCERR fault.  */
-               info.si_addr = (void *)address;
+               info.si_addr = (void *) compute_si_addr(regs, text_fault);
                info.si_trapno = 0;
                force_sig_info (SIGSEGV, &info, tsk);
                return;
@@ -361,7 +380,7 @@ do_sigbus:
        info.si_signo = SIGBUS;
        info.si_errno = 0;
        info.si_code = BUS_ADRERR;
-       info.si_addr = (void *)address;
+       info.si_addr = (void *) compute_si_addr(regs, text_fault);
        info.si_trapno = 0;
        force_sig_info (SIGBUS, &info, tsk);
        if (!from_user)
@@ -530,7 +549,7 @@ bad_area:
        info.si_errno = 0;
        /* info.si_code set above to make clear whether
           this was a SEGV_MAPERR or SEGV_ACCERR fault.  */
-       info.si_addr = (void *)address;
+       info.si_addr = (void *) address;
        info.si_trapno = 0;
        force_sig_info (SIGSEGV, &info, tsk);
        return;
@@ -540,7 +559,7 @@ do_sigbus:
        info.si_signo = SIGBUS;
        info.si_errno = 0;
        info.si_code = BUS_ADRERR;
-       info.si_addr = (void *)address;
+       info.si_addr = (void *) address;
        info.si_trapno = 0;
        force_sig_info (SIGBUS, &info, tsk);
 }
index 810a7ed..45469d2 100644 (file)
@@ -174,7 +174,7 @@ static inline int srmmu_pmd_present(pmd_t pmd)
 
 static inline void srmmu_pmd_clear(pmd_t *pmdp) {
        int i;
-       for (i = 0; i < SRMMU_PTRS_PER_PTE_SOFT/SRMMU_PTRS_PER_PTE; i++)
+       for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++)
                srmmu_set_pte((pte_t *)&pmdp->pmdv[i], __pte(0));
 }
 
@@ -234,9 +234,9 @@ static void srmmu_pmd_set(pmd_t *pmdp, pte_t *ptep)
        int i;
 
        ptp = __nocache_pa((unsigned long) ptep) >> 4;
-       for (i = 0; i < SRMMU_PTRS_PER_PTE_SOFT/SRMMU_PTRS_PER_PTE; i++) {
+       for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) {
                srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
-               ptp += (SRMMU_PTRS_PER_PTE*sizeof(pte_t) >> 4);
+               ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4);
        }
 }
 
@@ -246,9 +246,9 @@ static void srmmu_pmd_populate(pmd_t *pmdp, struct page *ptep)
        int i;
 
        ptp = page_to_pfn(ptep) << (PAGE_SHIFT-4);      /* watch for overflow */
-       for (i = 0; i < SRMMU_PTRS_PER_PTE_SOFT/SRMMU_PTRS_PER_PTE; i++) {
+       for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) {
                srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
-               ptp += (SRMMU_PTRS_PER_PTE*sizeof(pte_t) >> 4);
+               ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4);
        }
 }
 
@@ -263,7 +263,7 @@ extern inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long addre
 static inline pmd_t *srmmu_pmd_offset(pgd_t * dir, unsigned long address)
 {
        return (pmd_t *) srmmu_pgd_page(*dir) +
-           ((address >> SRMMU_PMD_SHIFT_SOFT) & (SRMMU_PTRS_PER_PMD_SOFT - 1));
+           ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
 }
 
 /* Find an entry in the third-level page table.. */ 
@@ -273,7 +273,7 @@ static inline pte_t *srmmu_pte_offset(pmd_t * dir, unsigned long address)
 
        pte = __nocache_va((dir->pmdv[0] & SRMMU_PTD_PMASK) << 4);
        return (pte_t *) pte +
-           ((address >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE_SOFT - 1));
+           ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
 }
 
 static unsigned long srmmu_swp_type(swp_entry_t entry)
@@ -487,7 +487,7 @@ static void srmmu_pmd_free(pmd_t * pmd)
 static pte_t *
 srmmu_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
-       return (pte_t *)srmmu_get_nocache(SRMMU_PTE_SZ_SOFT, SRMMU_PTE_SZ_SOFT);
+       return (pte_t *)srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
 }
 
 static struct page *
@@ -502,7 +502,7 @@ srmmu_pte_alloc_one(struct mm_struct *mm, unsigned long address)
 
 static void srmmu_free_pte_fast(pte_t *pte)
 {
-       srmmu_free_nocache((unsigned long)pte, SRMMU_PTE_SZ_SOFT);
+       srmmu_free_nocache((unsigned long)pte, PTE_SIZE);
 }
 
 static void srmmu_pte_free(struct page *pte)
@@ -514,7 +514,7 @@ static void srmmu_pte_free(struct page *pte)
                BUG();
        p = page_to_pfn(pte) << PAGE_SHIFT;     /* Physical address */
        p = (unsigned long) __nocache_va(p);    /* Nocached virtual */
-       srmmu_free_nocache(p, SRMMU_PTE_SZ_SOFT);
+       srmmu_free_nocache(p, PTE_SIZE);
 }
 
 /*
@@ -829,7 +829,7 @@ static void cypress_flush_cache_range(struct vm_area_struct *vma, unsigned long
        a = 0x20; b = 0x40; c = 0x60;
        d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
 
-       start &= SRMMU_PMD_MASK;
+       start &= SRMMU_REAL_PMD_MASK;
        while(start < end) {
                faddr = (start + (0x10000 - 0x100));
                goto inside;
@@ -849,7 +849,7 @@ static void cypress_flush_cache_range(struct vm_area_struct *vma, unsigned long
                                             "r" (a), "r" (b), "r" (c), "r" (d),
                                             "r" (e), "r" (f), "r" (g));
                } while (faddr != start);
-               start += SRMMU_PMD_SIZE;
+               start += SRMMU_REAL_PMD_SIZE;
        }
        srmmu_set_context(octx);
        local_irq_restore(flags);
@@ -1067,16 +1067,15 @@ void __init srmmu_early_allocate_ptable_skeleton(unsigned long start, unsigned l
                }
                pmdp = srmmu_pmd_offset(__nocache_fix(pgdp), start);
                if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
-                       ptep = (pte_t *)__srmmu_get_nocache(SRMMU_PTE_SZ_SOFT,
-                           SRMMU_PTE_SZ_SOFT);
+                       ptep = (pte_t *)__srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
                        if (ptep == NULL)
                                early_pgtable_allocfail("pte");
-                       memset(__nocache_fix(ptep), 0, SRMMU_PTE_SZ_SOFT);
+                       memset(__nocache_fix(ptep), 0, PTE_SIZE);
                        srmmu_pmd_set(__nocache_fix(pmdp), ptep);
                }
-               if (start > (0xffffffffUL - SRMMU_PMD_SIZE_SOFT))
+               if (start > (0xffffffffUL - PMD_SIZE))
                        break;
-               start = (start + SRMMU_PMD_SIZE_SOFT) & SRMMU_PMD_MASK_SOFT;
+               start = (start + PMD_SIZE) & PMD_MASK;
        }
 }
 
@@ -1097,16 +1096,16 @@ void __init srmmu_allocate_ptable_skeleton(unsigned long start, unsigned long en
                }
                pmdp = srmmu_pmd_offset(pgdp, start);
                if(srmmu_pmd_none(*pmdp)) {
-                       ptep = (pte_t *) __srmmu_get_nocache(SRMMU_PTE_SZ_SOFT,
-                           SRMMU_PTE_SZ_SOFT);
+                       ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE,
+                                                            PTE_SIZE);
                        if (ptep == NULL)
                                early_pgtable_allocfail("pte");
-                       memset(ptep, 0, SRMMU_PTE_SZ_SOFT);
+                       memset(ptep, 0, PTE_SIZE);
                        srmmu_pmd_set(pmdp, ptep);
                }
-               if (start > (0xffffffffUL - SRMMU_PMD_SIZE_SOFT))
+               if (start > (0xffffffffUL - PMD_SIZE))
                        break;
-               start = (start + SRMMU_PMD_SIZE_SOFT) & SRMMU_PMD_MASK_SOFT;
+               start = (start + PMD_SIZE) & PMD_MASK;
        }
 }
 
@@ -1136,8 +1135,8 @@ void __init srmmu_inherit_prom_mappings(unsigned long start,unsigned long end)
                /* A red snapper, see what it really is. */
                what = 0;
     
-               if(!(start & ~(SRMMU_PMD_MASK))) {
-                       if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_PMD_SIZE) == prompte)
+               if(!(start & ~(SRMMU_REAL_PMD_MASK))) {
+                       if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte)
                                what = 1;
                }
     
@@ -1162,11 +1161,11 @@ void __init srmmu_inherit_prom_mappings(unsigned long start,unsigned long end)
                }
                pmdp = srmmu_pmd_offset(__nocache_fix(pgdp), start);
                if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
-                       ptep = (pte_t *) __srmmu_get_nocache(SRMMU_PTE_SZ_SOFT,
-                           SRMMU_PTE_SZ_SOFT);
+                       ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE,
+                                                            PTE_SIZE);
                        if (ptep == NULL)
                                early_pgtable_allocfail("pte");
-                       memset(__nocache_fix(ptep), 0, SRMMU_PTE_SZ_SOFT);
+                       memset(__nocache_fix(ptep), 0, PTE_SIZE);
                        srmmu_pmd_set(__nocache_fix(pmdp), ptep);
                }
                if(what == 1) {
@@ -1176,9 +1175,9 @@ void __init srmmu_inherit_prom_mappings(unsigned long start,unsigned long end)
                         * good hardware PTE piece. Alternatives seem worse.
                         */
                        unsigned int x; /* Index of HW PMD in soft cluster */
-                       x = (start >> SRMMU_PMD_SHIFT) & 15;
+                       x = (start >> PMD_SHIFT) & 15;
                        *(unsigned long *)__nocache_fix(&pmdp->pmdv[x]) = prompte;
-                       start += SRMMU_PMD_SIZE;
+                       start += SRMMU_REAL_PMD_SIZE;
                        continue;
                }
                ptep = srmmu_pte_offset(__nocache_fix(pmdp), start);
@@ -2139,16 +2138,11 @@ void __init ld_mmu_srmmu(void)
        extern void ld_mmu_iounit(void);
        extern void ___xchg32_sun4md(void);
 
-       BTFIXUPSET_SIMM13(pmd_shift, SRMMU_PMD_SHIFT_SOFT);
-       BTFIXUPSET_SETHI(pmd_size, SRMMU_PMD_SIZE_SOFT);
-       BTFIXUPSET_SETHI(pmd_mask, SRMMU_PMD_MASK_SOFT);
-
        BTFIXUPSET_SIMM13(pgdir_shift, SRMMU_PGDIR_SHIFT);
        BTFIXUPSET_SETHI(pgdir_size, SRMMU_PGDIR_SIZE);
        BTFIXUPSET_SETHI(pgdir_mask, SRMMU_PGDIR_MASK);
 
-       BTFIXUPSET_SIMM13(ptrs_per_pte, SRMMU_PTRS_PER_PTE_SOFT);
-       BTFIXUPSET_SIMM13(ptrs_per_pmd, SRMMU_PTRS_PER_PMD_SOFT);
+       BTFIXUPSET_SIMM13(ptrs_per_pmd, SRMMU_PTRS_PER_PMD);
        BTFIXUPSET_SIMM13(ptrs_per_pgd, SRMMU_PTRS_PER_PGD);
 
        BTFIXUPSET_INT(page_none, pgprot_val(SRMMU_PAGE_NONE));
index 4b9fc1d..f169a48 100644 (file)
@@ -2137,14 +2137,10 @@ void __init ld_mmu_sun4c(void)
        printk("Loading sun4c MMU routines\n");
 
        /* First the constants */
-       BTFIXUPSET_SIMM13(pmd_shift, SUN4C_PMD_SHIFT);
-       BTFIXUPSET_SETHI(pmd_size, SUN4C_PMD_SIZE);
-       BTFIXUPSET_SETHI(pmd_mask, SUN4C_PMD_MASK);
        BTFIXUPSET_SIMM13(pgdir_shift, SUN4C_PGDIR_SHIFT);
        BTFIXUPSET_SETHI(pgdir_size, SUN4C_PGDIR_SIZE);
        BTFIXUPSET_SETHI(pgdir_mask, SUN4C_PGDIR_MASK);
 
-       BTFIXUPSET_SIMM13(ptrs_per_pte, SUN4C_PTRS_PER_PTE);
        BTFIXUPSET_SIMM13(ptrs_per_pmd, SUN4C_PTRS_PER_PMD);
        BTFIXUPSET_SIMM13(ptrs_per_pgd, SUN4C_PTRS_PER_PGD);
        BTFIXUPSET_SIMM13(user_ptrs_per_pgd, KERNBASE / SUN4C_PGDIR_SIZE);
index 3891ac5..dfedd7e 100644 (file)
@@ -233,7 +233,6 @@ CONFIG_BLK_DEV_IDE=y
 #
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDETAPE=m
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -342,7 +341,6 @@ CONFIG_SCSI_SATA_SIS=m
 CONFIG_SCSI_SATA_VIA=m
 CONFIG_SCSI_SATA_VITESSE=m
 # CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
 CONFIG_SCSI_DMX3191D=m
 # CONFIG_SCSI_EATA is not set
 CONFIG_SCSI_EATA_PIO=m
@@ -864,9 +862,8 @@ CONFIG_VIA_RHINE=m
 # CONFIG_VIA_RHINE_MMIO is not set
 
 #
-# Gigabit Ethernet (1000/10000 Mbit)
+# Ethernet (1000 Mbit)
 #
-CONFIG_NET_GIGE=y
 CONFIG_ACENIC=m
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
 CONFIG_DL2K=m
@@ -879,6 +876,10 @@ CONFIG_YELLOWFIN=m
 CONFIG_R8169=m
 CONFIG_SK98LIN=m
 CONFIG_TIGON3=m
+
+#
+# Ethernet (10000 Mbit)
+#
 CONFIG_IXGB=m
 CONFIG_IXGB_NAPI=y
 CONFIG_S2IO=m
@@ -1584,6 +1585,7 @@ CONFIG_USB_HPUSBSCSI=m
 # CONFIG_USB_IBMCAM is not set
 # CONFIG_USB_KONICAWC is not set
 # CONFIG_USB_OV511 is not set
+CONFIG_USB_PWC=m
 # CONFIG_USB_SE401 is not set
 # CONFIG_USB_STV680 is not set
 CONFIG_USB_W9968CF=m
index 6e39a10..2296525 100644 (file)
@@ -243,8 +243,9 @@ int chmc_getunumber(int syndrome_code,
 static u64 read_mcreg(struct mctrl_info *mp, unsigned long offset)
 {
        unsigned long ret;
+       int this_cpu = get_cpu();
 
-       if (mp->portid == smp_processor_id()) {
+       if (mp->portid == this_cpu) {
                __asm__ __volatile__("ldxa      [%1] %2, %0"
                                     : "=r" (ret)
                                     : "r" (offset), "i" (ASI_MCU_CTRL_REG));
@@ -254,6 +255,8 @@ static u64 read_mcreg(struct mctrl_info *mp, unsigned long offset)
                                     : "r" (mp->regs + offset),
                                       "i" (ASI_PHYS_BYPASS_EC_E));
        }
+       put_cpu();
+
        return ret;
 }
 
index e452506..329b38f 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/init_task.h>
+#include <linux/mqueue.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
index 9a48757..b7f6a1e 100644 (file)
@@ -174,6 +174,8 @@ void enable_irq(unsigned int irq)
        if (imap == 0UL)
                return;
 
+       preempt_disable();
+
        if (tlb_type == cheetah || tlb_type == cheetah_plus) {
                unsigned long ver;
 
@@ -214,6 +216,8 @@ void enable_irq(unsigned int irq)
         * Things like FFB can now be handled via the new IRQ mechanism.
         */
        upa_writel(tid | IMAP_VALID, imap);
+
+       preempt_enable();
 }
 
 /* This now gets passed true ino's as well. */
index 040323b..64b8732 100644 (file)
@@ -547,15 +547,18 @@ retry:
 static void smp_cross_call_masked(unsigned long *func, u32 ctx, u64 data1, u64 data2, cpumask_t mask)
 {
        u64 data0 = (((u64)ctx)<<32 | (((u64)func) & 0xffffffff));
+       int this_cpu = get_cpu();
 
        cpus_and(mask, mask, cpu_online_map);
-       cpu_clear(smp_processor_id(), mask);
+       cpu_clear(this_cpu, mask);
 
        if (tlb_type == spitfire)
                spitfire_xcall_deliver(data0, data1, data2, mask);
        else
                cheetah_xcall_deliver(data0, data1, data2, mask);
        /* NOTE: Caller runs local copy on master. */
+
+       put_cpu();
 }
 
 extern unsigned long xcall_sync_tick;
@@ -685,11 +688,12 @@ static __inline__ void __local_flush_dcache_page(struct page *page)
 void smp_flush_dcache_page_impl(struct page *page, int cpu)
 {
        cpumask_t mask = cpumask_of_cpu(cpu);
+       int this_cpu = get_cpu();
 
 #ifdef CONFIG_DEBUG_DCFLUSH
        atomic_inc(&dcpage_flushes);
 #endif
-       if (cpu == smp_processor_id()) {
+       if (cpu == this_cpu) {
                __local_flush_dcache_page(page);
        } else if (cpu_online(cpu)) {
                u64 data0;
@@ -714,14 +718,17 @@ void smp_flush_dcache_page_impl(struct page *page, int cpu)
                atomic_inc(&dcpage_flushes_xcall);
 #endif
        }
+
+       put_cpu();
 }
 
 void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
 {
        cpumask_t mask = cpu_online_map;
        u64 data0;
+       int this_cpu = get_cpu();
 
-       cpu_clear(smp_processor_id(), mask);
+       cpu_clear(this_cpu, mask);
 
 #ifdef CONFIG_DEBUG_DCFLUSH
        atomic_inc(&dcpage_flushes);
@@ -747,6 +754,8 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
 #endif
  flush_self:
        __local_flush_dcache_page(page);
+
+       put_cpu();
 }
 
 void smp_receive_signal(int cpu)
@@ -842,7 +851,7 @@ void smp_flush_tlb_mm(struct mm_struct *mm)
 
        {
                u32 ctx = CTX_HWBITS(mm->context);
-               int cpu = smp_processor_id();
+               int cpu = get_cpu();
 
                if (atomic_read(&mm->mm_users) == 1) {
                        /* See smp_flush_tlb_page for info about this. */
@@ -856,6 +865,8 @@ void smp_flush_tlb_mm(struct mm_struct *mm)
 
        local_flush_and_out:
                __flush_tlb_mm(ctx, SECONDARY_CONTEXT);
+
+               put_cpu();
        }
 }
 
@@ -863,7 +874,7 @@ void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start,
                         unsigned long end)
 {
        u32 ctx = CTX_HWBITS(mm->context);
-       int cpu = smp_processor_id();
+       int cpu = get_cpu();
 
        start &= PAGE_MASK;
        end    = PAGE_ALIGN(end);
@@ -880,6 +891,8 @@ void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start,
  local_flush_and_out:
        __flush_tlb_range(ctx, start, SECONDARY_CONTEXT,
                          end, PAGE_SIZE, (end-start));
+
+       put_cpu();
 }
 
 void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end)
@@ -898,7 +911,7 @@ void smp_flush_tlb_page(struct mm_struct *mm, unsigned long page)
 {
        {
                u32 ctx = CTX_HWBITS(mm->context);
-               int cpu = smp_processor_id();
+               int cpu = get_cpu();
 
                page &= PAGE_MASK;
                if (mm == current->active_mm &&
@@ -938,6 +951,8 @@ void smp_flush_tlb_page(struct mm_struct *mm, unsigned long page)
 
        local_flush_and_out:
                __flush_tlb_page(ctx, page, SECONDARY_CONTEXT);
+
+               put_cpu();
        }
 }
 
index ea2c0e3..10c7821 100644 (file)
@@ -189,6 +189,11 @@ EXPORT_SYMBOL(___test_and_change_bit);
 EXPORT_SYMBOL(___test_and_set_le_bit);
 EXPORT_SYMBOL(___test_and_clear_le_bit);
 
+/* Bit searching */
+EXPORT_SYMBOL(find_next_bit);
+EXPORT_SYMBOL(find_next_zero_bit);
+EXPORT_SYMBOL(find_next_zero_le_bit);
+
 EXPORT_SYMBOL(ivector_table);
 EXPORT_SYMBOL(enable_irq);
 EXPORT_SYMBOL(disable_irq);
index 95e3d3a..7a5d4f4 100644 (file)
@@ -91,7 +91,7 @@ SIGN1(sys32_io_submit, compat_sys_io_submit, %o1)
 SIGN1(sys32_mq_open, compat_sys_mq_open, %o1)
 SIGN1(sys32_select, compat_sys_select, %o0)
 SIGN1(sys32_mkdir, sys_mkdir, %o1)
-SIGN2(sys32_futex, compat_sys_futex, %o1, %o2)
+SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5)
 SIGN1(sys32_sysfs, compat_sys_sysfs, %o0)
 SIGN3(sys32_ipc, compat_sys_ipc, %o1, %o2, %o3)
 SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1)
index c1c0640..0ed11ea 100644 (file)
@@ -800,8 +800,8 @@ asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid)
 }
 
 /* So stupid... */
-extern long compat_sys_wait4(compat_pid_t, compat_uint_t *, int,
-                            struct compat_rusage *);
+extern long compat_sys_wait4(compat_pid_t, compat_uint_t __user *, int,
+                            struct compat_rusage __user *);
 
 asmlinkage int sunos_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options, struct compat_rusage __user *ru)
 {
index 5b66435..646a788 100644 (file)
@@ -158,8 +158,8 @@ static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs)
        }
 }
 
-static unsigned long compute_effective_address(struct pt_regs *regs,
-                                              unsigned int insn, unsigned int rd)
+unsigned long compute_effective_address(struct pt_regs *regs,
+                                       unsigned int insn, unsigned int rd)
 {
        unsigned int rs1 = (insn >> 14) & 0x1f;
        unsigned int rs2 = insn & 0x1f;
index 14a4c72..230e59f 100644 (file)
@@ -10,7 +10,8 @@ lib-y := PeeCeeI.o blockops.o strlen.o strncmp.o \
         VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o \
         VIScsumcopyusr.o VISsave.o atomic.o rwlock.o bitops.o \
         U3memcpy.o U3copy_from_user.o U3copy_to_user.o \
-        U3copy_in_user.o mcount.o ipcsum.o rwsem.o xor.o splock.o
+        U3copy_in_user.o mcount.o ipcsum.o rwsem.o xor.o splock.o \
+        find_bit.o
 
 lib-$(CONFIG_DEBUG_SPINLOCK) += debuglocks.o
 lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
index 7b68a4d..9e083e2 100644 (file)
@@ -55,7 +55,7 @@ void _do_spin_lock(spinlock_t *lock, char *str)
 {
        unsigned long caller, val;
        int stuck = INIT_STUCK;
-       int cpu = smp_processor_id();
+       int cpu = get_cpu();
        int shown = 0;
 
        GET_CALLER(caller);
@@ -80,12 +80,14 @@ again:
        lock->owner_cpu = cpu;
        current->thread.smp_lock_count++;
        current->thread.smp_lock_pc = ((unsigned int)caller);
+
+       put_cpu();
 }
 
 int _spin_trylock(spinlock_t *lock)
 {
        unsigned long val, caller;
-       int cpu = smp_processor_id();
+       int cpu = get_cpu();
 
        GET_CALLER(caller);
        __asm__ __volatile__("ldstub [%1], %0"
@@ -99,6 +101,9 @@ int _spin_trylock(spinlock_t *lock)
                current->thread.smp_lock_count++;
                current->thread.smp_lock_pc = ((unsigned int)caller);
        }
+
+       put_cpu();
+
        return val == 0;
 }
 
@@ -117,7 +122,7 @@ void _do_read_lock (rwlock_t *rw, char *str)
 {
        unsigned long caller, val;
        int stuck = INIT_STUCK;
-       int cpu = smp_processor_id();
+       int cpu = get_cpu();
        int shown = 0;
 
        GET_CALLER(caller);
@@ -148,13 +153,15 @@ wlock_again:
        rw->reader_pc[cpu] = ((unsigned int)caller);
        current->thread.smp_lock_count++;
        current->thread.smp_lock_pc = ((unsigned int)caller);
+
+       put_cpu();
 }
 
 void _do_read_unlock (rwlock_t *rw, char *str)
 {
        unsigned long caller, val;
        int stuck = INIT_STUCK;
-       int cpu = smp_processor_id();
+       int cpu = get_cpu();
        int shown = 0;
 
        GET_CALLER(caller);
@@ -181,13 +188,15 @@ runlock_again:
                }
                goto runlock_again;
        }
+
+       put_cpu();
 }
 
 void _do_write_lock (rwlock_t *rw, char *str)
 {
        unsigned long caller, val;
        int stuck = INIT_STUCK;
-       int cpu = smp_processor_id();
+       int cpu = get_cpu();
        int shown = 0;
 
        GET_CALLER(caller);
@@ -263,6 +272,8 @@ wlock_again:
        rw->writer_cpu = cpu;
        current->thread.smp_lock_count++;
        current->thread.smp_lock_pc = ((unsigned int)caller);
+
+       put_cpu();
 }
 
 void _do_write_unlock(rwlock_t *rw)
@@ -302,7 +313,7 @@ wlock_again:
 int _do_write_trylock (rwlock_t *rw, char *str)
 {
        unsigned long caller, val;
-       int cpu = smp_processor_id();
+       int cpu = get_cpu();
 
        GET_CALLER(caller);
 
@@ -322,8 +333,10 @@ int _do_write_trylock (rwlock_t *rw, char *str)
        : "0" (&(rw->lock))
        : "g3", "g5", "g7", "memory");
 
-       if (val)
+       if (val) {
+               put_cpu();
                return 0;
+       }
 
        if ((rw->lock & ((1UL<<63)-1UL)) != 0UL) {
                /* Readers still around, drop the write
@@ -342,6 +355,8 @@ int _do_write_trylock (rwlock_t *rw, char *str)
                : "r" (&(rw->lock))
                : "g3", "g5", "g7", "cc", "memory");
 
+               put_cpu();
+
                return 0;
        }
 
@@ -351,6 +366,8 @@ int _do_write_trylock (rwlock_t *rw, char *str)
        current->thread.smp_lock_count++;
        current->thread.smp_lock_pc = ((unsigned int)caller);
 
+       put_cpu();
+
        return 1;
 }
 
index bdde3da..31e4747 100644 (file)
 #include <linux/types.h>
 #include <asm/byteorder.h>
 
-#define add_ssaaaa(sh, sl, ah, al, bh, bl)                                             \
-  __asm__ ("addcc %4,%5,%1\n\
-           add %2,%3,%0\n\
-           bcs,a,pn %%xcc, 1f\n\
-           add %0, 1, %0\n\
-           1:"                                                                         \
-          : "=r" ((UDItype)(sh)),                                                      \
-            "=&r" ((UDItype)(sl))                                                      \
-          : "r" ((UDItype)(ah)),                                                       \
-            "r" ((UDItype)(bh)),                                                       \
-            "r" ((UDItype)(al)),                                                       \
-            "r" ((UDItype)(bl))                                                        \
+#define add_ssaaaa(sh, sl, ah, al, bh, bl)     \
+  __asm__ ("addcc %4,%5,%1\n\t"                        \
+          "add %2,%3,%0\n\t"                   \
+          "bcs,a,pn %%xcc, 1f\n\t"             \
+          "add %0, 1, %0\n"                    \
+          "1:"                                 \
+          : "=r" ((UDItype)(sh)),              \
+            "=&r" ((UDItype)(sl))              \
+          : "r" ((UDItype)(ah)),               \
+            "r" ((UDItype)(bh)),               \
+            "r" ((UDItype)(al)),               \
+            "r" ((UDItype)(bl))                \
           : "cc")
           
-#define sub_ddmmss(sh, sl, ah, al, bh, bl)                                             \
-  __asm__ ("subcc %4,%5,%1\n\
-           sub %2,%3,%0\n\
-           bcs,a,pn %%xcc, 1f\n\
-           sub %0, 1, %0\n\
-           1:"                                                                         \
-          : "=r" ((UDItype)(sh)),                                                      \
-            "=&r" ((UDItype)(sl))                                                      \
-          : "r" ((UDItype)(ah)),                                                       \
-            "r" ((UDItype)(bh)),                                                       \
-            "r" ((UDItype)(al)),                                                       \
-            "r" ((UDItype)(bl))                                                        \
+#define sub_ddmmss(sh, sl, ah, al, bh, bl)     \
+  __asm__ ("subcc %4,%5,%1\n\t"                        \
+          "sub %2,%3,%0\n\t"                   \
+          "bcs,a,pn %%xcc, 1f\n\t"             \
+          "sub %0, 1, %0\n"                    \
+          "1:"                                 \
+          : "=r" ((UDItype)(sh)),              \
+            "=&r" ((UDItype)(sl))              \
+          : "r" ((UDItype)(ah)),               \
+            "r" ((UDItype)(bh)),               \
+            "r" ((UDItype)(al)),               \
+            "r" ((UDItype)(bl))                \
           : "cc")
 
-#define umul_ppmm(wh, wl, u, v)                                                                \
-  do {                                                                                 \
-         UDItype tmp1, tmp2, tmp3, tmp4;                                               \
-         __asm__ __volatile__ (                                                        \
-                  "srl %7,0,%3\n\
-                   mulx %3,%6,%1\n\
-                   srlx %6,32,%2\n\
-                   mulx %2,%3,%4\n\
-                   sllx %4,32,%5\n\
-                   srl %6,0,%3\n\
-                   sub %1,%5,%5\n\
-                   srlx %5,32,%5\n\
-                   addcc %4,%5,%4\n\
-                   srlx %7,32,%5\n\
-                   mulx %3,%5,%3\n\
-                   mulx %2,%5,%5\n\
-                   sethi %%hi(0x80000000),%2\n\
-                   addcc %4,%3,%4\n\
-                   srlx %4,32,%4\n\
-                   add %2,%2,%2\n\
-                   movcc %%xcc,%%g0,%2\n\
-                   addcc %5,%4,%5\n\
-                   sllx %3,32,%3\n\
-                   add %1,%3,%1\n\
-                   add %5,%2,%0"                                                       \
-          : "=r" ((UDItype)(wh)),                                                      \
-            "=&r" ((UDItype)(wl)),                                                     \
-            "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4)                     \
-          : "r" ((UDItype)(u)),                                                        \
-            "r" ((UDItype)(v))                                                         \
-          : "cc");                                                                     \
+#define umul_ppmm(wh, wl, u, v)                                \
+  do {                                                 \
+         UDItype tmp1, tmp2, tmp3, tmp4;               \
+         __asm__ __volatile__ (                        \
+                  "srl %7,0,%3\n\t"                    \
+                  "mulx %3,%6,%1\n\t"                  \
+                  "srlx %6,32,%2\n\t"                  \
+                  "mulx %2,%3,%4\n\t"                  \
+                  "sllx %4,32,%5\n\t"                  \
+                  "srl %6,0,%3\n\t"                    \
+                  "sub %1,%5,%5\n\t"                   \
+                  "srlx %5,32,%5\n\t"                  \
+                  "addcc %4,%5,%4\n\t"                 \
+                  "srlx %7,32,%5\n\t"                  \
+                  "mulx %3,%5,%3\n\t"                  \
+                  "mulx %2,%5,%5\n\t"                  \
+                  "sethi %%hi(0x80000000),%2\n\t"      \
+                  "addcc %4,%3,%4\n\t"                 \
+                  "srlx %4,32,%4\n\t"                  \
+                  "add %2,%2,%2\n\t"                   \
+                  "movcc %%xcc,%%g0,%2\n\t"            \
+                  "addcc %5,%4,%5\n\t"                 \
+                  "sllx %3,32,%3\n\t"                  \
+                  "add %1,%3,%1\n\t"                   \
+                  "add %5,%2,%0"                       \
+          : "=r" ((UDItype)(wh)),                      \
+            "=&r" ((UDItype)(wl)),                     \
+            "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \
+          : "r" ((UDItype)(u)),                        \
+            "r" ((UDItype)(v))                         \
+          : "cc");                                     \
   } while (0)
   
-#define udiv_qrnnd(q, r, n1, n0, d)                                                    \
-  do {                                                                                 \
-    UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m;                                    \
-    __d1 = (d >> 32);                                                                  \
-    __d0 = (USItype)d;                                                                 \
-                                                                                       \
-    __r1 = (n1) % __d1;                                                                \
-    __q1 = (n1) / __d1;                                                                \
-    __m = (UWtype) __q1 * __d0;                                                        \
-    __r1 = (__r1 << 32) | (n0 >> 32);                                                          \
-    if (__r1 < __m)                                                                    \
-      {                                                                                \
-        __q1--, __r1 += (d);                                                           \
-        if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */            \
-          if (__r1 < __m)                                                              \
-            __q1--, __r1 += (d);                                                       \
-      }                                                                                \
-    __r1 -= __m;                                                                       \
-                                                                                       \
-    __r0 = __r1 % __d1;                                                                \
-    __q0 = __r1 / __d1;                                                                \
-    __m = (UWtype) __q0 * __d0;                                                        \
-    __r0 = (__r0 << 32) | ((USItype)n0);                                               \
-    if (__r0 < __m)                                                                    \
-      {                                                                                \
-        __q0--, __r0 += (d);                                                           \
-        if (__r0 >= (d))                                                               \
-          if (__r0 < __m)                                                              \
-            __q0--, __r0 += (d);                                                       \
-      }                                                                                \
-    __r0 -= __m;                                                                       \
-                                                                                       \
-    (q) = (UWtype) (__q1 << 32)  | __q0;                                               \
-    (r) = __r0;                                                                        \
+#define udiv_qrnnd(q, r, n1, n0, d)                    \
+  do {                                                  \
+    UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m;     \
+    __d1 = (d >> 32);                                   \
+    __d0 = (USItype)d;                                  \
+                                                        \
+    __r1 = (n1) % __d1;                                 \
+    __q1 = (n1) / __d1;                                 \
+    __m = (UWtype) __q1 * __d0;                         \
+    __r1 = (__r1 << 32) | (n0 >> 32);                   \
+    if (__r1 < __m)                                     \
+      {                                                 \
+        __q1--, __r1 += (d);                            \
+        if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */ \
+          if (__r1 < __m)                               \
+            __q1--, __r1 += (d);                        \
+      }                                                 \
+    __r1 -= __m;                                        \
+                                                        \
+    __r0 = __r1 % __d1;                                 \
+    __q0 = __r1 / __d1;                                 \
+    __m = (UWtype) __q0 * __d0;                         \
+    __r0 = (__r0 << 32) | ((USItype)n0);                \
+    if (__r0 < __m)                                     \
+      {                                                 \
+        __q0--, __r0 += (d);                            \
+        if (__r0 >= (d))                                \
+          if (__r0 < __m)                               \
+            __q0--, __r0 += (d);                        \
+      }                                                 \
+    __r0 -= __m;                                        \
+                                                        \
+    (q) = (UWtype) (__q1 << 32)  | __q0;                \
+    (r) = __r0;                                         \
   } while (0)
 
 #define UDIV_NEEDS_NORMALIZATION 1  
 
-#define abort()                                                                                \
+#define abort() \
        return 0
 
 #ifdef __BIG_ENDIAN
index 348f206..5fc4644 100644 (file)
@@ -207,14 +207,21 @@ outret:
        return insn;
 }
 
-static void do_fault_siginfo(int code, int sig, unsigned long address)
+extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int);
+
+static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
+                            unsigned int insn, int fault_code)
 {
        siginfo_t info;
 
        info.si_code = code;
        info.si_signo = sig;
        info.si_errno = 0;
-       info.si_addr = (void *) address;
+       if (fault_code & FAULT_CODE_ITLB)
+               info.si_addr = (void *) regs->tpc;
+       else
+               info.si_addr = (void *)
+                       compute_effective_address(regs, insn, 0);
        info.si_trapno = 0;
        force_sig_info(sig, &info, current);
 }
@@ -295,7 +302,7 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
                /* The si_code was set to make clear whether
                 * this was a SEGV_MAPERR or SEGV_ACCERR fault.
                 */
-               do_fault_siginfo(si_code, SIGSEGV, address);
+               do_fault_siginfo(si_code, SIGSEGV, regs, insn, fault_code);
                return;
        }
 
@@ -471,7 +478,7 @@ do_sigbus:
         * Send a sigbus, regardless of whether we were in kernel
         * or user mode.
         */
-       do_fault_siginfo(BUS_ADRERR, SIGBUS, address);
+       do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, insn, fault_code);
 
        /* Kernel mode? Handle exceptions or die */
        if (regs->tstate & TSTATE_PRIV)
index 1e9519d..043861f 100644 (file)
@@ -152,9 +152,9 @@ __inline__ void flush_dcache_page_impl(struct page *page)
 #define dcache_dirty_cpu(page) \
        (((page)->flags >> 24) & (NR_CPUS - 1UL))
 
-static __inline__ void set_dcache_dirty(struct page *page)
+static __inline__ void set_dcache_dirty(struct page *page, int this_cpu)
 {
-       unsigned long mask = smp_processor_id();
+       unsigned long mask = this_cpu;
        unsigned long non_cpu_bits = ~((NR_CPUS - 1UL) << 24UL);
        mask = (mask << 24) | (1UL << PG_dcache_dirty);
        __asm__ __volatile__("1:\n\t"
@@ -206,16 +206,19 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p
            (page = pfn_to_page(pfn), page_mapping(page)) &&
            ((pg_flags = page->flags) & (1UL << PG_dcache_dirty))) {
                int cpu = ((pg_flags >> 24) & (NR_CPUS - 1UL));
+               int this_cpu = get_cpu();
 
                /* This is just to optimize away some function calls
                 * in the SMP case.
                 */
-               if (cpu == smp_processor_id())
+               if (cpu == this_cpu)
                        flush_dcache_page_impl(page);
                else
                        smp_flush_dcache_page_impl(page, cpu);
 
                clear_dcache_dirty_cpu(page, cpu);
+
+               put_cpu();
        }
        if (get_thread_fault_code())
                __update_mmu_cache(vma->vm_mm->context & TAG_CONTEXT_BITS,
@@ -227,14 +230,15 @@ void flush_dcache_page(struct page *page)
        struct address_space *mapping = page_mapping(page);
        int dirty = test_bit(PG_dcache_dirty, &page->flags);
        int dirty_cpu = dcache_dirty_cpu(page);
+       int this_cpu = get_cpu();
 
        if (mapping && !mapping_mapped(mapping)) {
                if (dirty) {
-                       if (dirty_cpu == smp_processor_id())
-                               return;
+                       if (dirty_cpu == this_cpu)
+                               goto out;
                        smp_flush_dcache_page_impl(page, dirty_cpu);
                }
-               set_dcache_dirty(page);
+               set_dcache_dirty(page, this_cpu);
        } else {
                /* We could delay the flush for the !page_mapping
                 * case too.  But that case is for exec env/arg
@@ -243,6 +247,9 @@ void flush_dcache_page(struct page *page)
                 */
                flush_dcache_page_impl(page);
        }
+
+out:
+       put_cpu();
 }
 
 /* When shared+writable mmaps of files go away, we lose all dirty
index 7d6bb96..be82caf 100644 (file)
@@ -9,6 +9,7 @@
 #include "linux/sched.h"
 #include "linux/init_task.h"
 #include "linux/version.h"
+#include "linux/mqueue.h"
 #include "asm/uaccess.h"
 #include "asm/pgtable.h"
 #include "user_util.h"
index a5dac3a..ed2f93c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/init_task.h>
 #include <linux/fs.h>
+#include <linux/mqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
index 896873b..9b9a504 100644 (file)
@@ -37,6 +37,8 @@ LDFLAGS               := -m elf_x86_64
 OBJCOPYFLAGS   := -O binary -R .note -R .comment -S
 LDFLAGS_vmlinux := -e stext
 
+CHECK           := $(CHECK) -D__x86_64__=1
+
 cflags-$(CONFIG_MK8) += $(call check_gcc,-march=k8,)
 cflags-$(CONFIG_MPSC) += $(call check_gcc,-march=nocona,)
 CFLAGS += $(cflags-y)
index df768a0..e569a14 100644 (file)
@@ -34,6 +34,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_IOSCHED_NOOP=y
@@ -234,6 +235,7 @@ CONFIG_BLK_DEV_PIIX=y
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
 CONFIG_IDEDMA_AUTO=y
@@ -258,7 +260,6 @@ CONFIG_BLK_DEV_SD=y
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
 # CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_REPORT_LUNS is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
 
@@ -789,7 +790,6 @@ CONFIG_USB_HIDINPUT=y
 # Firmware Drivers
 #
 # CONFIG_EDD is not set
-# CONFIG_SMBIOS is not set
 
 #
 # File systems
index c6d0b02..f9a2638 100644 (file)
@@ -72,15 +72,15 @@ static inline unsigned long twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
 
 
 static inline int convert_fxsr_from_user(struct i387_fxsave_struct *fxsave,
-                                        struct _fpstate_ia32 *buf)
+                                        struct _fpstate_ia32 __user *buf)
 {
        struct _fpxreg *to;
-       struct _fpreg *from;
+       struct _fpreg __user *from;
        int i;
        u32 v;
        int err = 0;
 
-#define G(num,val) err |= __get_user(val, num + (u32 *)buf)
+#define G(num,val) err |= __get_user(val, num + (u32 __user *)buf)
        G(0, fxsave->cwd);
        G(1, fxsave->swd);
        G(2, fxsave->twd);
@@ -104,12 +104,12 @@ static inline int convert_fxsr_from_user(struct i387_fxsave_struct *fxsave,
 }
 
 
-static inline int convert_fxsr_to_user(struct _fpstate_ia32 *buf,
+static inline int convert_fxsr_to_user(struct _fpstate_ia32 __user *buf,
                                       struct i387_fxsave_struct *fxsave,
                                       struct pt_regs *regs,
                                       struct task_struct *tsk)
 {
-       struct _fpreg *to;
+       struct _fpreg __user *to;
        struct _fpxreg *from;
        int i;
        u16 cs,ds; 
@@ -125,7 +125,7 @@ static inline int convert_fxsr_to_user(struct _fpstate_ia32 *buf,
                cs = regs->cs;
        } 
 
-#define P(num,val) err |= __put_user(val, num + (u32 *)buf)
+#define P(num,val) err |= __put_user(val, num + (u32 __user *)buf)
        P(0, (u32)fxsave->cwd | 0xffff0000);
        P(1, (u32)fxsave->swd | 0xffff0000);
        P(2, twd_fxsr_to_i387(fxsave));
@@ -147,7 +147,7 @@ static inline int convert_fxsr_to_user(struct _fpstate_ia32 *buf,
        return 0;
 }
 
-int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 *buf, int fsave) 
+int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, int fsave) 
 { 
        clear_fpu(tsk);
        if (!fsave) { 
@@ -162,7 +162,7 @@ int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 *buf, int fs
 }  
 
 int save_i387_ia32(struct task_struct *tsk, 
-                  struct _fpstate_ia32 *buf, 
+                  struct _fpstate_ia32 __user *buf, 
                   struct pt_regs *regs,
                   int fsave)
 {
index d397957..8c69642 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef TIOCGDEV
 #define TIOCGDEV       _IOR('T',0x32, unsigned int)
 #endif
-static int tiocgdev(unsigned fd, unsigned cmd,  unsigned int *ptr) 
+static int tiocgdev(unsigned fd, unsigned cmd,  unsigned int __user *ptr) 
 { 
 
        struct file *file = fget(fd);
@@ -54,7 +54,7 @@ static int rtc32_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
                ret = sys_ioctl(fd, RTC_IRQP_READ, (unsigned long)&val); 
                set_fs(oldfs); 
                if (!ret)
-                       ret = put_user(val, (unsigned int*) arg); 
+                       ret = put_user(val, (unsigned int __user *) arg); 
                return ret; 
 
        case RTC_IRQP_SET32: 
@@ -66,7 +66,7 @@ static int rtc32_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
                ret = sys_ioctl(fd, RTC_EPOCH_READ, (unsigned long) &val); 
                set_fs(oldfs); 
                if (!ret)
-                       ret = put_user(val, (unsigned int*) arg); 
+                       ret = put_user(val, (unsigned int __user *) arg); 
                return ret; 
 
        case RTC_EPOCH_SET32:
@@ -113,7 +113,7 @@ static int mtrr_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg)
        struct mtrr_gentry g;
        struct mtrr_sentry s;
        int get = 0, err = 0; 
-       struct mtrr_gentry32 *g32 = (struct mtrr_gentry32 *)arg; 
+       struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)arg; 
        mm_segment_t oldfs = get_fs(); 
 
        switch (cmd) { 
@@ -139,7 +139,7 @@ static int mtrr_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg)
 
                arg = (unsigned long)&g; 
        } else { 
-               struct mtrr_sentry32 *s32 = (struct mtrr_sentry32 *)arg;
+               struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)arg;
                err = get_user(s.base, &s32->base);
                err |= get_user(s.size, &s32->size);
                err |= get_user(s.type, &s32->type);
index 7e95c0a..2fe68d9 100644 (file)
@@ -42,7 +42,7 @@
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
-void signal_fault(struct pt_regs *regs, void *frame, char *where);
+void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
 
 int ia32_copy_siginfo_to_user(siginfo_t32 __user *to, siginfo_t *from)
 {
@@ -136,8 +136,9 @@ sys32_sigsuspend(int history0, int history1, old_sigset_t mask, struct pt_regs r
 }
 
 asmlinkage long
-sys32_sigaltstack(const stack_ia32_t *uss_ptr, stack_ia32_t *uoss_ptr, 
-                                 struct pt_regs regs)
+sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
+                 stack_ia32_t __user *uoss_ptr, 
+                 struct pt_regs regs)
 {
        stack_t uss,uoss; 
        int ret;
@@ -193,7 +194,7 @@ struct rt_sigframe
 };
 
 static int
-ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsigned int *peax)
+ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 __user *sc, unsigned int *peax)
 {
        unsigned int err = 0;
        
@@ -252,9 +253,9 @@ ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsign
 
        {
                u32 tmp;
-               struct _fpstate_ia32 * buf;
+               struct _fpstate_ia32 __user * buf;
                err |= __get_user(tmp, &sc->fpstate);
-               buf = (struct _fpstate_ia32 *) (u64)tmp;
+               buf = compat_ptr(tmp);
                if (buf) {
                        if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
                                goto badframe;
@@ -275,7 +276,7 @@ badframe:
 
 asmlinkage long sys32_sigreturn(struct pt_regs regs)
 {
-       struct sigframe *frame = (struct sigframe *)(regs.rsp - 8);
+       struct sigframe __user *frame = (struct sigframe __user *)(regs.rsp-8);
        sigset_t set;
        unsigned int eax;
 
@@ -304,9 +305,8 @@ badframe:
 
 asmlinkage long sys32_rt_sigreturn(struct pt_regs regs)
 {
-       struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 4);
+       struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(regs.rsp - 4);
        sigset_t set;
-       stack_t st;
        unsigned int eax;
 
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
@@ -338,20 +338,20 @@ badframe:
  */
 
 static int
-ia32_setup_sigcontext(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
+ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate,
                 struct pt_regs *regs, unsigned int mask)
 {
        int tmp, err = 0;
 
        tmp = 0;
        __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
-       err |= __put_user(tmp, (unsigned int *)&sc->gs);
+       err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
        __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
-       err |= __put_user(tmp, (unsigned int *)&sc->fs);
+       err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
        __asm__("movl %%ds,%0" : "=r"(tmp): "0"(tmp));
-       err |= __put_user(tmp, (unsigned int *)&sc->ds);
+       err |= __put_user(tmp, (unsigned int __user *)&sc->ds);
        __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp));
-       err |= __put_user(tmp, (unsigned int *)&sc->es);
+       err |= __put_user(tmp, (unsigned int __user *)&sc->es);
 
        err |= __put_user((u32)regs->rdi, &sc->edi);
        err |= __put_user((u32)regs->rsi, &sc->esi);
@@ -388,7 +388,7 @@ ia32_setup_sigcontext(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
 /*
  * Determine which stack to use..
  */
-static void *
+static void __user *
 get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
 {
        unsigned long rsp;
@@ -409,13 +409,13 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
                rsp = (unsigned long) ka->sa.sa_restorer;
        }
 
-       return (void *)((rsp - frame_size) & -8UL);
+       return (void __user *)((rsp - frame_size) & -8UL);
 }
 
 void ia32_setup_frame(int sig, struct k_sigaction *ka,
                        compat_sigset_t *set, struct pt_regs * regs)
 {
-       struct sigframe *frame;
+       struct sigframe __user *frame;
        int err = 0;
 
        frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -502,7 +502,7 @@ give_sigsegv:
 void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                           compat_sigset_t *set, struct pt_regs * regs)
 {
-       struct rt_sigframe *frame;
+       struct rt_sigframe __user *frame;
        int err = 0;
 
        frame = get_sigframe(ka, regs, sizeof(*frame));
index 1b98891..0a2fb66 100644 (file)
@@ -322,7 +322,7 @@ ia32_sys_call_table:
        .quad sys_mknod
        .quad sys_chmod         /* 15 */
        .quad sys_lchown16
-       .quad ni_syscall                        /* old break syscall holder */
+       .quad quiet_ni_syscall                  /* old break syscall holder */
        .quad sys_stat
        .quad sys32_lseek
        .quad sys_getpid                /* 20 */
@@ -336,11 +336,11 @@ ia32_sys_call_table:
        .quad sys_fstat /* (old)fstat */
        .quad sys_pause
        .quad compat_sys_utime  /* 30 */
-       .quad ni_syscall        /* old stty syscall holder */
-       .quad ni_syscall        /* old gtty syscall holder */
+       .quad quiet_ni_syscall  /* old stty syscall holder */
+       .quad quiet_ni_syscall  /* old gtty syscall holder */
        .quad sys_access
        .quad sys_nice  
-       .quad ni_syscall        /* 35 */        /* old ftime syscall holder */
+       .quad quiet_ni_syscall  /* 35 */        /* old ftime syscall holder */
        .quad sys_sync
        .quad sys32_kill
        .quad sys_rename
@@ -349,7 +349,7 @@ ia32_sys_call_table:
        .quad sys_dup
        .quad sys32_pipe
        .quad compat_sys_times
-       .quad ni_syscall                        /* old prof syscall holder */
+       .quad quiet_ni_syscall                  /* old prof syscall holder */
        .quad sys_brk           /* 45 */
        .quad sys_setgid16
        .quad sys_getgid16
@@ -358,12 +358,12 @@ ia32_sys_call_table:
        .quad sys_getegid16     /* 50 */
        .quad sys_acct
        .quad sys_umount                        /* new_umount */
-       .quad ni_syscall                        /* old lock syscall holder */
+       .quad quiet_ni_syscall                  /* old lock syscall holder */
        .quad compat_sys_ioctl
        .quad compat_sys_fcntl64                /* 55 */
-       .quad ni_syscall                        /* old mpx syscall holder */
+       .quad quiet_ni_syscall                  /* old mpx syscall holder */
        .quad sys_setpgid
-       .quad ni_syscall                        /* old ulimit syscall holder */
+       .quad quiet_ni_syscall                  /* old ulimit syscall holder */
        .quad sys32_olduname
        .quad sys_umask         /* 60 */
        .quad sys_chroot
@@ -403,7 +403,7 @@ ia32_sys_call_table:
        .quad sys_fchown16              /* 95 */
        .quad sys_getpriority
        .quad sys_setpriority
-       .quad ni_syscall                        /* old profil syscall holder */
+       .quad quiet_ni_syscall                  /* old profil syscall holder */
        .quad compat_sys_statfs
        .quad compat_sys_fstatfs                /* 100 */
        .quad sys_ioperm
@@ -417,7 +417,7 @@ ia32_sys_call_table:
        .quad sys32_uname
        .quad stub32_iopl               /* 110 */
        .quad sys_vhangup
-       .quad ni_syscall        /* old "idle" system call */
+       .quad quiet_ni_syscall  /* old "idle" system call */
        .quad sys32_vm86_warning        /* vm86old */ 
        .quad compat_sys_wait4
        .quad sys_swapoff               /* 115 */
@@ -442,7 +442,7 @@ ia32_sys_call_table:
        .quad quiet_ni_syscall  /* bdflush */
        .quad sys_sysfs         /* 135 */
        .quad sys_personality
-       .quad ni_syscall        /* for afs_syscall */
+       .quad quiet_ni_syscall  /* for afs_syscall */
        .quad sys_setfsuid16
        .quad sys_setfsgid16
        .quad sys_llseek                /* 140 */
@@ -493,8 +493,8 @@ ia32_sys_call_table:
        .quad sys_capset
        .quad stub32_sigaltstack
        .quad sys32_sendfile
-       .quad ni_syscall                /* streams1 */
-       .quad ni_syscall                /* streams2 */
+       .quad quiet_ni_syscall          /* streams1 */
+       .quad quiet_ni_syscall          /* streams2 */
        .quad stub32_vfork            /* 190 */
        .quad compat_sys_getrlimit
        .quad sys32_mmap2
@@ -543,51 +543,52 @@ ia32_sys_call_table:
        .quad sys_removexattr   /* 235 */
        .quad sys_lremovexattr
        .quad sys_fremovexattr
-       .quad sys_tkill         /* 238 */ 
+       .quad sys_tkill
        .quad sys_sendfile64 
        .quad compat_sys_futex          /* 240 */
-        .quad compat_sys_sched_setaffinity
-        .quad compat_sys_sched_getaffinity
+       .quad compat_sys_sched_setaffinity
+       .quad compat_sys_sched_getaffinity
        .quad sys32_set_thread_area
        .quad sys32_get_thread_area
-       .quad sys32_io_setup
+       .quad sys32_io_setup            /* 245 */
        .quad sys_io_destroy
        .quad sys32_io_getevents
        .quad sys32_io_submit
        .quad sys_io_cancel
-       .quad sys_fadvise64
-       .quad quiet_ni_syscall /* free_huge_pages */
-       .quad sys_exit_group /* exit_group */
+       .quad sys_fadvise64             /* 250 */
+       .quad quiet_ni_syscall  /* free_huge_pages */
+       .quad sys_exit_group
        .quad sys_lookup_dcookie
        .quad sys_epoll_create
-       .quad sys_epoll_ctl
+       .quad sys_epoll_ctl             /* 255 */
        .quad sys_epoll_wait
        .quad sys_remap_file_pages
        .quad sys_set_tid_address
        .quad sys32_timer_create
-       .quad compat_timer_settime
+       .quad compat_timer_settime      /* 260 */
        .quad compat_timer_gettime
        .quad sys_timer_getoverrun
        .quad sys_timer_delete
        .quad compat_clock_settime
-       .quad compat_clock_gettime
+       .quad compat_clock_gettime      /* 265 */
        .quad compat_clock_getres
        .quad compat_clock_nanosleep
-       .quad compat_statfs64   /* statfs64 */
-       .quad compat_fstatfs64  /* fstatfs64 */
-       .quad sys_tgkill
+       .quad compat_statfs64
+       .quad compat_fstatfs64
+       .quad sys_tgkill                /* 270 */
        .quad compat_sys_utimes
        .quad sys32_fadvise64_64
-       .quad sys_ni_syscall    /* sys_vserver */
-       .quad sys_ni_syscall    /* sys_mbind */
-       .quad sys_ni_syscall    /* 275 sys_get_mempolicy */
-       .quad sys_ni_syscall    /* sys_set_mempolicy */
+       .quad quiet_ni_syscall  /* sys_vserver */
+       .quad sys_mbind
+       .quad compat_get_mempolicy      /* 275 */
+       .quad sys_set_mempolicy
        .quad compat_sys_mq_open
        .quad sys_mq_unlink
        .quad compat_sys_mq_timedsend
        .quad compat_sys_mq_timedreceive        /* 280 */
        .quad compat_sys_mq_notify
        .quad compat_sys_mq_getsetattr
+       .quad quiet_ni_syscall          /* reserved for kexec */
        /* don't forget to change IA32_NR_syscalls */
 ia32_syscall_end:              
        .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
index c2ef942..01202b7 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mm.h>
 #include <linux/ptrace.h>
 #include <asm/ptrace.h>
+#include <asm/compat.h>
 #include <asm/uaccess.h>
 #include <asm/user32.h>
 #include <asm/user.h>
@@ -228,6 +229,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
 {
        struct task_struct *child;
        struct pt_regs *childregs; 
+       void __user *datap = compat_ptr(data);
        int ret;
        __u32 val;
 
@@ -264,7 +266,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
                if (access_process_vm(child, addr, &val, sizeof(u32), 0)!=sizeof(u32))
                        ret = -EIO;
                else
-                       ret = put_user(val, (unsigned int *)(u64)data); 
+                       ret = put_user(val, (unsigned int __user *)datap); 
                break; 
 
        case PTRACE_POKEDATA:
@@ -277,7 +279,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
        case PTRACE_PEEKUSR:
                ret = getreg32(child, addr, &val);
                if (ret == 0)
-                       ret = put_user(val, (__u32 *)(unsigned long) data);
+                       ret = put_user(val, (__u32 __user *)datap);
                break;
 
        case PTRACE_POKEUSR:
@@ -286,15 +288,15 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
 
        case PTRACE_GETREGS: { /* Get all gp regs from the child. */
                int i;
-               if (!access_ok(VERIFY_WRITE, (unsigned *)(unsigned long)data, 16*4)) {
+               if (!access_ok(VERIFY_WRITE, datap, 16*4)) {
                        ret = -EIO;
                        break;
                }
                ret = 0;
                for ( i = 0; i <= 16*4 ; i += sizeof(__u32) ) {
                        getreg32(child, i, &val);
-                       ret |= __put_user(val,(u32 *) (unsigned long) data);
-                       data += sizeof(u32);
+                       ret |= __put_user(val,(u32 __user *)datap);
+                       datap += sizeof(u32);
                }
                break;
        }
@@ -302,40 +304,40 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
        case PTRACE_SETREGS: { /* Set all gp regs in the child. */
                unsigned long tmp;
                int i;
-               if (!access_ok(VERIFY_READ, (unsigned *)(unsigned long)data, 16*4)) {
+               if (!access_ok(VERIFY_READ, datap, 16*4)) {
                        ret = -EIO;
                        break;
                }
                ret = 0; 
                for ( i = 0; i <= 16*4; i += sizeof(u32) ) {
-                       ret |= __get_user(tmp, (u32 *) (unsigned long) data);
+                       ret |= __get_user(tmp, (u32 __user *)datap);
                        putreg32(child, i, tmp);
-                       data += sizeof(u32);
+                       datap += sizeof(u32);
                }
                break;
        }
 
        case PTRACE_GETFPREGS:
                ret = -EIO; 
-               if (!access_ok(VERIFY_READ, (void *)(u64)data
+               if (!access_ok(VERIFY_READ, compat_ptr(data)
                               sizeof(struct user_i387_struct)))
                        break;
-               save_i387_ia32(child, (void *)(u64)data, childregs, 1);
+               save_i387_ia32(child, datap, childregs, 1);
                ret = 0; 
                        break;
 
        case PTRACE_SETFPREGS:
                ret = -EIO;
-               if (!access_ok(VERIFY_WRITE, (void *)(u64)data
+               if (!access_ok(VERIFY_WRITE, datap
                               sizeof(struct user_i387_struct)))
                        break;
                ret = 0;
                /* don't check EFAULT to be bug-to-bug compatible to i386 */
-               restore_i387_ia32(child, (void *)(u64)data, 1);
+               restore_i387_ia32(child, datap, 1);
                break;
 
        case PTRACE_GETFPXREGS: { 
-               struct user32_fxsr_struct *u = (void *)(u64)data; 
+               struct user32_fxsr_struct __user *u = datap;
                init_fpu(child); 
                ret = -EIO;
                if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
@@ -348,7 +350,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
                break; 
        } 
        case PTRACE_SETFPXREGS: { 
-               struct user32_fxsr_struct *u = (void *)(u64)data; 
+               struct user32_fxsr_struct __user *u = datap;
                unlazy_fpu(child);
                ret = -EIO;
                if (!access_ok(VERIFY_READ, u, sizeof(*u)))
index 465476e..af5f321 100644 (file)
@@ -76,9 +76,9 @@
 #define A(__x)         ((unsigned long)(__x))
 #define AA(__x)                ((unsigned long)(__x))
 #define ROUND_UP(x,a)  ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
+#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
 
-int cp_compat_stat(struct kstat *kbuf, struct compat_stat *ubuf)
+int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
 {
        typeof(ubuf->st_uid) uid = 0;
        typeof(ubuf->st_gid) gid = 0;
@@ -110,7 +110,7 @@ int cp_compat_stat(struct kstat *kbuf, struct compat_stat *ubuf)
 }
 
 asmlinkage long
-sys32_truncate64(char * filename, unsigned long offset_low, unsigned long offset_high)
+sys32_truncate64(char __user * filename, unsigned long offset_low, unsigned long offset_high)
 {
        return sys_truncate(filename, ((loff_t) offset_high << 32) | offset_low);
 }
@@ -125,7 +125,7 @@ sys32_ftruncate64(unsigned int fd, unsigned long offset_low, unsigned long offse
    support for 64bit inode numbers. */
 
 static int
-cp_stat64(struct stat64 *ubuf, struct kstat *stat)
+cp_stat64(struct stat64 __user *ubuf, struct kstat *stat)
 {
        typeof(ubuf->st_uid) uid = 0;
        typeof(ubuf->st_gid) gid = 0;
@@ -154,7 +154,7 @@ cp_stat64(struct stat64 *ubuf, struct kstat *stat)
 }
 
 asmlinkage long
-sys32_stat64(char * filename, struct stat64 *statbuf)
+sys32_stat64(char __user * filename, struct stat64 __user *statbuf)
 {
        struct kstat stat;
        int ret = vfs_stat(filename, &stat);
@@ -164,7 +164,7 @@ sys32_stat64(char * filename, struct stat64 *statbuf)
 }
 
 asmlinkage long
-sys32_lstat64(char * filename, struct stat64 *statbuf)
+sys32_lstat64(char __user * filename, struct stat64 __user *statbuf)
 {
        struct kstat stat;
        int ret = vfs_lstat(filename, &stat);
@@ -174,7 +174,7 @@ sys32_lstat64(char * filename, struct stat64 *statbuf)
 }
 
 asmlinkage long
-sys32_fstat64(unsigned int fd, struct stat64 *statbuf)
+sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf)
 {
        struct kstat stat;
        int ret = vfs_fstat(fd, &stat);
@@ -199,7 +199,7 @@ struct mmap_arg_struct {
 };
 
 asmlinkage long
-sys32_mmap(struct mmap_arg_struct *arg)
+sys32_mmap(struct mmap_arg_struct __user *arg)
 {
        struct mmap_arg_struct a;
        struct file *file = NULL;
@@ -241,7 +241,7 @@ sys32_mprotect(unsigned long start, size_t len, unsigned long prot)
 }
 
 asmlinkage long
-sys32_pipe(int *fd)
+sys32_pipe(int __user *fd)
 {
        int retval;
        int fds[2];
@@ -256,8 +256,8 @@ sys32_pipe(int *fd)
 }
 
 asmlinkage long
-sys32_rt_sigaction(int sig, struct sigaction32 *act,
-                  struct sigaction32 *oact,  unsigned int sigsetsize)
+sys32_rt_sigaction(int sig, struct sigaction32 __user *act,
+                  struct sigaction32 __user *oact,  unsigned int sigsetsize)
 {
        struct k_sigaction new_ka, old_ka;
        int ret;
@@ -321,7 +321,7 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act,
 }
 
 asmlinkage long
-sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
+sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact)
 {
         struct k_sigaction new_ka, old_ka;
         int ret;
@@ -395,7 +395,7 @@ sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
 }
 
 static inline long
-get_tv32(struct timeval *o, struct compat_timeval *i)
+get_tv32(struct timeval *o, struct compat_timeval __user *i)
 {
        int err = -EFAULT; 
        if (access_ok(VERIFY_READ, i, sizeof(*i))) { 
@@ -406,7 +406,7 @@ get_tv32(struct timeval *o, struct compat_timeval *i)
 }
 
 static inline long
-put_tv32(struct compat_timeval *o, struct timeval *i)
+put_tv32(struct compat_timeval __user *o, struct timeval *i)
 {
        int err = -EFAULT;
        if (access_ok(VERIFY_WRITE, o, sizeof(*o))) { 
@@ -442,7 +442,7 @@ sys32_alarm(unsigned int seconds)
 extern struct timezone sys_tz;
 
 asmlinkage long
-sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
+sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
 {
        if (tv) {
                struct timeval ktv;
@@ -458,7 +458,7 @@ sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
 }
 
 asmlinkage long
-sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
+sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
 {
        struct timeval ktv;
        struct timespec kts;
@@ -493,14 +493,14 @@ struct old_linux32_dirent {
 };
 
 struct getdents32_callback {
-       struct linux32_dirent * current_dir;
-       struct linux32_dirent * previous;
+       struct linux32_dirent __user * current_dir;
+       struct linux32_dirent __user * previous;
        int count;
        int error;
 };
 
 struct readdir32_callback {
-       struct old_linux32_dirent * dirent;
+       struct old_linux32_dirent __user * dirent;
        int count;
 };
 
@@ -508,7 +508,7 @@ static int
 filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
           unsigned int d_type)
 {
-       struct linux32_dirent * dirent;
+       struct linux32_dirent __user * dirent;
        struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
        int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2, 4);
 
@@ -524,18 +524,18 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
        put_user(reclen, &dirent->d_reclen);
        copy_to_user(dirent->d_name, name, namlen);
        put_user(0, dirent->d_name + namlen);
-       put_user(d_type, (char *)dirent + reclen - 1); 
-       dirent = ((void *)dirent) + reclen;
+       put_user(d_type, (char __user *)dirent + reclen - 1); 
+       dirent = ((void __user *)dirent) + reclen;
        buf->current_dir = dirent;
        buf->count -= reclen;
        return 0;
 }
 
 asmlinkage long
-sys32_getdents (unsigned int fd, void * dirent, unsigned int count)
+sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count)
 {
        struct file * file;
-       struct linux32_dirent * lastdirent;
+       struct linux32_dirent __user * lastdirent;
        struct getdents32_callback buf;
        int error;
 
@@ -544,7 +544,7 @@ sys32_getdents (unsigned int fd, void * dirent, unsigned int count)
        if (!file)
                goto out;
 
-       buf.current_dir = (struct linux32_dirent *) dirent;
+       buf.current_dir = (struct linux32_dirent __user *) dirent;
        buf.previous = NULL;
        buf.count = count;
        buf.error = 0;
@@ -569,7 +569,7 @@ static int
 fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned d_type)
 {
        struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
-       struct old_linux32_dirent * dirent;
+       struct old_linux32_dirent __user * dirent;
 
        if (buf->count)
                return -EINVAL;
@@ -584,7 +584,7 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t
 }
 
 asmlinkage long
-sys32_oldreaddir (unsigned int fd, void * dirent, unsigned int count)
+sys32_oldreaddir (unsigned int fd, void __user * dirent, unsigned int count)
 {
        int error;
        struct file * file;
@@ -615,7 +615,7 @@ struct sel_arg_struct {
 };
 
 asmlinkage long
-sys32_old_select(struct sel_arg_struct *arg)
+sys32_old_select(struct sel_arg_struct __user *arg)
 {
        struct sel_arg_struct a;
 
@@ -630,7 +630,7 @@ sys32_old_select(struct sel_arg_struct *arg)
  * sys_gettimeofday().  x86-64 did this but i386 Linux did not
  * so we have to implement this system call here.
  */
-asmlinkage long sys32_time(int * tloc)
+asmlinkage long sys32_time(int __user * tloc)
 {
        int i;
        struct timeval tv;
@@ -693,7 +693,7 @@ struct sysinfo32 {
 };
 
 asmlinkage long
-sys32_sysinfo(struct sysinfo32 *info)
+sys32_sysinfo(struct sysinfo32 __user *info)
 {
        struct sysinfo s;
        int ret;
@@ -742,7 +742,7 @@ sys32_sysinfo(struct sysinfo32 *info)
 }
                 
 asmlinkage long
-sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec *interval)
+sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval)
 {
        struct timespec t;
        int ret;
@@ -782,8 +782,8 @@ sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
 
 
 asmlinkage long
-sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo,
-                     struct compat_timespec *uts, compat_size_t sigsetsize)
+sys32_rt_sigtimedwait(compat_sigset_t __user *uthese, siginfo_t32 __user *uinfo,
+                     struct compat_timespec __user *uts, compat_size_t sigsetsize)
 {
        sigset_t s;
        compat_sigset_t s32;
@@ -820,7 +820,7 @@ sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo,
 }
 
 asmlinkage long
-sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
+sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 __user *uinfo)
 {
        siginfo_t info;
        int ret;
@@ -856,7 +856,7 @@ struct sysctl_ia32 {
 
 
 asmlinkage long
-sys32_sysctl(struct sysctl_ia32 *args32)
+sys32_sysctl(struct sysctl_ia32 __user *args32)
 {
 #ifndef CONFIG_SYSCTL
        return -ENOSYS; 
@@ -906,14 +906,14 @@ sys32_sysctl(struct sysctl_ia32 *args32)
 
 /* warning: next two assume little endian */ 
 asmlinkage long
-sys32_pread(unsigned int fd, char *ubuf, u32 count, u32 poslo, u32 poshi)
+sys32_pread(unsigned int fd, char __user *ubuf, u32 count, u32 poslo, u32 poshi)
 {
        return sys_pread64(fd, ubuf, count,
                         ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
 asmlinkage long
-sys32_pwrite(unsigned int fd, char *ubuf, u32 count, u32 poslo, u32 poshi)
+sys32_pwrite(unsigned int fd, char __user *ubuf, u32 count, u32 poslo, u32 poshi)
 {
        return sys_pwrite64(fd, ubuf, count,
                          ((loff_t)AA(poshi) << 32) | AA(poslo));
@@ -934,7 +934,7 @@ sys32_personality(unsigned long personality)
 }
 
 asmlinkage long
-sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, s32 count)
+sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count)
 {
        mm_segment_t old_fs = get_fs();
        int ret;
@@ -971,7 +971,7 @@ struct timex32 {
 extern int do_adjtimex(struct timex *);
 
 asmlinkage long
-sys32_adjtimex(struct timex32 *utp)
+sys32_adjtimex(struct timex32 __user *utp)
 {
        struct timex txc;
        int ret;
@@ -1056,7 +1056,7 @@ asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
        return error;
 }
 
-asmlinkage long sys32_olduname(struct oldold_utsname * name)
+asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
 {
        int error;
 
@@ -1090,7 +1090,7 @@ asmlinkage long sys32_olduname(struct oldold_utsname * name)
         return error;
 }
 
-long sys32_uname(struct old_utsname * name)
+long sys32_uname(struct old_utsname __user * name)
 {
        int err;
        if (!name)
@@ -1124,7 +1124,7 @@ long sys32_ustat(unsigned dev, struct ustat32 __user *u32p)
        return ret;
 } 
 
-asmlinkage long sys32_execve(char *name, compat_uptr_t __user *argv,
+asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv,
                             compat_uptr_t __user *envp, struct pt_regs regs)
 {
        long error;
@@ -1143,8 +1143,8 @@ asmlinkage long sys32_execve(char *name, compat_uptr_t __user *argv,
 
 asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp, struct pt_regs regs)
 {
-       void *parent_tid = (void *)regs.rdx;
-       void *child_tid = (void *)regs.rdi; 
+       void __user *parent_tid = (void __user *)regs.rdx;
+       void __user *child_tid = (void __user *)regs.rdi; 
        if (!newsp)
                newsp = regs.rsp;
         return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, 
@@ -1166,7 +1166,7 @@ long sys32_kill(int pid, int sig)
 }
  
 
-long sys32_io_setup(unsigned nr_reqs, u32 *ctx32p)
+long sys32_io_setup(unsigned nr_reqs, u32 __user *ctx32p)
 { 
        long ret; 
        aio_context_t ctx64;
@@ -1181,7 +1181,7 @@ long sys32_io_setup(unsigned nr_reqs, u32 *ctx32p)
 } 
 
 asmlinkage long sys32_io_submit(aio_context_t ctx_id, int nr,
-                  compat_uptr_t *iocbpp)
+                  compat_uptr_t __user *iocbpp)
 {
        struct kioctx *ctx;
        long ret = 0;
@@ -1201,7 +1201,8 @@ asmlinkage long sys32_io_submit(aio_context_t ctx_id, int nr,
 
        for (i=0; i<nr; i++) {
                compat_uptr_t p32;
-               struct iocb *user_iocb, tmp;
+               struct iocb __user *user_iocb;
+               struct iocb tmp;
 
                if (unlikely(__get_user(p32, iocbpp + i))) {
                        ret = -EFAULT;
@@ -1227,8 +1228,8 @@ asmlinkage long sys32_io_submit(aio_context_t ctx_id, int nr,
 asmlinkage long sys32_io_getevents(aio_context_t ctx_id,
                                 unsigned long min_nr,
                                 unsigned long nr,
-                                struct io_event *events,
-                                struct compat_timespec *timeout)
+                                struct io_event __user *events,
+                                struct compat_timespec __user *timeout)
 {      
        long ret;
        mm_segment_t oldfs; 
@@ -1248,7 +1249,7 @@ asmlinkage long sys32_io_getevents(aio_context_t ctx_id,
        return ret;
 } 
 
-asmlinkage long sys32_open(const char * filename, int flags, int mode)
+asmlinkage long sys32_open(const char __user * filename, int flags, int mode)
 {
        char * tmp;
        int fd, error;
@@ -1285,11 +1286,11 @@ sys_timer_create(clockid_t which_clock,
                 timer_t __user * created_timer_id);
 
 long
-sys32_timer_create(u32 clock, struct sigevent32 *se32, timer_t *timer_id)
+sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id)
 {
        struct sigevent se;
-       mm_segment_t oldfs;
-       long err;
+       mm_segment_t oldfs;
+       long err;
 
        if (se32) { 
                memset(&se, 0, sizeof(struct sigevent)); 
@@ -1303,9 +1304,9 @@ sys32_timer_create(u32 clock, struct sigevent32 *se32, timer_t *timer_id)
        if (!access_ok(VERIFY_WRITE,timer_id,sizeof(timer_t)))
                return -EFAULT;
 
-       oldfs = get_fs();
+       oldfs = get_fs();
        set_fs(KERNEL_DS);
-       err = sys_timer_create(clock, se32 ? &se : NULL, timer_id);
+       err = sys_timer_create(clock, se32 ? &se : NULL, timer_id);
        set_fs(oldfs); 
        
        return err; 
index 64b7a59..1806bff 100644 (file)
@@ -83,9 +83,9 @@ void __init syscall32_cpu_init(void)
 
        /* Load these always in case some future AMD CPU supports
           SYSENTER from compat mode too. */
-       wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
-       wrmsr(MSR_IA32_SYSENTER_ESP, 0, 0);
-       wrmsrl(MSR_IA32_SYSENTER_EIP, ia32_sysenter_target);
+       checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
+       checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL);
+       checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);
 
        wrmsrl(MSR_CSTAR, ia32_cstar_target);
 }
index b938935..1cc4340 100644 (file)
@@ -28,7 +28,7 @@ static int get_free_idx(void)
  * Set a given TLS descriptor:
  * When you want addresses > 32bit use arch_prctl() 
  */
-int do_set_thread_area(struct thread_struct *t, struct user_desc *u_info)
+int do_set_thread_area(struct thread_struct *t, struct user_desc __user *u_info)
 {
        struct user_desc info;
        struct n_desc_struct *desc;
@@ -75,7 +75,7 @@ int do_set_thread_area(struct thread_struct *t, struct user_desc *u_info)
        return 0;
 }
 
-asmlinkage long sys32_set_thread_area(struct user_desc *u_info)
+asmlinkage long sys32_set_thread_area(struct user_desc __user *u_info)
 { 
        return do_set_thread_area(&current->thread, u_info); 
 } 
@@ -102,7 +102,7 @@ asmlinkage long sys32_set_thread_area(struct user_desc *u_info)
 #define GET_USEABLE(desc)      (((desc)->b >> 20) & 1)
 #define GET_LONGMODE(desc)     (((desc)->b >> 21) & 1)
 
-int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info)
+int do_get_thread_area(struct thread_struct *t, struct user_desc __user *u_info)
 {
        struct user_desc info;
        struct n_desc_struct *desc;
@@ -132,7 +132,7 @@ int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info)
        return 0;
 }
 
-asmlinkage long sys32_get_thread_area(struct user_desc *u_info)
+asmlinkage long sys32_get_thread_area(struct user_desc __user *u_info)
 {
        return do_get_thread_area(&current->thread, u_info);
 } 
@@ -141,10 +141,11 @@ asmlinkage long sys32_get_thread_area(struct user_desc *u_info)
 int ia32_child_tls(struct task_struct *p, struct pt_regs *childregs)
 {
        struct n_desc_struct *desc;
-       struct user_desc info, *cp;
+       struct user_desc info;
+       struct user_desc __user *cp;
        int idx;
        
-       cp = (void *)childregs->rsi;
+       cp = (void __user *)childregs->rsi;
        if (copy_from_user(&info, cp, sizeof(info)))
                return -EFAULT;
        if (LDT_empty(&info))
index 20e9266..3331a56 100644 (file)
@@ -114,7 +114,6 @@ void __init acpi_reserve_bootmem(void)
        acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
        if ((&wakeup_end - &wakeup_start) > PAGE_SIZE)
                printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n");
-       printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
 }
 
 static int __init acpi_sleep_setup(char *str)
index 6235eab..90fb846 100644 (file)
@@ -34,7 +34,7 @@ unsigned long end_pfn_map;
  */
 unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT;  
 
-extern struct resource code_resource, data_resource, vram_resource;
+extern struct resource code_resource, data_resource;
 
 /* Check for some hardcoded bad areas that early boot is not allowed to touch */ 
 static inline int bad_addr(unsigned long *addrp, unsigned long size)
index b04a1ad..4055c78 100644 (file)
@@ -73,6 +73,8 @@ static void __init setup_boot_cpu_data(void)
        boot_cpu_data.x86_mask = eax & 0xf;
 }
 
+extern char _end[];
+
 void __init x86_64_start_kernel(char * real_mode_data)
 {
        char *s;
@@ -80,6 +82,9 @@ void __init x86_64_start_kernel(char * real_mode_data)
        clear_bss();
        pda_init(0);
        copy_bootdata(real_mode_data);
+#ifdef CONFIG_SMP
+       cpu_set(0, cpu_online_map);
+#endif
        /* default console: */
        if (!strstr(saved_command_line, "console="))
                strcat(saved_command_line, " console=tty0"); 
@@ -95,6 +100,10 @@ void __init x86_64_start_kernel(char * real_mode_data)
        if (strstr(saved_command_line, "disableapic"))
                disable_apic = 1;
 #endif
+       /* You need early console to see that */
+       if (__pa_symbol(&_end) >= KERNEL_TEXT_SIZE)
+               panic("Kernel too big for kernel mapping\n");
+
        setup_boot_cpu_data();
        start_kernel();
 }
index 1aa4deb..6bc3d64 100644 (file)
@@ -77,7 +77,7 @@ void init_fpu(struct task_struct *child)
  * Signal frame handlers.
  */
 
-int save_i387(struct _fpstate *buf)
+int save_i387(struct _fpstate __user *buf)
 {
        struct task_struct *tsk = current;
        int err = 0;
@@ -95,7 +95,7 @@ int save_i387(struct _fpstate *buf)
                return 0;
        tsk->used_math = 0; /* trigger finit */ 
        if (tsk->thread_info->status & TS_USEDFPU) {
-               err = save_i387_checking((struct i387_fxsave_struct *)buf);
+               err = save_i387_checking((struct i387_fxsave_struct __user *)buf);
                if (err) return err;
                stts();
                } else {
@@ -110,14 +110,14 @@ int save_i387(struct _fpstate *buf)
  * ptrace request handlers.
  */
 
-int get_fpregs(struct user_i387_struct *buf, struct task_struct *tsk)
+int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *tsk)
 {
        init_fpu(tsk);
-       return __copy_to_user((void *)buf, &tsk->thread.i387.fxsave,
+       return __copy_to_user(buf, &tsk->thread.i387.fxsave,
                               sizeof(struct user_i387_struct)) ? -EFAULT : 0;
 }
 
-int set_fpregs(struct task_struct *tsk, struct user_i387_struct *buf)
+int set_fpregs(struct task_struct *tsk, struct user_i387_struct __user *buf)
 {
        if (__copy_from_user(&tsk->thread.i387.fxsave, buf, 
                             sizeof(struct user_i387_struct)))
index 57ec2f0..33185ca 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/init.h>
 #include <linux/init_task.h>
 #include <linux/fs.h>
+#include <linux/mqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
index f7625f3..718504a 100644 (file)
@@ -252,7 +252,8 @@ void __init check_ioapic(void)
                                switch (vendor) { 
                                case PCI_VENDOR_ID_VIA:
 #ifdef CONFIG_GART_IOMMU
-                                       if (end_pfn >= (0xffffffff>>PAGE_SHIFT) &&
+                                       if ((end_pfn >= (0xffffffff>>PAGE_SHIFT) ||
+                                            force_iommu) &&
                                            !iommu_aperture_allowed) {
                                                printk(KERN_INFO
     "Looks like a VIA chipset. Disabling IOMMU. Overwrite with \"iommu=allowed\"\n");
index 732a6f4..bfdb95e 100644 (file)
@@ -833,7 +833,8 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off,
        return len;
 }
 
-static int irq_affinity_write_proc (struct file *file, const char *buffer,
+static int irq_affinity_write_proc (struct file *file,
+                                       const char __user *buffer,
                                        unsigned long count, void *data)
 {
        int irq = (long) data, full_count = count, err;
@@ -871,7 +872,8 @@ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
        return len;
 }
 
-static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
+static int prof_cpu_mask_write_proc (struct file *file,
+                                       const char __user *buffer,
                                        unsigned long count, void *data)
 {
        unsigned long full_count = count, err;
index 1b6252c..4e43e53 100644 (file)
@@ -125,7 +125,7 @@ void destroy_context(struct mm_struct *mm)
        }
 }
 
-static int read_ldt(void * ptr, unsigned long bytecount)
+static int read_ldt(void __user * ptr, unsigned long bytecount)
 {
        int err;
        unsigned long size;
@@ -153,7 +153,7 @@ static int read_ldt(void * ptr, unsigned long bytecount)
        return bytecount;
 }
 
-static int read_default_ldt(void * ptr, unsigned long bytecount)
+static int read_default_ldt(void __user * ptr, unsigned long bytecount)
 {
        /* Arbitrary number */ 
        /* x86-64 default LDT is all zeros */
@@ -164,7 +164,7 @@ static int read_default_ldt(void * ptr, unsigned long bytecount)
        return bytecount; 
 }
 
-static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
+static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
 {
        struct task_struct *me = current;
        struct mm_struct * mm = me->mm;
@@ -225,7 +225,7 @@ out:
        return error;
 }
 
-asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
 {
        int ret = -ENOSYS;
 
index 922d62f..3bb678f 100644 (file)
@@ -25,8 +25,9 @@
 #define NR_BANKS 5
 
 static int mce_disabled __initdata;
-/* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic */ 
-static int tolerant = 2;
+/* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic,
+   3: never panic or exit (for testing only) */
+static int tolerant = 1;
 static int banks;
 static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL };
 
@@ -96,7 +97,8 @@ static void mce_panic(char *msg, struct mce *backup, unsigned long start)
        int i;
        oops_begin();
        for (i = 0; i < MCE_LOG_LEN; i++) {
-               if (mcelog.entry[i].tsc < start)
+               unsigned long tsc = mcelog.entry[i].tsc;
+               if (time_before(tsc, start))
                        continue;
                print_mce(&mcelog.entry[i]); 
                if (mcelog.entry[i].tsc == backup->tsc)
@@ -104,7 +106,10 @@ static void mce_panic(char *msg, struct mce *backup, unsigned long start)
        }
        if (backup)
                print_mce(backup);
-       panic(msg);
+       if (tolerant >= 3)
+               printk("Fake panic: %s\n", msg);
+       else
+               panic(msg);
 } 
 
 static int mce_available(struct cpuinfo_x86 *c)
@@ -120,8 +125,8 @@ static int mce_available(struct cpuinfo_x86 *c)
 
 void do_machine_check(struct pt_regs * regs, long error_code)
 {
-       struct mce m;
-       int nowayout = 0;
+       struct mce m, panicm;
+       int nowayout = (tolerant < 1); 
        int kill_it = 0;
        u64 mcestart;
        int i;
@@ -149,13 +154,31 @@ void do_machine_check(struct pt_regs * regs, long error_code)
        for (i = 0; i < banks; i++) {
                if (!bank[i])
                        continue;
+               
+               m.misc = 0; 
+               m.addr = 0;
 
                rdmsrl(MSR_IA32_MC0_STATUS + i*4, m.status);
                if ((m.status & MCI_STATUS_VAL) == 0)
                        continue;
+               /* Should be implied by the banks check above, but
+                  check it anyways */
+               if ((m.status & MCI_STATUS_EN) == 0)
+                       continue;
 
-               nowayout |= (tolerant < 1); 
-               nowayout |= !!(m.status & (MCI_STATUS_OVER|MCI_STATUS_PCC));
+               /* Did this bank cause the exception? */
+               /* Assume that the bank with uncorrectable errors did it,
+                  and that there is only a single one. */
+               if (m.status & MCI_STATUS_UC) {
+                       panicm = m;
+               } else {
+                       m.rip = 0;
+                       m.cs = 0;
+               }
+
+               /* In theory _OVER could be a nowayout too, but
+                  assume any overflowed errors were no fatal. */
+               nowayout |= !!(m.status & MCI_STATUS_PCC);
                kill_it |= !!(m.status & MCI_STATUS_UC);
                m.bank = i;
 
@@ -176,7 +199,10 @@ void do_machine_check(struct pt_regs * regs, long error_code)
        if (nowayout)
                mce_panic("Machine check", &m, mcestart);
        if (kill_it) {
-               int user_space = (m.rip && (m.cs & 3));
+               int user_space = 0;
+
+               if (m.mcgstatus & MCG_STATUS_RIPV)
+                       user_space = m.rip && (m.cs & 3);
                
                /* When the machine was in user space and the CPU didn't get
                   confused it's normally not necessary to panic, unless you 
@@ -187,11 +213,12 @@ void do_machine_check(struct pt_regs * regs, long error_code)
                   it is best to just halt the machine. */
                if ((!user_space && (panic_on_oops || tolerant < 2)) ||
                    (unsigned)current->pid <= 1)
-                       mce_panic("Uncorrected machine check", &m, mcestart);
+                       mce_panic("Uncorrected machine check", &panicm, mcestart);
 
                /* do_exit takes an awful lot of locks and has as slight risk 
                   of deadlocking. If you don't want that don't set tolerant >= 2 */
-               do_exit(SIGBUS);
+               if (tolerant < 3)
+                       do_exit(SIGBUS);
        }
 }
 
@@ -207,7 +234,7 @@ static void mce_clear_all(void)
  * Periodic polling timer for "silent" machine check errors.
  */
 
-static int check_interval = 3600; /* one hour */
+static int check_interval = 5 * 60; /* 5 minutes */
 static void mcheck_timer(void *data);
 static DECLARE_WORK(mcheck_work, mcheck_timer, NULL);
 
@@ -297,12 +324,12 @@ static void collect_tscs(void *data)
        rdtscll(cpu_tsc[smp_processor_id()]);
 } 
 
-static ssize_t mce_read(struct file *filp, char *ubuf, size_t usize, loff_t *off)
+static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff_t *off)
 {
        unsigned long cpu_tsc[NR_CPUS];
        static DECLARE_MUTEX(mce_read_sem);
        unsigned next;
-       char *buf = ubuf;
+       char __user *buf = ubuf;
        int i, err;
 
        down(&mce_read_sem); 
@@ -348,19 +375,20 @@ static ssize_t mce_read(struct file *filp, char *ubuf, size_t usize, loff_t *off
 
 static int mce_ioctl(struct inode *i, struct file *f,unsigned int cmd, unsigned long arg)
 {
+       int __user *p = (int __user *)arg;
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM; 
        switch (cmd) {
        case MCE_GET_RECORD_LEN: 
-               return put_user(sizeof(struct mce), (int *)arg);
+               return put_user(sizeof(struct mce), p);
        case MCE_GET_LOG_LEN:
-               return put_user(MCE_LOG_LEN, (int *)arg);               
+               return put_user(MCE_LOG_LEN, p);                
        case MCE_GETCLEAR_FLAGS: {
                unsigned flags;
                do { 
                        flags = mcelog.flags;
                } while (cmpxchg(&mcelog.flags, flags, 0) != flags); 
-               return put_user(flags, (int *)arg); 
+               return put_user(flags, p); 
        }
        default:
                return -ENOTTY; 
index 27122be..c43bb7b 100644 (file)
@@ -575,6 +575,7 @@ static int __init smp_scan_config (unsigned long base, unsigned long length)
        extern void __bad_mpf_size(void); 
        unsigned int *bp = phys_to_virt(base);
        struct intel_mp_floating *mpf;
+       static int printed __initdata; 
 
        Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
        if (sizeof(*mpf) != 16)
@@ -598,7 +599,10 @@ static int __init smp_scan_config (unsigned long base, unsigned long length)
                bp += 4;
                length -= 16;
        }
-       printk(KERN_INFO "No mptable found.\n");
+       if (!printed) {         
+               printk(KERN_INFO "No mptable found.\n");
+               printed = 1;
+       }
        return 0;
 }
 
@@ -712,7 +716,7 @@ struct mp_ioapic_routing {
 } mp_ioapic_routing[MAX_IO_APICS];
 
 
-static int __init mp_find_ioapic (
+static int mp_find_ioapic (
        int                     gsi)
 {
        int                     i = 0;
@@ -857,6 +861,7 @@ void __init mp_config_acpi_legacy_irqs (void)
 
                for (idx = 0; idx < mp_irq_entries; idx++)
                        if (mp_irqs[idx].mpc_srcbus == MP_ISA_BUS &&
+                               (mp_irqs[idx].mpc_dstapic == ioapic) &&
                                (mp_irqs[idx].mpc_srcbusirq == i ||
                                mp_irqs[idx].mpc_dstirq == i))
                                        break;
@@ -884,91 +889,54 @@ void __init mp_config_acpi_legacy_irqs (void)
        return;
 }
 
-
-extern FADT_DESCRIPTOR acpi_fadt;
-
-#ifdef CONFIG_ACPI_PCI
-
-void __init mp_parse_prt (void)
+void mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
 {
-       struct list_head        *node = NULL;
-       struct acpi_prt_entry   *entry = NULL;
        int                     ioapic = -1;
        int                     ioapic_pin = 0;
-       int                     gsi = 0;
        int                     idx, bit = 0;
-       int                     edge_level = 0;
-       int                     active_high_low = 0;
 
-       /*
-        * Parsing through the PCI Interrupt Routing Table (PRT) and program
-        * routing for all static (IOAPIC-direct) entries.
-        */
-       list_for_each(node, &acpi_prt.entries) {
-               entry = list_entry(node, struct acpi_prt_entry, node);
-
-               /* Need to get gsi for dynamic entry */
-               if (entry->link.handle) {
-                       gsi = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low);
-                       if (!gsi)
-                               continue;
-               } else {
-                       /* Hardwired GSI. Assume PCI standard settings */
-                       gsi = entry->link.index;
-                       edge_level = 1;
-                       active_high_low = 1;
-               }
+       if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
+               return;
 
-               /* Don't set up the ACPI SCI because it's already set up */
-               if (acpi_fadt.sci_int == gsi) {
-                       /* we still need to set up the entry's irq */
-                       acpi_gsi_to_irq(gsi, &entry->irq);
-                       continue;
-               }
+#ifdef CONFIG_ACPI_BUS
+       /* Don't set up the ACPI SCI because it's already set up */
+       if (acpi_fadt.sci_int == gsi)
+               return;
+#endif
 
-               ioapic = mp_find_ioapic(gsi);
-               if (ioapic < 0)
-                       continue;
-               ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start;
+       ioapic = mp_find_ioapic(gsi);
+       if (ioapic < 0) {
+               printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
+               return;
+       }
 
-               /* 
-                * Avoid pin reprogramming.  PRTs typically include entries  
-                * with redundant pin->gsi mappings (but unique PCI devices);
-                * we only only program the IOAPIC on the first.
-                */
-               bit = ioapic_pin % 32;
-               idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
-               if (idx > 3) {
-                       printk(KERN_ERR "Invalid reference to IOAPIC pin "
-                               "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, 
-                               ioapic_pin);
-                       continue;
-               }
-               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);
-                       acpi_gsi_to_irq(gsi, &entry->irq);
-                       continue;
-               }
+       ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start;
 
-               mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
-               if (!io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, edge_level, active_high_low)) {
-                       acpi_gsi_to_irq(gsi, &entry->irq);
-               }
-               printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n",
-                       entry->id.segment, entry->id.bus,
-                       entry->id.device, ('A' + entry->pin), 
-                       mp_ioapic_routing[ioapic].apic_id, ioapic_pin,
-                       entry->irq);
+       /* 
+        * Avoid pin reprogramming.  PRTs typically include entries  
+        * with redundant pin->gsi mappings (but unique PCI devices);
+        * we only program the IOAPIC on the first.
+        */
+       bit = ioapic_pin % 32;
+       idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
+       if (idx > 3) {
+               printk(KERN_ERR "Invalid reference to IOAPIC pin "
+                       "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, 
+                       ioapic_pin);
+               return;
+       }
+       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;
        }
-       
-       print_IO_APIC();
 
-       return;
-}
+       mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
 
-#endif /*CONFIG_ACPI_PCI*/
+       io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
+               edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
+               active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
+}
 
 #endif /*CONFIG_X86_IO_APIC*/
-
 #endif /*CONFIG_ACPI_BOOT*/
index d2e6fff..654e457 100644 (file)
@@ -186,10 +186,10 @@ static loff_t msr_seek(struct file *file, loff_t offset, int orig)
   return ret;
 }
 
-static ssize_t msr_read(struct file * file, char * buf,
+static ssize_t msr_read(struct file * file, char __user * buf,
                        size_t count, loff_t *ppos)
 {
-  u32 *tmp = (u32 *)buf;
+  char __user *tmp = buf;
   u32 data[2];
   size_t rv;
   u32 reg = *ppos;
@@ -205,16 +205,16 @@ static ssize_t msr_read(struct file * file, char * buf,
       return err;
     if ( copy_to_user(tmp,&data,8) )
       return -EFAULT;
-    tmp += 2;
+    tmp += 8;
   }
 
-  return ((char *)tmp) - buf;
+  return tmp - buf;
 }
 
-static ssize_t msr_write(struct file * file, const char * buf,
+static ssize_t msr_write(struct file * file, const char __user * buf,
                         size_t count, loff_t *ppos)
 {
-  const u32 *tmp = (const u32 *)buf;
+  const char __user *tmp = buf;
   u32 data[2];
   size_t rv;
   u32 reg = *ppos;
@@ -230,10 +230,10 @@ static ssize_t msr_write(struct file * file, const char * buf,
     err = do_wrmsr(cpu, reg, data[0], data[1]);
     if ( err )
       return err;
-    tmp += 2;
+    tmp += 8;
   }
 
-  return ((char *)tmp) - buf;
+  return tmp - buf;
 }
 
 static int msr_open(struct inode *inode, struct file *file)
@@ -241,7 +241,7 @@ static int msr_open(struct inode *inode, struct file *file)
   int cpu = iminor(file->f_dentry->d_inode);
   struct cpuinfo_x86 *c = &(cpu_data)[cpu];
   
-  if (!cpu_online(cpu))
+  if (cpu >= NR_CPUS || !cpu_online(cpu))
     return -ENXIO;             /* No such CPU */
   if ( !cpu_has(c, X86_FEATURE_MSR) )
     return -EIO;               /* MSR not supported */
index 6b78619..f7d3cf3 100644 (file)
@@ -521,7 +521,8 @@ struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct *
  * sys_execve() executes a new program.
  */
 asmlinkage 
-long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs)
+long sys_execve(char __user *name, char __user * __user *argv,
+               char __user * __user *envp, struct pt_regs regs)
 {
        long error;
        char * filename;
@@ -550,7 +551,7 @@ asmlinkage long sys_fork(struct pt_regs regs)
        return do_fork(SIGCHLD, regs.rsp, &regs, 0, NULL, NULL);
 }
 
-asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void *parent_tid, void *child_tid, struct pt_regs regs)
+asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void __user *parent_tid, void __user *child_tid, struct pt_regs regs)
 {
        if (!newsp)
                newsp = regs.rsp;
@@ -664,7 +665,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
                        rdmsrl(MSR_FS_BASE, base);
                } else
                        base = task->thread.fs;
-               ret = put_user(base, (unsigned long *)addr); 
+               ret = put_user(base, (unsigned long __user *)addr); 
                break; 
        }
        case ARCH_GET_GS: { 
@@ -675,7 +676,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
                        rdmsrl(MSR_KERNEL_GS_BASE, base);
                } else
                        base = task->thread.gs;
-               ret = put_user(base, (unsigned long *)addr); 
+               ret = put_user(base, (unsigned long __user *)addr); 
                break;
        }
 
index a97bee6..5dd7752 100644 (file)
@@ -232,7 +232,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
                ret = -EIO;
                if (copied != sizeof(tmp))
                        break;
-               ret = put_user(tmp,(unsigned long *) data);
+               ret = put_user(tmp,(unsigned long __user *) data);
                break;
        }
 
@@ -271,7 +271,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
                        tmp = 0;
                        break;
                }
-               ret = put_user(tmp,(unsigned long *) data);
+               ret = put_user(tmp,(unsigned long __user *) data);
                break;
        }
 
@@ -360,19 +360,20 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
                   don't use it against 64bit processes, use
                   PTRACE_ARCH_PRCTL instead. */
        case PTRACE_SET_THREAD_AREA: {
+               struct user_desc __user *p;
                int old; 
-               get_user(old,  &((struct user_desc *)data)->entry_number); 
-               put_user(addr, &((struct user_desc *)data)->entry_number);
-               ret = do_set_thread_area(&child->thread, 
-                                        (struct user_desc *)data);
-               put_user(old,  &((struct user_desc *)data)->entry_number); 
+               p = (struct user_desc __user *)data;
+               get_user(old,  &p->entry_number); 
+               put_user(addr, &p->entry_number);
+               ret = do_set_thread_area(&child->thread, p);
+               put_user(old,  &p->entry_number); 
                break;
        case PTRACE_GET_THREAD_AREA:
-               get_user(old,  &((struct user_desc *)data)->entry_number); 
-               put_user(addr, &((struct user_desc *)data)->entry_number);
-               ret = do_get_thread_area(&child->thread, 
-                                        (struct user_desc *)data);
-               put_user(old,  &((struct user_desc *)data)->entry_number); 
+               p = (struct user_desc __user *)data;
+               get_user(old,  &p->entry_number); 
+               put_user(addr, &p->entry_number);
+               ret = do_get_thread_area(&child->thread, p);
+               put_user(old,  &p->entry_number); 
                break;
        } 
 #endif
@@ -428,12 +429,12 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
                break;
 
        case PTRACE_GETREGS: { /* Get all gp regs from the child. */
-               if (!access_ok(VERIFY_WRITE, (unsigned *)data, FRAME_SIZE)) {
+               if (!access_ok(VERIFY_WRITE, (unsigned __user *)data, FRAME_SIZE)) {
                        ret = -EIO;
                        break;
                }
                for (ui = 0; ui < sizeof(struct user_regs_struct); ui += sizeof(long)) {
-                       __put_user(getreg(child, ui),(unsigned long *) data);
+                       __put_user(getreg(child, ui),(unsigned long __user *) data);
                        data += sizeof(long);
                }
                ret = 0;
@@ -442,12 +443,12 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
 
        case PTRACE_SETREGS: { /* Set all gp regs in the child. */
                unsigned long tmp;
-               if (!access_ok(VERIFY_READ, (unsigned *)data, FRAME_SIZE)) {
+               if (!access_ok(VERIFY_READ, (unsigned __user *)data, FRAME_SIZE)) {
                        ret = -EIO;
                        break;
                }
                for (ui = 0; ui < sizeof(struct user_regs_struct); ui += sizeof(long)) {
-                       __get_user(tmp, (unsigned long *) data);
+                       __get_user(tmp, (unsigned long __user *) data);
                        putreg(child, ui, tmp);
                        data += sizeof(long);
                }
@@ -456,23 +457,23 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
        }
 
        case PTRACE_GETFPREGS: { /* Get the child extended FPU state. */
-               if (!access_ok(VERIFY_WRITE, (unsigned *)data,
+               if (!access_ok(VERIFY_WRITE, (unsigned __user *)data,
                               sizeof(struct user_i387_struct))) {
                        ret = -EIO;
                        break;
                }
-               ret = get_fpregs((struct user_i387_struct *)data, child);
+               ret = get_fpregs((struct user_i387_struct __user *)data, child);
                break;
        }
 
        case PTRACE_SETFPREGS: { /* Set the child extended FPU state. */
-               if (!access_ok(VERIFY_READ, (unsigned *)data,
+               if (!access_ok(VERIFY_READ, (unsigned __user *)data,
                               sizeof(struct user_i387_struct))) {
                        ret = -EIO;
                        break;
                }
                child->used_math = 1;
-               ret = set_fpregs(child, (struct user_i387_struct *)data);
+               ret = set_fpregs(child, (struct user_i387_struct __user *)data);
                break;
        }
 
index 09f9c72..094949f 100644 (file)
@@ -116,9 +116,10 @@ struct resource standard_io_resources[] = {
 #define STANDARD_IO_RESOURCES \
        (sizeof standard_io_resources / sizeof standard_io_resources[0])
 
-struct resource code_resource = { "Kernel code", 0x100000, 0, IORESOURCE_MEM };
-struct resource data_resource = { "Kernel data", 0, 0, IORESOURCE_MEM };
-struct resource vram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_BUSY | IORESOURCE_MEM };
+#define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM)
+
+struct resource data_resource = { "Kernel data", 0, 0, IORESOURCE_RAM };
+struct resource code_resource = { "Kernel code", 0, 0, IORESOURCE_RAM };
 
 #define IORESOURCE_ROM (IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM)
 
@@ -138,10 +139,11 @@ static struct resource adapter_rom_resources[] = {
        (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
 
 static struct resource video_rom_resource = { "Video ROM", 0xc0000, 0xc7fff, IORESOURCE_ROM };
+static struct resource video_ram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_RAM };
 
 #define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
 
-static int __init checksum(unsigned char *rom, unsigned long length)
+static int __init romchecksum(unsigned char *rom, unsigned long length)
 {
        unsigned char *p, sum = 0;
 
@@ -169,7 +171,7 @@ static void __init probe_roms(void)
                length = rom[2] * 512;
 
                /* if checksum okay, trust length byte */
-               if (length && checksum(rom, length))
+               if (length && romchecksum(rom, length))
                        video_rom_resource.end = start + length - 1;
 
                request_resource(&iomem_resource, &video_rom_resource);
@@ -188,7 +190,7 @@ static void __init probe_roms(void)
        rom = isa_bus_to_virt(extension_rom_resource.start);
        if (romsignature(rom)) {
                length = extension_rom_resource.end - extension_rom_resource.start + 1;
-               if (checksum(rom, length)) {
+               if (romchecksum(rom, length)) {
                        request_resource(&iomem_resource, &extension_rom_resource);
                        upper = extension_rom_resource.start;
                }
@@ -204,7 +206,7 @@ static void __init probe_roms(void)
                length = rom[2] * 512;
 
                /* but accept any length that fits if checksum okay */
-               if (!length || start + length > upper || !checksum(rom, length))
+               if (!length || start + length > upper || !romchecksum(rom, length))
                        continue;
 
                adapter_rom_resources[i].start = start;
@@ -253,6 +255,8 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                /* acpi=ht just means: do ACPI MADT parsing 
                   at bootup, but don't enable the full ACPI interpreter */
                if (!memcmp(from, "acpi=ht", 7)) { 
+                       /* if (!acpi_force) */
+                               disable_acpi();
                        acpi_ht = 1; 
                }
                 else if (!memcmp(from, "pci=noacpi", 10)) 
@@ -535,8 +539,7 @@ void __init setup_arch(char **cmdline_p)
         * the bootmem allocator) but before get_smp_config (to allow parsing
         * of MADT).
         */
-       if (!acpi_disabled)
-               acpi_boot_init();
+       acpi_boot_init();
 #endif
 #ifdef CONFIG_X86_LOCAL_APIC
        /*
@@ -554,13 +557,13 @@ void __init setup_arch(char **cmdline_p)
        probe_roms();
        e820_reserve_resources(); 
 
-       request_resource(&iomem_resource, &vram_resource);
+       request_resource(&iomem_resource, &video_ram_resource);
 
        {
        unsigned i;
        /* request I/O space for devices used on all i[345]86 PCs */
        for (i = 0; i < STANDARD_IO_RESOURCES; i++)
-               request_resource(&ioport_resource, standard_io_resources+i);
+               request_resource(&ioport_resource, &standard_io_resources[i]);
        }
 
        /* Will likely break when you have unassigned resources with more
@@ -909,7 +912,7 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c)
                        c->x86_model += ((tfms >> 16) & 0xF) << 4;
                } 
                if (c->x86_capability[0] & (1<<19)) 
-                       c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
+                       c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
        } else {
                /* Have CPUID level 0 only - unheard of */
                c->x86 = 4;
@@ -967,7 +970,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
                        display_cacheinfo(c);
                        break;
        }
-       
+
        select_idle_routine(c);
        detect_ht(c); 
                
index dd0d415..9d3137a 100644 (file)
@@ -39,7 +39,7 @@ extern unsigned char __per_cpu_start[], __per_cpu_end[];
 extern struct desc_ptr cpu_gdt_descr[];
 struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table }; 
 
-char boot_cpu_stack[IRQSTACKSIZE] __cacheline_aligned;
+char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
 
 unsigned long __supported_pte_mask = ~0UL;
 static int do_not_nx __initdata = 0;
@@ -190,7 +190,8 @@ void pda_init(int cpu)
        pda->irqstackptr += IRQSTACKSIZE-64;
 } 
 
-char boot_exception_stacks[N_EXCEPTION_STACKS * EXCEPTION_STKSZ];
+char boot_exception_stacks[N_EXCEPTION_STACKS * EXCEPTION_STKSZ] 
+__attribute__((section(".bss.page_aligned")));
 
 void __init syscall_init(void)
 {
index fc81ceb..d814db6 100644 (file)
@@ -40,7 +40,7 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka,
             sigset_t *set, struct pt_regs * regs); 
 
 asmlinkage long
-sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs regs)
+sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs regs)
 {
        sigset_t saveset, newset;
 
@@ -57,7 +57,7 @@ sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs regs)
        current->blocked = newset;
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
        printk("rt_sigsuspend savset(%lx) newset(%lx) regs(%p) rip(%lx)\n",
                saveset, newset, &regs, regs.rip);
 #endif 
@@ -71,7 +71,7 @@ sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs regs)
 }
 
 asmlinkage long
-sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs regs)
+sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, struct pt_regs regs)
 {
        return do_sigaltstack(uss, uoss, regs.rsp);
 }
@@ -89,7 +89,7 @@ struct rt_sigframe
 };
 
 static int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, unsigned long *prax)
+restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, unsigned long *prax)
 {
        unsigned int err = 0;
 
@@ -117,7 +117,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, unsigned long *p
        }
 
        {
-               struct _fpstate * buf;
+               struct _fpstate __user * buf;
                err |= __get_user(buf, &sc->fpstate);
 
                if (buf) {
@@ -136,10 +136,11 @@ badframe:
 
 asmlinkage long sys_rt_sigreturn(struct pt_regs regs)
 {
-       struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 8);
+       struct rt_sigframe __user *frame;
        sigset_t set;
        long eax;
 
+       frame = (struct rt_sigframe __user *)(regs.rsp - 8);
        if (verify_area(VERIFY_READ, frame, sizeof(*frame))) { 
                goto badframe;
        } 
@@ -157,7 +158,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs regs)
                goto badframe;
        } 
 
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
        printk("%d sigreturn rip:%lx rsp:%lx frame:%p rax:%lx\n",current->pid,regs.rip,regs.rsp,frame,eax);
 #endif
 
@@ -176,7 +177,7 @@ badframe:
  */
 
 static inline int
-setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me)
+setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me)
 {
        int err = 0;
 
@@ -213,7 +214,7 @@ setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask
  * Determine which stack to use..
  */
 
-static void *
+static void __user *
 get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
 {
        unsigned long rsp;
@@ -228,20 +229,20 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
                        rsp = current->sas_ss_sp + current->sas_ss_size;
        }
 
-       return (void *)round_down(rsp - size, 16); 
+       return (void __user *)round_down(rsp - size, 16); 
 }
 
 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                           sigset_t *set, struct pt_regs * regs)
 {
-       struct rt_sigframe *frame;
-       struct _fpstate *fp = NULL; 
+       struct rt_sigframe __user *frame;
+       struct _fpstate __user *fp = NULL; 
        int err = 0;
        struct task_struct *me = current;
 
        if (me->used_math) {
                fp = get_stack(ka, regs, sizeof(struct _fpstate)); 
-               frame = (void *)round_down((u64)fp - sizeof(struct rt_sigframe), 16) - 8;
+               frame = (void __user *)round_down((u64)fp - sizeof(struct rt_sigframe), 16) - 8;
 
                if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) { 
                goto give_sigsegv;
@@ -294,7 +295,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                goto give_sigsegv;
        } 
 
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
        printk("%d old rip %lx old rsp %lx old rax %lx\n", current->pid,regs->rip,regs->rsp,regs->rax);
 #endif
 
@@ -319,7 +320,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        set_fs(USER_DS);
        regs->eflags &= ~TF_MASK;
 
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
        printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
                current->comm, current->pid, frame, regs->rip, frame->pretcode);
 #endif
@@ -342,7 +343,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
 {
        struct k_sigaction *ka = &current->sighand->action[sig-1];
 
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
        printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", current->pid, sig, 
                regs->rip, regs->rsp, regs);
 #endif
@@ -454,7 +455,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
 
 void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, __u32 thread_info_flags)
 {
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
        printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%lx pending:%lx\n",
               thread_info_flags, regs->rip, regs->rsp, __builtin_return_address(0),signal_pending(current)); 
 #endif
@@ -470,7 +471,7 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, __u32 thread_info_
                do_signal(regs,oldset);
 }
 
-void signal_fault(struct pt_regs *regs, void *frame, char *where)
+void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
 { 
        struct task_struct *me = current; 
        if (exception_trace)
index 3ea64ef..ba2cba6 100644 (file)
@@ -895,15 +895,17 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                                        cpu_set(i, cpu_sibling_map[cpu]);
                                }
                        }
-               } else {
+               } else { 
                        siblings++;
                        cpu_set(cpu, cpu_sibling_map[cpu]);
                }
 
-               if (siblings != smp_num_siblings)
-                       printk(KERN_WARNING
-              "WARNING: %d siblings found for CPU%d, should be %d\n",
+               if (siblings != smp_num_siblings) {
+                       printk(KERN_WARNING 
+              "WARNING: %d siblings found for CPU%d, should be %d\n", 
                               siblings, cpu, smp_num_siblings);
+                       smp_num_siblings = siblings;
+               }       
        }
 
        Dprintk("Boot done.\n");
index e518c1f..38a286c 100644 (file)
@@ -25,7 +25,7 @@
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way Unix traditionally does this, though.
  */
-asmlinkage long sys_pipe(int *fildes)
+asmlinkage long sys_pipe(int __user *fildes)
 {
        int fd[2];
        int error;
@@ -142,7 +142,7 @@ full_search:
        }
 }
 
-asmlinkage long sys_uname(struct new_utsname * name)
+asmlinkage long sys_uname(struct new_utsname __user * name)
 {
        int err;
        down_read(&uts_sem);
@@ -153,13 +153,13 @@ asmlinkage long sys_uname(struct new_utsname * name)
        return err ? -EFAULT : 0;
 }
 
-asmlinkage long wrap_sys_shmat(int shmid, char *shmaddr, int shmflg)
+asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg)
 {
        unsigned long raddr;
        return do_shmat(shmid,shmaddr,shmflg,&raddr) ?: (long)raddr;
 }
 
-asmlinkage long sys_time64(long * tloc)
+asmlinkage long sys_time64(long __user * tloc)
 {
        struct timeval now; 
        int i; 
index 70a1700..d82da80 100644 (file)
@@ -302,7 +302,7 @@ void handle_BUG(struct pt_regs *regs)
        if (__get_user(tmp, f.filename))
                f.filename = "unmapped filename"; 
        printk("----------- [cut here ] --------- [please bite here ] ---------\n");
-       printk("Kernel BUG at %.50s:%d\n", f.filename, f.line);         
+       printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", f.filename, f.line);
 } 
 
 void out_of_line_bug(void)
@@ -356,7 +356,7 @@ void __die(const char * str, struct pt_regs * regs, long err)
        notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
        show_registers(regs);
        /* Executive summary in case the oops scrolled away */
-       printk("RIP "); 
+       printk(KERN_ALERT "RIP ");
        printk_address(regs->rip); 
        printk(" RSP <%016lx>\n", regs->rsp); 
 }
index c612e4d..2138354 100644 (file)
@@ -39,6 +39,7 @@ SECTIONS
 
   __bss_start = .;             /* BSS */
   .bss : {
+       *(.bss.page_aligned)    
        *(.bss)
        }
   __bss_end = .;
@@ -75,8 +76,8 @@ SECTIONS
   . = ALIGN(8192);             /* init_task */
   .data.init_task : { *(.data.init_task) }
 
-  . = ALIGN(4096); 
-  .data.boot_pgt : { *(.data.boot_pgt) }
+  . = ALIGN(4096);
+  .data.page_aligned : { *(.data.page_aligned) }
 
   . = ALIGN(4096);             /* Init code and data */
   __init_begin = .;
index a1f892b..2b0d639 100644 (file)
@@ -219,6 +219,3 @@ EXPORT_SYMBOL_GPL(flush_tlb_all);
 #endif
 
 EXPORT_SYMBOL(sys_ioctl);
-
-EXPORT_SYMBOL(memcpy_toio);
-EXPORT_SYMBOL(memcpy_fromio);
index f09cbc3..32b2064 100644 (file)
@@ -4,9 +4,11 @@
 
 CFLAGS_csum-partial.o := -funroll-loops
 
+obj-y := io.o
+
 lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \
        usercopy.o getuser.o putuser.o  \
-       thunk.o io.o clear_page.o copy_page.o bitstr.o
+       thunk.o clear_page.o copy_page.o bitstr.o
 lib-y += memcpy.o memmove.o memset.o copy_user.o
 
 lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
index b89aca4..a8e4c18 100644 (file)
@@ -19,7 +19,7 @@
  * src and dst are best aligned to 64bits. 
  */ 
 unsigned int 
-csum_partial_copy_from_user(const char *src, char *dst, 
+csum_partial_copy_from_user(const char __user *src, char *dst, 
                            int len, unsigned int isum, int *errp)
 { 
        *errp = 0;
@@ -33,7 +33,7 @@ csum_partial_copy_from_user(const char *src, char *dst,
                if (unlikely((unsigned long)src & 6)) {                 
                        while (((unsigned long)src & 6) && len >= 2) { 
                                __u16 val16;                    
-                               *errp = __get_user(val16, (__u16 *)src); 
+                               *errp = __get_user(val16, (__u16 __user *)src); 
                                if (*errp)
                                        return isum;
                                *(__u16 *)dst = val16;
@@ -43,7 +43,7 @@ csum_partial_copy_from_user(const char *src, char *dst,
                                len -= 2;
                        }
                }
-               isum = csum_partial_copy_generic(src,dst,len,isum,errp,NULL);
+               isum = csum_partial_copy_generic((void *)src,dst,len,isum,errp,NULL);
                if (likely(*errp == 0)) 
                        return isum;
        } 
@@ -66,7 +66,7 @@ EXPORT_SYMBOL(csum_partial_copy_from_user);
  * src and dst are best aligned to 64bits.
  */ 
 unsigned int 
-csum_partial_copy_to_user(const char *src, char *dst, 
+csum_partial_copy_to_user(const char *src, char __user *dst, 
                          int len, unsigned int isum, int *errp)
 { 
        if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) {
@@ -78,7 +78,7 @@ csum_partial_copy_to_user(const char *src, char *dst,
                while (((unsigned long)dst & 6) && len >= 2) { 
                        __u16 val16 = *(__u16 *)src;
                        isum = add32_with_carry(isum, val16);
-                       *errp = __put_user(val16, (__u16 *)dst);
+                       *errp = __put_user(val16, (__u16 __user *)dst);
                        if (*errp)
                                return isum;
                        src += 2; 
@@ -88,7 +88,7 @@ csum_partial_copy_to_user(const char *src, char *dst,
        }
 
        *errp = 0;
-       return csum_partial_copy_generic(src,dst,len,isum,NULL,errp); 
+       return csum_partial_copy_generic(src, (void *)dst,len,isum,NULL,errp); 
 } 
 
 EXPORT_SYMBOL(csum_partial_copy_to_user);
index ca08e31..5950b82 100644 (file)
@@ -2,12 +2,14 @@
 #include <asm/io.h>
 #include <linux/module.h>
 
-void *memcpy_toio(void *dst,const void*src,unsigned len)
+void *__memcpy_toio(unsigned long dst,const void*src,unsigned len)
 {
-       return __inline_memcpy(dst,src,len);
+       return __inline_memcpy((void *) dst,src,len);
 }
+EXPORT_SYMBOL(__memcpy_toio);
 
-void *memcpy_fromio(void *dst,const void*src,unsigned len)
+void *__memcpy_fromio(void *dst,unsigned long src,unsigned len)
 {
-       return __inline_memcpy(dst,src,len);
+       return __inline_memcpy(dst,(const void *) src,len);
 }
+EXPORT_SYMBOL(__memcpy_fromio);
index 4a8603e..c83825e 100644 (file)
@@ -40,7 +40,7 @@ do {                                                                     \
 } while (0)
 
 long
-__strncpy_from_user(char *dst, const char *src, long count)
+__strncpy_from_user(char *dst, const char __user *src, long count)
 {
        long res;
        __do_strncpy_from_user(dst, src, count, res);
@@ -48,7 +48,7 @@ __strncpy_from_user(char *dst, const char *src, long count)
 }
 
 long
-strncpy_from_user(char *dst, const char *src, long count)
+strncpy_from_user(char *dst, const char __user *src, long count)
 {
        long res = -EFAULT;
        if (access_ok(VERIFY_READ, src, 1))
@@ -60,7 +60,7 @@ strncpy_from_user(char *dst, const char *src, long count)
  * Zero Userspace
  */
 
-unsigned long __clear_user(void *addr, unsigned long size)
+unsigned long __clear_user(void __user *addr, unsigned long size)
 {
        long __d0;
        /* no memory constraint because it doesn't change any memory gcc knows
@@ -94,7 +94,7 @@ unsigned long __clear_user(void *addr, unsigned long size)
 }
 
 
-unsigned long clear_user(void *to, unsigned long n)
+unsigned long clear_user(void __user *to, unsigned long n)
 {
        if (access_ok(VERIFY_WRITE, to, n))
                return __clear_user(to, n);
@@ -107,7 +107,7 @@ unsigned long clear_user(void *to, unsigned long n)
  * Return 0 on exception, a value greater than N if too long
  */
 
-long strnlen_user(const char *s, long n)
+long strnlen_user(const char __user *s, long n)
 {
        long res = 0;
        char c;
@@ -127,7 +127,7 @@ long strnlen_user(const char *s, long n)
        }
 }
 
-long strlen_user(const char *s)
+long strlen_user(const char __user *s)
 {
        long res = 0;
        char c;
@@ -142,10 +142,10 @@ long strlen_user(const char *s)
        }
 }
 
-unsigned long copy_in_user(void *to, const void *from, unsigned len)
+unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len)
 {
        if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) { 
-               return copy_user_generic(to, from, len);
+               return copy_user_generic((void *)to, (void *)from, len);
        } 
        return len;             
 }
index e5fd0d4..2cdf34b 100644 (file)
@@ -211,7 +211,8 @@ static int is_errata93(struct pt_regs *regs, unsigned long address)
 int unhandled_signal(struct task_struct *tsk, int sig)
 {
        /* Warn for strace, but not for gdb */
-       if ((tsk->ptrace & (PT_PTRACED|PT_TRACESYSGOOD)) == PT_PTRACED)
+       if (!test_ti_thread_flag(tsk->thread_info, TIF_SYSCALL_TRACE) &&
+           (tsk->ptrace & PT_PTRACED))
                return 0;
        return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) ||
                (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL);
@@ -374,7 +375,7 @@ bad_area_nosemaphore:
                    (address >> 32))
                        return;
 
-               if (exception_trace && !unhandled_signal(tsk, SIGSEGV)) { 
+               if (exception_trace && unhandled_signal(tsk, SIGSEGV)) {
                printk(KERN_INFO 
                       "%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
                                        tsk->comm, tsk->pid, address, regs->rip,
@@ -423,8 +424,9 @@ no_context:
                printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
        else
                printk(KERN_ALERT "Unable to handle kernel paging request");
-       printk(" at %016lx RIP: \n",address);   
+       printk(" at %016lx RIP: \n" KERN_ALERT,address);
        printk_address(regs->rip);
+       printk("\n");
        dump_pagetable(address);
        __die("Oops", regs, error_code);
        /* Executive summary in case the body of the oops scrolled away */
index 8026616..186242e 100644 (file)
@@ -512,9 +512,7 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
        /* Should check here against the e820 map to avoid double free */ 
 #ifdef CONFIG_DISCONTIGMEM
        int nid = phys_to_nid(phys);
-       if (phys < HIGH_MEMORY && nid) 
-               panic("reserve of %lx at node %d", phys, nid);
-       reserve_bootmem_node(NODE_DATA(nid), phys, len);
+       reserve_bootmem_node(NODE_DATA(nid), phys, len);
 #else                  
        reserve_bootmem(phys, len);    
 #endif
index 8d1cb38..0cc4a61 100644 (file)
@@ -158,6 +158,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
        area = get_vm_area(size, VM_IOREMAP);
        if (!area)
                return NULL;
+       area->phys_addr = phys_addr;
        addr = area->addr;
        if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
                vunmap(addr);
index e891e9d..598a35c 100644 (file)
@@ -124,7 +124,7 @@ void __init setup_node_zones(int nodeid)
        start_pfn = node_start_pfn(nodeid);
        end_pfn = node_end_pfn(nodeid);
 
-       printk(KERN_INFO "setting up node %d %lx-%lx\n", nodeid, start_pfn, end_pfn); 
+       Dprintk(KERN_INFO "setting up node %d %lx-%lx\n", nodeid, start_pfn, end_pfn);
        
        /* All nodes > 0 have a zero length zone DMA */ 
        dma_end_pfn = __pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT; 
@@ -182,7 +182,7 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
        numnodes = 1;
        for (i = 0; i < NR_CPUS; i++)
                cpu_to_node[i] = 0;
-       node_to_cpumask[0] = 1;
+       node_to_cpumask[0] = cpumask_of_cpu(0);
        setup_node_bootmem(0, start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
 }
 
index 00ced1d..61b73da 100644 (file)
@@ -32,7 +32,8 @@ static inline pte_t *lookup_address(unsigned long address)
        return pte;
 } 
 
-static struct page *split_large_page(unsigned long address, pgprot_t prot)
+static struct page *split_large_page(unsigned long address, pgprot_t prot,
+                                    pgprot_t ref_prot)
 { 
        int i; 
        unsigned long addr;
@@ -45,7 +46,7 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot)
        pbase = (pte_t *)page_address(base);
        for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
                pbase[i] = pfn_pte(addr >> PAGE_SHIFT, 
-                                  addr == address ? prot : PAGE_KERNEL);
+                                  addr == address ? prot : ref_prot);
        }
        return base;
 } 
@@ -95,7 +96,7 @@ static inline void save_page(unsigned long address, struct page *fpage)
  * No more special protections in this 2/4MB area - revert to a
  * large page again. 
  */
-static void revert_page(struct page *kpte_page, unsigned long address)
+static void revert_page(unsigned long address, pgprot_t ref_prot)
 {
        pgd_t *pgd;
        pmd_t *pmd; 
@@ -104,12 +105,14 @@ static void revert_page(struct page *kpte_page, unsigned long address)
        pgd = pgd_offset_k(address); 
        pmd = pmd_offset(pgd, address);
        BUG_ON(pmd_val(*pmd) & _PAGE_PSE); 
-       large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, PAGE_KERNEL_LARGE);
+       pgprot_val(ref_prot) |= _PAGE_PSE;
+       large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot);
        set_pte((pte_t *)pmd, large_pte);
 }      
 
 static int
-__change_page_attr(unsigned long address, struct page *page, pgprot_t prot)
+__change_page_attr(unsigned long address, struct page *page, pgprot_t prot, 
+                  pgprot_t ref_prot)
 { 
        pte_t *kpte; 
        struct page *kpte_page;
@@ -119,29 +122,29 @@ __change_page_attr(unsigned long address, struct page *page, pgprot_t prot)
        if (!kpte) return 0;
        kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
        kpte_flags = pte_val(*kpte); 
-       if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { 
+       if (pgprot_val(prot) != pgprot_val(ref_prot)) { 
                if ((kpte_flags & _PAGE_PSE) == 0) { 
                        pte_t old = *kpte;
-                       pte_t standard = mk_pte(page, PAGE_KERNEL); 
+                       pte_t standard = mk_pte(page, ref_prot); 
 
                        set_pte(kpte, mk_pte(page, prot)); 
                        if (pte_same(old,standard))
                                get_page(kpte_page);
                } else {
-                       struct page *split = split_large_page(address, prot); 
+                       struct page *split = split_large_page(address, prot, ref_prot); 
                        if (!split)
                                return -ENOMEM;
                        get_page(kpte_page);
-                       set_pte(kpte,mk_pte(split, PAGE_KERNEL));
+                       set_pte(kpte,mk_pte(split, ref_prot));
                }       
        } else if ((kpte_flags & _PAGE_PSE) == 0) { 
-               set_pte(kpte, mk_pte(page, PAGE_KERNEL));
+               set_pte(kpte, mk_pte(page, ref_prot));
                __put_page(kpte_page);
        }
 
        if (page_count(kpte_page) == 1) {
                save_page(address, kpte_page);               
-               revert_page(kpte_page, address);
+               revert_page(address, ref_prot);
        } 
        return 0;
 } 
@@ -167,13 +170,17 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot)
        down_write(&init_mm.mmap_sem);
        for (i = 0; i < numpages; !err && i++, page++) { 
                unsigned long address = (unsigned long)page_address(page); 
-               err = __change_page_attr(address, page, prot); 
+               err = __change_page_attr(address, page, prot, PAGE_KERNEL); 
                if (err) 
                        break; 
-               /* Handle kernel mapping too which aliases part of the lowmem */
-               if (page_to_phys(page) < KERNEL_TEXT_SIZE) {            
-                       unsigned long addr2 = __START_KERNEL_map + page_to_phys(page);
-                       err = __change_page_attr(addr2, page, prot);
+               /* Handle kernel mapping too which aliases part of the
+                * lowmem */
+               /* Disabled right now. Fixme */ 
+               if (0 && page_to_phys(page) < KERNEL_TEXT_SIZE) {               
+                       unsigned long addr2;
+                       addr2 = __START_KERNEL_map + page_to_phys(page);
+                       err = __change_page_attr(addr2, page, prot, 
+                                                PAGE_KERNEL_EXEC);
                } 
        }       
        up_write(&init_mm.mmap_sem); 
index 30dabe2..d9b6ac9 100644 (file)
@@ -27,13 +27,28 @@ static void update(struct crypto_tfm *tfm,
                    struct scatterlist *sg, unsigned int nsg)
 {
        unsigned int i;
-       
+
        for (i = 0; i < nsg; i++) {
-               char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
-               tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm),
-                                                     p, sg[i].length);
-               crypto_kunmap(p, 0);
-               crypto_yield(tfm);
+
+               struct page *pg = sg[i].page;
+               unsigned int offset = sg[i].offset;
+               unsigned int l = sg[i].length;
+
+               do {
+                       unsigned int bytes_from_page = min(l, ((unsigned int)
+                                                          (PAGE_SIZE)) - 
+                                                          offset);
+                       char *p = crypto_kmap(pg, 0) + offset;
+
+                       tfm->__crt_alg->cra_digest.dia_update
+                                       (crypto_tfm_ctx(tfm), p,
+                                        bytes_from_page);
+                       crypto_kunmap(p, 0);
+                       crypto_yield(tfm);
+                       offset = 0;
+                       pg++;
+                       l -= bytes_from_page;
+               } while (l > 0);
        }
 }
 
index 1a537e0..a742764 100644 (file)
@@ -267,7 +267,7 @@ config X86_PM_TIMER
          (TSC) timing source.
 
          So, if you see messages like 'Losing too many ticks!' in the
-         kernel logs, and/or you are using this on a notebook which
+         kernel logs, and/or you are using this on a notebook which
          does not yet have an HPET, you should say "Y" here.
 
 endmenu
index 8e73079..23e9945 100644 (file)
 #include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/acpi.h>
-#ifdef CONFIG_X86_IO_APIC
-#include <asm/mpspec.h>
-#endif
-#ifdef CONFIG_IOSAPIC
-# include <asm/iosapic.h>
-#endif
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -50,10 +44,6 @@ ACPI_MODULE_NAME             ("pci_irq")
 
 struct acpi_prt_list           acpi_prt;
 
-#ifdef CONFIG_X86
-extern void eisa_set_level_irq(unsigned int irq);
-#endif
-
 
 /* --------------------------------------------------------------------------
                          PCI IRQ Routing Table (PRT) Support
@@ -237,12 +227,18 @@ acpi_pci_irq_add_prt (
                           PCI Interrupt Routing Support
    -------------------------------------------------------------------------- */
 
-int
-acpi_pci_irq_lookup (struct pci_bus *bus, int device, int pin)
+static int
+acpi_pci_irq_lookup (
+       struct pci_bus          *bus,
+       int                     device,
+       int                     pin,
+       int                     *edge_level,
+       int                     *active_high_low)
 {
        struct acpi_prt_entry   *entry = NULL;
        int segment = pci_domain_nr(bus);
        int bus_nr = bus->number;
+       int irq;
 
        ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup");
 
@@ -255,28 +251,30 @@ acpi_pci_irq_lookup (struct pci_bus *bus, int device, int pin)
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n"));
                return_VALUE(0);
        }
-
-       if (!entry->irq && entry->link.handle) {
-               entry->irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, NULL, NULL);
-               if (!entry->irq) {
+       
+       if (entry->link.handle) {
+               irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, edge_level, active_high_low);
+               if (!irq) {
                        ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
                        return_VALUE(0);
                }
-       }
-       else if (!entry->irq) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid static routing entry (IRQ 0)\n"));
-               return_VALUE(0);
+       } else {
+               irq = entry->link.index;
+               *edge_level = ACPI_LEVEL_SENSITIVE;
+               *active_high_low = ACPI_ACTIVE_LOW;
        }
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", entry->irq));
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
 
-       return_VALUE(entry->irq);
+       return_VALUE(irq);
 }
 
 static int
 acpi_pci_irq_derive (
        struct pci_dev          *dev,
-       int                     pin)
+       int                     pin,
+       int                     *edge_level,
+       int                     *active_high_low)
 {
        struct pci_dev          *bridge = dev;
        int                     irq = 0;
@@ -308,8 +306,8 @@ acpi_pci_irq_derive (
                        pin = bridge_pin;
                }
 
-               irq = acpi_pci_irq_lookup(bridge->bus,
-                               PCI_SLOT(bridge->devfn), pin);
+               irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn),
+                       pin, edge_level, active_high_low);
        }
 
        if (!irq) {
@@ -330,6 +328,8 @@ acpi_pci_irq_enable (
 {
        int                     irq = 0;
        u8                      pin = 0;
+       int                     edge_level = ACPI_LEVEL_SENSITIVE;
+       int                     active_high_low = ACPI_ACTIVE_LOW;
 
        ACPI_FUNCTION_TRACE("acpi_pci_irq_enable");
 
@@ -352,21 +352,22 @@ acpi_pci_irq_enable (
         * First we check the PCI IRQ routing table (PRT) for an IRQ.  PRT
         * values override any BIOS-assigned IRQs set during boot.
         */
-       irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin);
+       irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, &edge_level, &active_high_low);
 
        /*
         * If no PRT entry was found, we'll try to derive an IRQ from the
         * device's parent bridge.
         */
        if (!irq)
-               irq = acpi_pci_irq_derive(dev, pin);
+               irq = acpi_pci_irq_derive(dev, pin, &edge_level, &active_high_low);
  
        /*
         * No IRQ known to the ACPI subsystem - maybe the BIOS / 
         * driver reported one, then use it. Exit in any case.
         */
        if (!irq) {
-               printk(KERN_WARNING PREFIX "No IRQ known for interrupt pin %c of device %s", ('A' + pin), pci_name(dev));
+               printk(KERN_WARNING PREFIX "PCI interrupt %s[%c]: no GSI",
+                       pci_name(dev), ('A' + pin));
                /* Interrupt Line values above 0xF are forbidden */
                if (dev->irq && (dev->irq <= 0xF)) {
                        printk(" - using IRQ %d\n", dev->irq);
@@ -378,62 +379,14 @@ acpi_pci_irq_enable (
                }
        }
 
-       dev->irq = irq;
+       dev->irq = acpi_register_gsi(irq, edge_level, active_high_low);
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s using IRQ %d\n", pci_name(dev), dev->irq));
-
-       /* 
-        * Make sure all (legacy) PCI IRQs are set as level-triggered.
-        */
-#ifdef CONFIG_X86
-       {
-               static u16 irq_mask;
-               if ((dev->irq < 16) &&  !((1 << dev->irq) & irq_mask)) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Setting IRQ %d as level-triggered\n", dev->irq));
-                       irq_mask |= (1 << dev->irq);
-                       eisa_set_level_irq(dev->irq);
-               }
-       }
-#endif
-#ifdef CONFIG_IOSAPIC
-       if (acpi_irq_model == ACPI_IRQ_MODEL_IOSAPIC)
-               iosapic_enable_intr(dev->irq);
-#endif
+       printk(KERN_INFO PREFIX "PCI interrupt %s[%c] -> GSI %u "
+               "(%s, %s) -> IRQ %d\n",
+               pci_name(dev), 'A' + pin, irq,
+               (edge_level == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
+               (active_high_low == ACPI_ACTIVE_LOW) ? "low" : "high",
+               dev->irq);
 
        return_VALUE(dev->irq);
 }
-
-
-int __init
-acpi_pci_irq_init (void)
-{
-       struct pci_dev          *dev = NULL;
-
-       ACPI_FUNCTION_TRACE("acpi_pci_irq_init");
-
-       if (!acpi_prt.count) {
-               printk(KERN_WARNING PREFIX "ACPI tables contain no PCI IRQ "
-                       "routing entries\n");
-               return_VALUE(-ENODEV);
-       }
-
-       /* Make sure all link devices have a valid IRQ. */
-       if (acpi_pci_link_check()) {
-               return_VALUE(-ENODEV);
-       }
-
-#ifdef CONFIG_X86_IO_APIC
-       /* Program IOAPICs using data from PRT entries. */
-       if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
-               mp_parse_prt();
-#endif
-#ifdef CONFIG_IOSAPIC
-       if (acpi_irq_model == ACPI_IRQ_MODEL_IOSAPIC)
-               iosapic_parse_prt();
-#endif
-
-       while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
-               acpi_pci_irq_enable(dev);
-
-       return_VALUE(0);
-}
index 8940e11..13e9225 100644 (file)
@@ -308,31 +308,12 @@ acpi_pci_link_set (
                struct acpi_resource    end;
        }                       resource;
        struct acpi_buffer      buffer = {sizeof(resource)+1, &resource};
-       int                     i = 0;
-       int                     valid = 0;
 
        ACPI_FUNCTION_TRACE("acpi_pci_link_set");
 
        if (!link || !irq)
                return_VALUE(-EINVAL);
 
-       /* We don't check irqs the first time around */
-       if (link->irq.setonboot) {
-               /* See if we're already at the target IRQ. */
-               if (irq == link->irq.active)
-                       return_VALUE(0);
-
-               /* Make sure the target IRQ in the list of possible IRQs. */
-               for (i=0; i<link->irq.possible_count; i++) {
-                       if (irq == link->irq.possible[i])
-                               valid = 1;
-               }
-               if (!valid) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Target IRQ %d invalid\n", irq));
-                       return_VALUE(-EINVAL);
-               }
-       }
-
        memset(&resource, 0, sizeof(resource));
 
        switch(link->irq.resource_type) {
@@ -487,13 +468,13 @@ static int __initdata acpi_irq_penalty[ACPI_MAX_IRQS] = {
 };
 
 int
-acpi_pci_link_check (void)
+acpi_irq_penalty_init(void)
 {
        struct list_head        *node = NULL;
        struct acpi_pci_link    *link = NULL;
        int                     i = 0;
 
-       ACPI_FUNCTION_TRACE("acpi_pci_link_check");
+       ACPI_FUNCTION_TRACE("acpi_irq_penalty_init");
 
        /*
         * Update penalties to facilitate IRQ balancing.
@@ -703,6 +684,9 @@ acpi_pci_link_add (
        acpi_link.count++;
 
 end:
+       /* disable all links -- to be activated on use */
+       acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL);
+
        if (result)
                kfree(link);
 
index 3d19331..dd08b63 100644 (file)
@@ -113,6 +113,40 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
        }
 }
 
+static acpi_status
+get_root_bridge_busnr_callback (struct acpi_resource *resource, void *data)
+{
+       int *busnr = (int *)data;
+       struct acpi_resource_address64 address;
+
+       if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
+           resource->id != ACPI_RSTYPE_ADDRESS32 &&
+           resource->id != ACPI_RSTYPE_ADDRESS64)
+               return AE_OK;
+
+       acpi_resource_to_address64(resource, &address);
+       if ((address.address_length > 0) && 
+          (address.resource_type == ACPI_BUS_NUMBER_RANGE))
+               *busnr = address.min_address_range;
+
+       return AE_OK;
+}
+
+static acpi_status 
+try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
+{
+       acpi_status status;
+
+       *busnum = -1;
+       status = acpi_walk_resources(handle, METHOD_NAME__CRS, get_root_bridge_busnr_callback, busnum);
+       if (ACPI_FAILURE(status))
+               return status;
+       /* Check if we really get a bus number from _CRS */
+       if (*busnum == -1)
+               return AE_ERROR;
+       return AE_OK;
+}
+
 static int
 acpi_pci_root_add (
        struct acpi_device      *device)
@@ -190,9 +224,22 @@ acpi_pci_root_add (
        /* Some systems have wrong _BBN */
        list_for_each_entry(tmp, &acpi_pci_roots, node) {
                if ((tmp->id.segment == root->id.segment)
-                               && (tmp->id.bus == root->id.bus))
+                               && (tmp->id.bus == root->id.bus)) {
+                       int bus = 0;
+                       acpi_status status;
+
                        ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
                                "Wrong _BBN value, please reboot and using option 'pci=noacpi'\n"));
+
+                       status = try_get_root_bridge_busnr(root->handle, &bus);
+                       if (ACPI_FAILURE(status))
+                               break;
+                       if (bus != root->id.bus) {
+                               printk(KERN_INFO PREFIX "PCI _CRS %d overrides _BBN 0\n", bus);
+                               root->id.bus = bus;
+                       }
+                       break;
+               }
        }
        /*
         * Device & Function
index d87764e..a1844bc 100644 (file)
@@ -131,7 +131,7 @@ acpi_table_print_madt_entry (
        {
                struct acpi_table_ioapic *p =
                        (struct acpi_table_ioapic*) header;
-               printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] global_irq_base[0x%x])\n",
+               printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n",
                        p->id, p->address, p->global_irq_base);
        }
                break;
@@ -185,8 +185,8 @@ acpi_table_print_madt_entry (
        {
                struct acpi_table_iosapic *p =
                        (struct acpi_table_iosapic*) header;
-               printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] global_irq_base[0x%x] address[%p])\n",
-                       p->id, p->global_irq_base, (void *) (unsigned long) p->address);
+               printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n",
+                       p->id, (void *) (unsigned long) p->address, p->global_irq_base);
        }
                break;
 
index 00c8059..7b94ac0 100644 (file)
@@ -289,6 +289,13 @@ acpi_thermal_set_cooling_mode (
        status = acpi_get_handle(tz->handle, "_SCP", &handle);
        if (ACPI_FAILURE(status)) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n"));
+               status = acpi_get_handle(tz->handle, "_PSV", &handle);
+               if(!ACPI_FAILURE(status)) {
+                       tz->cooling_mode = 1;
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n", 
+                               mode?"passive":"active"));
+                       return_VALUE(0);
+               }
                return_VALUE(-ENODEV);
        }
 
index b293bb7..c26a12e 100644 (file)
@@ -1706,105 +1706,108 @@ static void destroy_queues (amb_dev * dev) {
 }
 
 /********** basic loader commands and error handling **********/
+// centisecond timeouts - guessing away here
+static unsigned int command_timeouts [] = {
+       [host_memory_test]     = 15,
+       [read_adapter_memory]  = 2,
+       [write_adapter_memory] = 2,
+       [adapter_start]        = 50,
+       [get_version_number]   = 10,
+       [interrupt_host]       = 1,
+       [flash_erase_sector]   = 1,
+       [adap_download_block]  = 1,
+       [adap_erase_flash]     = 1,
+       [adap_run_in_iram]     = 1,
+       [adap_end_download]    = 1
+};
+
+
+unsigned int command_successes [] = {
+       [host_memory_test]     = COMMAND_PASSED_TEST,
+       [read_adapter_memory]  = COMMAND_READ_DATA_OK,
+       [write_adapter_memory] = COMMAND_WRITE_DATA_OK,
+       [adapter_start]        = COMMAND_COMPLETE,
+       [get_version_number]   = COMMAND_COMPLETE,
+       [interrupt_host]       = COMMAND_COMPLETE,
+       [flash_erase_sector]   = COMMAND_COMPLETE,
+       [adap_download_block]  = COMMAND_COMPLETE,
+       [adap_erase_flash]     = COMMAND_COMPLETE,
+       [adap_run_in_iram]     = COMMAND_COMPLETE,
+       [adap_end_download]    = COMMAND_COMPLETE
+};
+  
+static  int decode_loader_result (loader_command cmd, u32 result)
+{
+       int res;
+       const char *msg;
+
+       if (result == command_successes[cmd])
+               return 0;
+
+       switch (result) {
+               case BAD_COMMAND:
+                       res = -EINVAL;
+                       msg = "bad command";
+                       break;
+               case COMMAND_IN_PROGRESS:
+                       res = -ETIMEDOUT;
+                       msg = "command in progress";
+                       break;
+               case COMMAND_PASSED_TEST:
+                       res = 0;
+                       msg = "command passed test";
+                       break;
+               case COMMAND_FAILED_TEST:
+                       res = -EIO;
+                       msg = "command failed test";
+                       break;
+               case COMMAND_READ_DATA_OK:
+                       res = 0;
+                       msg = "command read data ok";
+                       break;
+               case COMMAND_READ_BAD_ADDRESS:
+                       res = -EINVAL;
+                       msg = "command read bad address";
+                       break;
+               case COMMAND_WRITE_DATA_OK:
+                       res = 0;
+                       msg = "command write data ok";
+                       break;
+               case COMMAND_WRITE_BAD_ADDRESS:
+                       res = -EINVAL;
+                       msg = "command write bad address";
+                       break;
+               case COMMAND_WRITE_FLASH_FAILURE:
+                       res = -EIO;
+                       msg = "command write flash failure";
+                       break;
+               case COMMAND_COMPLETE:
+                       res = 0;
+                       msg = "command complete";
+                       break;
+               case COMMAND_FLASH_ERASE_FAILURE:
+                       res = -EIO;
+                       msg = "command flash erase failure";
+                       break;
+               case COMMAND_WRITE_BAD_DATA:
+                       res = -EINVAL;
+                       msg = "command write bad data";
+                       break;
+               default:
+                       res = -EINVAL;
+                       msg = "unknown error";
+                       PRINTD (DBG_LOAD|DBG_ERR,
+                               "decode_loader_result got %d=%x !",
+                               result, result);
+                       break;
+       }
+
+       PRINTK (KERN_ERR, "%s", msg);
+       return res;
+}
 
 static int __init do_loader_command (volatile loader_block * lb,
                                     const amb_dev * dev, loader_command cmd) {
-  // centisecond timeouts - guessing away here
-  unsigned int command_timeouts [] = {
-    [host_memory_test]     = 15,
-    [read_adapter_memory]  = 2,
-    [write_adapter_memory] = 2,
-    [adapter_start]        = 50,
-    [get_version_number]   = 10,
-    [interrupt_host]       = 1,
-    [flash_erase_sector]   = 1,
-    [adap_download_block]  = 1,
-    [adap_erase_flash]     = 1,
-    [adap_run_in_iram]     = 1,
-    [adap_end_download]    = 1
-  };
-  
-  unsigned int command_successes [] = {
-    [host_memory_test]     = COMMAND_PASSED_TEST,
-    [read_adapter_memory]  = COMMAND_READ_DATA_OK,
-    [write_adapter_memory] = COMMAND_WRITE_DATA_OK,
-    [adapter_start]        = COMMAND_COMPLETE,
-    [get_version_number]   = COMMAND_COMPLETE,
-    [interrupt_host]       = COMMAND_COMPLETE,
-    [flash_erase_sector]   = COMMAND_COMPLETE,
-    [adap_download_block]  = COMMAND_COMPLETE,
-    [adap_erase_flash]     = COMMAND_COMPLETE,
-    [adap_run_in_iram]     = COMMAND_COMPLETE,
-    [adap_end_download]    = COMMAND_COMPLETE
-  };
-  
-  int decode_loader_result (loader_command cmd, u32 result) {
-    int res;
-    const char * msg;
-    
-    if (result == command_successes[cmd])
-      return 0;
-    
-    switch (result) {
-      case BAD_COMMAND:
-       res = -EINVAL;
-       msg = "bad command";
-       break;
-      case COMMAND_IN_PROGRESS:
-       res = -ETIMEDOUT;
-       msg = "command in progress";
-       break;
-      case COMMAND_PASSED_TEST:
-       res = 0;
-       msg = "command passed test";
-       break;
-      case COMMAND_FAILED_TEST:
-       res = -EIO;
-       msg = "command failed test";
-       break;
-      case COMMAND_READ_DATA_OK:
-       res = 0;
-       msg = "command read data ok";
-       break;
-      case COMMAND_READ_BAD_ADDRESS:
-       res = -EINVAL;
-       msg = "command read bad address";
-       break;
-      case COMMAND_WRITE_DATA_OK:
-       res = 0;
-       msg = "command write data ok";
-       break;
-      case COMMAND_WRITE_BAD_ADDRESS:
-       res = -EINVAL;
-       msg = "command write bad address";
-       break;
-      case COMMAND_WRITE_FLASH_FAILURE:
-       res = -EIO;
-       msg = "command write flash failure";
-       break;
-      case COMMAND_COMPLETE:
-       res = 0;
-       msg = "command complete";
-       break;
-      case COMMAND_FLASH_ERASE_FAILURE:
-       res = -EIO;
-       msg = "command flash erase failure";
-       break;
-      case COMMAND_WRITE_BAD_DATA:
-       res = -EINVAL;
-       msg = "command write bad data";
-       break;
-      default:
-       res = -EINVAL;
-       msg = "unknown error";
-       PRINTD (DBG_LOAD|DBG_ERR, "decode_loader_result got %d=%x !",
-               result, result);
-       break;
-    }
-    
-    PRINTK (KERN_ERR, "%s", msg);
-    return res;
-  }
   
   unsigned long timeout;
   
@@ -1930,6 +1933,11 @@ static int __init loader_start (loader_block * lb,
 
 /********** reset card **********/
 
+static inline void sf (const char * msg)
+{
+       PRINTK (KERN_ERR, "self-test failed: %s", msg);
+}
+
 static int amb_reset (amb_dev * dev, int diags) {
   u32 word;
   
@@ -1974,9 +1982,6 @@ static int amb_reset (amb_dev * dev, int diags) {
     // XXX double check byte-order
     word = rd_mem (dev, offsetof(amb_mem, mb.loader.result));
     if (word & SELF_TEST_FAILURE) {
-      void sf (const char * msg) {
-       PRINTK (KERN_ERR, "self-test failed: %s", msg);
-      }
       if (word & GPINT_TST_FAILURE)
        sf ("interrupt");
       if (word & SUNI_DATA_PATTERN_FAILURE)
@@ -2044,31 +2049,31 @@ static int __init ucode_init (loader_block * lb, amb_dev * dev) {
 }
 
 /********** give adapter parameters **********/
+  
+static inline u32 bus_addr(void * addr) {
+    return cpu_to_be32 (virt_to_bus (addr));
+}
 
 static int __init amb_talk (amb_dev * dev) {
   adap_talk_block a;
   unsigned char pool;
   unsigned long timeout;
   
-  u32 x (void * addr) {
-    return cpu_to_be32 (virt_to_bus (addr));
-  }
-  
   PRINTD (DBG_FLOW, "amb_talk %p", dev);
   
-  a.command_start = x (dev->cq.ptrs.start);
-  a.command_end   = x (dev->cq.ptrs.limit);
-  a.tx_start      = x (dev->txq.in.start);
-  a.tx_end        = x (dev->txq.in.limit);
-  a.txcom_start   = x (dev->txq.out.start);
-  a.txcom_end     = x (dev->txq.out.limit);
+  a.command_start = bus_addr (dev->cq.ptrs.start);
+  a.command_end   = bus_addr (dev->cq.ptrs.limit);
+  a.tx_start      = bus_addr (dev->txq.in.start);
+  a.tx_end        = bus_addr (dev->txq.in.limit);
+  a.txcom_start   = bus_addr (dev->txq.out.start);
+  a.txcom_end     = bus_addr (dev->txq.out.limit);
   
   for (pool = 0; pool < NUM_RX_POOLS; ++pool) {
     // the other "a" items are set up by the adapter
-    a.rec_struct[pool].buffer_start = x (dev->rxq[pool].in.start);
-    a.rec_struct[pool].buffer_end   = x (dev->rxq[pool].in.limit);
-    a.rec_struct[pool].rx_start     = x (dev->rxq[pool].out.start);
-    a.rec_struct[pool].rx_end       = x (dev->rxq[pool].out.limit);
+    a.rec_struct[pool].buffer_start = bus_addr (dev->rxq[pool].in.start);
+    a.rec_struct[pool].buffer_end   = bus_addr (dev->rxq[pool].in.limit);
+    a.rec_struct[pool].rx_start     = bus_addr (dev->rxq[pool].out.start);
+    a.rec_struct[pool].rx_end       = bus_addr (dev->rxq[pool].out.limit);
     a.rec_struct[pool].buffer_size = cpu_to_be32 (dev->rxq[pool].buffer_size);
   }
   
@@ -2111,15 +2116,10 @@ static void __init amb_ucode_version (amb_dev * dev) {
   minor = be32_to_cpu (cmd.args.version.minor);
   PRINTK (KERN_INFO, "microcode version is %u.%u", major, minor);
 }
-
-// get end station address
-static void __init amb_esi (amb_dev * dev, u8 * esi) {
-  u32 lower4;
-  u16 upper2;
-  command cmd;
   
-  // swap bits within byte to get Ethernet ordering
-  u8 bit_swap (u8 byte) {
+// swap bits within byte to get Ethernet ordering
+u8 bit_swap (u8 byte)
+{
     const u8 swap[] = {
       0x0, 0x8, 0x4, 0xc,
       0x2, 0xa, 0x6, 0xe,
@@ -2127,7 +2127,13 @@ static void __init amb_esi (amb_dev * dev, u8 * esi) {
       0x3, 0xb, 0x7, 0xf
     };
     return ((swap[byte & 0xf]<<4) | swap[byte>>4]);
-  }
+}
+
+// get end station address
+static void __init amb_esi (amb_dev * dev, u8 * esi) {
+  u32 lower4;
+  u16 upper2;
+  command cmd;
   
   cmd.request = cpu_to_be32 (SRB_GET_BIA);
   while (command_do (dev, &cmd)) {
@@ -2155,29 +2161,31 @@ static void __init amb_esi (amb_dev * dev, u8 * esi) {
   
   return;
 }
+  
+static void fixup_plx_window (amb_dev *dev, loader_block *lb)
+{
+       // fix up the PLX-mapped window base address to match the block
+       unsigned long blb;
+       u32 mapreg;
+       blb = virt_to_bus(lb);
+       // the kernel stack had better not ever cross a 1Gb boundary!
+       mapreg = rd_plain (dev, offsetof(amb_mem, stuff[10]));
+       mapreg &= ~onegigmask;
+       mapreg |= blb & onegigmask;
+       wr_plain (dev, offsetof(amb_mem, stuff[10]), mapreg);
+       return;
+}
 
-static int __init amb_init (amb_dev * dev) {
+static int __init amb_init (amb_dev * dev)
+{
   loader_block lb;
   
-  void fixup_plx_window (void) {
-    // fix up the PLX-mapped window base address to match the block
-    unsigned long blb;
-    u32 mapreg;
-    blb = virt_to_bus (&lb);
-    // the kernel stack had better not ever cross a 1Gb boundary!
-    mapreg = rd_plain (dev, offsetof(amb_mem, stuff[10]));
-    mapreg &= ~onegigmask;
-    mapreg |= blb & onegigmask;
-    wr_plain (dev, offsetof(amb_mem, stuff[10]), mapreg);
-    return;
-  }
-  
   u32 version;
   
   if (amb_reset (dev, 1)) {
     PRINTK (KERN_ERR, "card reset failed!");
   } else {
-    fixup_plx_window ();
+    fixup_plx_window (dev, &lb);
     
     if (get_loader_version (&lb, dev, &version)) {
       PRINTK (KERN_INFO, "failed to get loader version");
@@ -2207,31 +2215,20 @@ static int __init amb_init (amb_dev * dev) {
     
   } /* amb_reset */
   
-  return -1;
+  return -EINVAL;
 }
 
-static int __init amb_probe (void) {
-  struct pci_dev * pci_dev;
-  int devs;
-  
-  void __init do_pci_device (void) {
-    amb_dev * dev;
-    
-    // read resources from PCI configuration space
-    u8 irq = pci_dev->irq;
-    u32 * membase = bus_to_virt (pci_resource_start (pci_dev, 0));
-    u32 iobase = pci_resource_start (pci_dev, 1);
-    
-    void setup_dev (void) {
+static void setup_dev(amb_dev *dev, struct pci_dev *pci_dev) 
+{
       unsigned char pool;
       memset (dev, 0, sizeof(amb_dev));
       
       // set up known dev items straight away
       dev->pci_dev = pci_dev; 
       
-      dev->iobase = iobase;
-      dev->irq = irq; 
-      dev->membase = membase;
+      dev->iobase = pci_resource_start (pci_dev, 1);
+      dev->irq = pci_dev->irq; 
+      dev->membase = bus_to_virt(pci_resource_start(pci_dev, 0));
       
       // flags (currently only dead)
       dev->flags = 0;
@@ -2258,101 +2255,125 @@ static int __init amb_probe (void) {
       spin_lock_init (&dev->txq.lock);
       for (pool = 0; pool < NUM_RX_POOLS; ++pool)
        spin_lock_init (&dev->rxq[pool].lock);
-    }
-    
-    void setup_pci_dev (void) {
-      unsigned char lat;
-      
-      /* XXX check return value */
-      pci_enable_device (pci_dev);
+}
 
-      // enable bus master accesses
-      pci_set_master (pci_dev);
-      
-      // frobnicate latency (upwards, usually)
-      pci_read_config_byte (pci_dev, PCI_LATENCY_TIMER, &lat);
-      if (pci_lat) {
-       PRINTD (DBG_INIT, "%s PCI latency timer from %hu to %hu",
-               "changing", lat, pci_lat);
-       pci_write_config_byte (pci_dev, PCI_LATENCY_TIMER, pci_lat);
-      } else if (lat < MIN_PCI_LATENCY) {
-       PRINTK (KERN_INFO, "%s PCI latency timer from %hu to %hu",
-               "increasing", lat, MIN_PCI_LATENCY);
-       pci_write_config_byte (pci_dev, PCI_LATENCY_TIMER, MIN_PCI_LATENCY);
-      }
-    }
-    
-    PRINTD (DBG_INFO, "found Madge ATM adapter (amb) at"
-           " IO %x, IRQ %u, MEM %p", iobase, irq, membase);
-    
-    // check IO region
-    if (!request_region (iobase, AMB_EXTENT, DEV_LABEL)) {
-      PRINTK (KERN_ERR, "IO range already in use!");
-      return;
-    }
-    
-    dev = kmalloc (sizeof(amb_dev), GFP_KERNEL);
-    if (!dev) {
-      // perhaps we should be nice: deregister all adapters and abort?
-      PRINTK (KERN_ERR, "out of memory!");
-      release_region (iobase, AMB_EXTENT);
-      return;
-    }
-    
-    setup_dev();
-    
-    if (amb_init (dev)) {
-      PRINTK (KERN_ERR, "adapter initialisation failure");
-    } else {
+static int setup_pci_dev(struct pci_dev *pci_dev)
+{
+       unsigned char lat;
+       int ret;
       
-      setup_pci_dev();
+       // enable bus master accesses
+       pci_set_master(pci_dev);
       
-      // grab (but share) IRQ and install handler
-      if (request_irq (irq, interrupt_handler, SA_SHIRQ, DEV_LABEL, dev)) {
-       PRINTK (KERN_ERR, "request IRQ failed!");
-       // free_irq is at "endif"
-      } else {
-       
+       ret = pci_enable_device(pci_dev);
+       if (ret < 0)
+               goto out;
+
+       // frobnicate latency (upwards, usually)
+       pci_read_config_byte (pci_dev, PCI_LATENCY_TIMER, &lat);
+
+       if (!pci_lat)
+               pci_lat = (lat < MIN_PCI_LATENCY) ? MIN_PCI_LATENCY : lat;
+
+       if (lat != pci_lat) {
+               PRINTK (KERN_INFO, "Changing PCI latency timer from %hu to %hu",
+                       lat, pci_lat);
+               pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, pci_lat);
+       }
+out:
+       return ret;
+}
+
+static int __init do_pci_device(struct pci_dev *pci_dev)
+{
+       amb_dev * dev;
+       int err;
+
+       // read resources from PCI configuration space
+       u8 irq = pci_dev->irq;
+       u32 * membase = bus_to_virt (pci_resource_start (pci_dev, 0));
+       u32 iobase = pci_resource_start (pci_dev, 1);
+
+       PRINTD (DBG_INFO, "found Madge ATM adapter (amb) at"
+               " IO %x, IRQ %u, MEM %p", iobase, irq, membase);
+
+       // check IO region
+       err = pci_request_region(pci_dev, 1, DEV_LABEL);
+       if (err < 0) {
+               PRINTK (KERN_ERR, "IO range already in use!");
+               goto out;
+       }
+
+       dev = kmalloc (sizeof(amb_dev), GFP_KERNEL);
+       if (!dev) {
+               PRINTK (KERN_ERR, "out of memory!");
+               err = -ENOMEM;
+               goto out_release;
+       }
+
+       setup_dev(dev, pci_dev);
+
+       err = amb_init(dev);
+       if (err < 0) {
+               PRINTK (KERN_ERR, "adapter initialisation failure");
+               goto out_free;
+       }
+
+       err = setup_pci_dev(pci_dev);
+       if (err < 0)
+               goto out_reset;
+
+       // grab (but share) IRQ and install handler
+       err = request_irq(irq, interrupt_handler, SA_SHIRQ, DEV_LABEL, dev);
+       if (err < 0) {
+               PRINTK (KERN_ERR, "request IRQ failed!");
+               goto out_disable;
+       }
+
        dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL);
        if (!dev->atm_dev) {
-         PRINTD (DBG_ERR, "failed to register Madge ATM adapter");
-       } else {
-         
-         PRINTD (DBG_INFO, "registered Madge ATM adapter (no. %d) (%p) at %p",
-                 dev->atm_dev->number, dev, dev->atm_dev);
-         dev->atm_dev->dev_data = (void *) dev;
-         
-         // register our address
-         amb_esi (dev, dev->atm_dev->esi);
-         
-         // 0 bits for vpi, 10 bits for vci
-         dev->atm_dev->ci_range.vpi_bits = NUM_VPI_BITS;
-         dev->atm_dev->ci_range.vci_bits = NUM_VCI_BITS;
-         
-         // update count and linked list
-         ++devs;
-         dev->prev = amb_devs;
-         amb_devs = dev;
-         
-         // enable host interrupts
-         interrupts_on (dev);
-         
-         // success
-         return;
-         
-         // not currently reached
-         atm_dev_deregister (dev->atm_dev);
-       } /* atm_dev_register */
-       
-       free_irq (irq, dev);
-      } /* request_irq */
-      
-      amb_reset (dev, 0);
-    } /* amb_init */
-    
-    kfree (dev);
-    release_region (iobase, AMB_EXTENT);
-  } /* kmalloc, end-of-fn */
+               PRINTD (DBG_ERR, "failed to register Madge ATM adapter");
+               err = -EINVAL;
+               goto out_free_irq;
+       }
+
+       PRINTD (DBG_INFO, "registered Madge ATM adapter (no. %d) (%p) at %p",
+               dev->atm_dev->number, dev, dev->atm_dev);
+               dev->atm_dev->dev_data = (void *) dev;
+
+       // register our address
+       amb_esi (dev, dev->atm_dev->esi);
+
+       // 0 bits for vpi, 10 bits for vci
+       dev->atm_dev->ci_range.vpi_bits = NUM_VPI_BITS;
+       dev->atm_dev->ci_range.vci_bits = NUM_VCI_BITS;
+
+       // update linked list
+       dev->prev = amb_devs;
+       amb_devs = dev;
+
+       // enable host interrupts
+       interrupts_on (dev);
+
+out:
+       return err;
+
+out_free_irq:
+       free_irq(irq, dev);
+out_disable:
+       pci_disable_device(pci_dev);
+out_reset:
+       amb_reset(dev, 0);
+out_free:
+       kfree(dev);
+out_release:
+       pci_release_region(pci_dev, 1);
+       goto out;
+}
+
+static int __init amb_probe (void) {
+  struct pci_dev * pci_dev;
+  int devs;
   
   PRINTD (DBG_FLOW, "amb_probe");
   
@@ -2360,8 +2381,11 @@ static int __init amb_probe (void) {
   pci_dev = NULL;
   while ((pci_dev = pci_find_device
           (PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR, pci_dev)
-          ))
-    do_pci_device();
+          )) {
+       if (do_pci_device(pci_dev) == 0)
+               devs++;
+  }
+
   
   pci_dev = NULL;
   while ((pci_dev = pci_find_device
@@ -2474,7 +2498,10 @@ static void __exit amb_module_exit (void) {
   del_timer_sync(&housekeeping);
   
   while (amb_devs) {
+    struct pci_dev *pdev;
+
     dev = amb_devs;
+    pdev = dev->pci_dev;
     amb_devs = dev->prev;
     
     PRINTD (DBG_INFO|DBG_INIT, "closing %p (atm_dev = %p)", dev, dev->atm_dev);
@@ -2482,11 +2509,12 @@ static void __exit amb_module_exit (void) {
     drain_rx_pools (dev);
     interrupts_off (dev);
     amb_reset (dev, 0);
+    free_irq (dev->irq, dev);
+    pci_disable_device (pdev);
     destroy_queues (dev);
     atm_dev_deregister (dev->atm_dev);
-    free_irq (dev->irq, dev);
-    release_region (dev->iobase, AMB_EXTENT);
     kfree (dev);
+    pci_release_region (pdev, 1);
   }
   
   return;
index aa1cbe3..0572f72 100644 (file)
@@ -152,7 +152,7 @@ static void atmtcp_v_close(struct atm_vcc *vcc)
 }
 
 
-static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
 {
        struct atm_cirange ci;
        struct atm_vcc *vcc;
@@ -161,7 +161,7 @@ static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
        int i;
 
        if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD;
-       if (copy_from_user(&ci,(void *) arg,sizeof(ci))) return -EFAULT;
+       if (copy_from_user(&ci, arg,sizeof(ci))) return -EFAULT;
        if (ci.vpi_bits == ATM_CI_MAX) ci.vpi_bits = MAX_VPI_BITS;
        if (ci.vci_bits == ATM_CI_MAX) ci.vci_bits = MAX_VCI_BITS;
        if (ci.vpi_bits > MAX_VPI_BITS || ci.vpi_bits < 0 ||
index b760589..8b13703 100644 (file)
@@ -1968,7 +1968,7 @@ static int eni_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flgs)
 }
 
 
-static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
 {
        struct eni_dev *eni_dev = ENI_DEV(dev);
 
@@ -1983,7 +1983,7 @@ static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
                struct eni_multipliers mult;
 
                if (!capable(CAP_NET_ADMIN)) return -EPERM;
-               if (copy_from_user(&mult,(void *) arg,
+               if (copy_from_user(&mult, arg,
                    sizeof(struct eni_multipliers)))
                        return -EFAULT;
                if ((mult.tx && mult.tx <= 100) || (mult.rx &&mult.rx <= 100) ||
@@ -1996,7 +1996,7 @@ static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
        if (cmd == ATM_SETCIRANGE) {
                struct atm_cirange ci;
 
-               if (copy_from_user(&ci,(void *) arg,sizeof(struct atm_cirange)))
+               if (copy_from_user(&ci, arg,sizeof(struct atm_cirange)))
                        return -EFAULT;
                if ((ci.vpi_bits == 0 || ci.vpi_bits == ATM_CI_MAX) &&
                    (ci.vci_bits == NR_VCI_LD || ci.vpi_bits == ATM_CI_MAX))
@@ -2009,14 +2009,14 @@ static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
 
 
 static int eni_getsockopt(struct atm_vcc *vcc,int level,int optname,
-    void *optval,int optlen)
+    void __user *optval,int optlen)
 {
        return -EINVAL;
 }
 
 
 static int eni_setsockopt(struct atm_vcc *vcc,int level,int optname,
-    void *optval,int optlen)
+    void __user *optval,int optlen)
 {
        return -EINVAL;
 }
index f45adbb..025c692 100644 (file)
@@ -1220,7 +1220,7 @@ static int fs_send (struct atm_vcc *atm_vcc, struct sk_buff *skb)
 /* Some function placeholders for functions we don't yet support. */
 
 #if 0
-static int fs_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int fs_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
 {
        func_enter ();
        func_exit ();
@@ -1229,7 +1229,7 @@ static int fs_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
 
 
 static int fs_getsockopt(struct atm_vcc *vcc,int level,int optname,
-                        void *optval,int optlen)
+                        void __user *optval,int optlen)
 {
        func_enter ();
        func_exit ();
@@ -1238,7 +1238,7 @@ static int fs_getsockopt(struct atm_vcc *vcc,int level,int optname,
 
 
 static int fs_setsockopt(struct atm_vcc *vcc,int level,int optname,
-                        void *optval,int optlen)
+                        void __user *optval,int optlen)
 {
        func_enter ();
        func_exit ();
index e46d01b..e33b535 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/atmdev.h>
 #include <linux/sonet.h>
 #include <linux/atm_suni.h>
+#include <linux/dma-mapping.h>
 #include <asm/io.h>
 #include <asm/string.h>
 #include <asm/page.h>
@@ -682,7 +683,7 @@ fore200e_pca_prom_read(struct fore200e* fore200e, struct prom_data* prom)
     opcode.opcode = OPCODE_GET_PROM;
     opcode.pad    = 0;
 
-    prom_dma = fore200e->bus->dma_map(fore200e, prom, sizeof(struct prom_data), FORE200E_DMA_FROMDEVICE);
+    prom_dma = fore200e->bus->dma_map(fore200e, prom, sizeof(struct prom_data), DMA_FROM_DEVICE);
 
     fore200e->bus->write(prom_dma, &entry->cp_entry->cmd.prom_block.prom_haddr);
     
@@ -694,7 +695,7 @@ fore200e_pca_prom_read(struct fore200e* fore200e, struct prom_data* prom)
 
     *entry->status = STATUS_FREE;
 
-    fore200e->bus->dma_unmap(fore200e, prom_dma, sizeof(struct prom_data), FORE200E_DMA_FROMDEVICE);
+    fore200e->bus->dma_unmap(fore200e, prom_dma, sizeof(struct prom_data), DMA_FROM_DEVICE);
 
     if (ok == 0) {
        printk(FORE200E "unable to get PROM data from device %s\n", fore200e->name);
@@ -1003,7 +1004,7 @@ fore200e_tx_irq(struct fore200e* fore200e)
        
        /* remove DMA mapping */
        fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length,
-                                FORE200E_DMA_TODEVICE);
+                                DMA_TO_DEVICE);
 
        vc_map = entry->vc_map;
 
@@ -1228,12 +1229,12 @@ fore200e_push_rpd(struct fore200e* fore200e, struct atm_vcc* vcc, struct rpd* rp
        buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
        
        /* Make device DMA transfer visible to CPU.  */
-       fore200e->bus->dma_sync_for_cpu(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, FORE200E_DMA_FROMDEVICE);
+       fore200e->bus->dma_sync_for_cpu(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, DMA_FROM_DEVICE);
        
        memcpy(skb_put(skb, rpd->rsd[ i ].length), buffer->data.align_addr, rpd->rsd[ i ].length);
 
        /* Now let the device get at it again.  */
-       fore200e->bus->dma_sync_for_device(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, FORE200E_DMA_FROMDEVICE);
+       fore200e->bus->dma_sync_for_device(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, DMA_FROM_DEVICE);
     }
 
     DPRINTK(3, "rx skb: len = %d, truesize = %d\n", skb->len, skb->truesize);
@@ -1807,7 +1808,7 @@ fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb)
     entry->data   = tx_copy ? data : NULL;
 
     tpd = entry->tpd;
-    tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, data, tx_len, FORE200E_DMA_TODEVICE);
+    tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, data, tx_len, DMA_TO_DEVICE);
     tpd->tsd[ 0 ].length = tx_len;
 
     FORE200E_NEXT_ENTRY(txq->head, QUEUE_SIZE_TX);
@@ -1881,7 +1882,7 @@ fore200e_getstats(struct fore200e* fore200e)
     }
     
     stats_dma_addr = fore200e->bus->dma_map(fore200e, fore200e->stats,
-                                           sizeof(struct stats), FORE200E_DMA_FROMDEVICE);
+                                           sizeof(struct stats), DMA_FROM_DEVICE);
     
     FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
 
@@ -1898,7 +1899,7 @@ fore200e_getstats(struct fore200e* fore200e)
 
     *entry->status = STATUS_FREE;
 
-    fore200e->bus->dma_unmap(fore200e, stats_dma_addr, sizeof(struct stats), FORE200E_DMA_FROMDEVICE);
+    fore200e->bus->dma_unmap(fore200e, stats_dma_addr, sizeof(struct stats), DMA_FROM_DEVICE);
     
     if (ok == 0) {
        printk(FORE200E "unable to get statistics from device %s\n", fore200e->name);
@@ -1910,7 +1911,7 @@ fore200e_getstats(struct fore200e* fore200e)
 
 
 static int
-fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, voidoptval, int optlen)
+fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
 {
     /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
 
@@ -1922,7 +1923,7 @@ fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void* optval, i
 
 
 static int
-fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, voidoptval, int optlen)
+fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
 {
     /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
     
@@ -1943,7 +1944,7 @@ fore200e_get_oc3(struct fore200e* fore200e, struct oc3_regs* regs)
     int                     ok;
     u32                     oc3_regs_dma_addr;
 
-    oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs), FORE200E_DMA_FROMDEVICE);
+    oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
 
     FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
 
@@ -1962,7 +1963,7 @@ fore200e_get_oc3(struct fore200e* fore200e, struct oc3_regs* regs)
 
     *entry->status = STATUS_FREE;
 
-    fore200e->bus->dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs), FORE200E_DMA_FROMDEVICE);
+    fore200e->bus->dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
     
     if (ok == 0) {
        printk(FORE200E "unable to get OC-3 regs of device %s\n", fore200e->name);
@@ -2058,7 +2059,7 @@ fore200e_swap(unsigned int in)
 
 
 static int
-fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_statsarg)
+fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats __user *arg)
 {
     struct sonet_stats tmp;
 
@@ -2087,7 +2088,7 @@ fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats* arg)
 
 
 static int
-fore200e_ioctl(struct atm_dev* dev, unsigned int cmd, void* arg)
+fore200e_ioctl(struct atm_dev* dev, unsigned int cmd, void __user * arg)
 {
     struct fore200e* fore200e = FORE200E_DEV(dev);
     
@@ -2096,19 +2097,19 @@ fore200e_ioctl(struct atm_dev* dev, unsigned int cmd, void* arg)
     switch (cmd) {
 
     case SONET_GETSTAT:
-       return fore200e_fetch_stats(fore200e, (struct sonet_stats*)arg);
+       return fore200e_fetch_stats(fore200e, (struct sonet_stats __user *)arg);
 
     case SONET_GETDIAG:
-       return put_user(0, (int*)arg) ? -EFAULT : 0;
+       return put_user(0, (int __user *)arg) ? -EFAULT : 0;
 
     case ATM_SETLOOP:
        return fore200e_setloop(fore200e, (int)(unsigned long)arg);
 
     case ATM_GETLOOP:
-       return put_user(fore200e->loop_mode, (int*)arg) ? -EFAULT : 0;
+       return put_user(fore200e->loop_mode, (int __user *)arg) ? -EFAULT : 0;
 
     case ATM_QUERYLOOP:
-       return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY, (int*)arg) ? -EFAULT : 0;
+       return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY, (int __user *)arg) ? -EFAULT : 0;
     }
 
     return -ENOSYS; /* not implemented */
@@ -2257,7 +2258,7 @@ fore200e_alloc_rx_buf(struct fore200e* fore200e)
                /* allocate the receive buffer body */
                if (fore200e_chunk_alloc(fore200e,
                                         &buffer[ i ].data, size, fore200e->bus->buffer_alignment,
-                                        FORE200E_DMA_FROMDEVICE) < 0) {
+                                        DMA_FROM_DEVICE) < 0) {
                    
                    while (i > 0)
                        fore200e_chunk_free(fore200e, &buffer[ --i ].data);
index 6a9d2ee..aca550b 100644 (file)
@@ -556,7 +556,7 @@ typedef struct host_bsq_entry {
 
 typedef struct host_cmdq_entry {
     struct cp_cmdq_entry* cp_entry;    /* addr of cp resident cmd queue entry */
-    enum   status*        status;      /* addr of host resident status        */
+    enum status *status;              /* addr of host resident status        */
 } host_cmdq_entry_t;
 
 
@@ -668,7 +668,7 @@ typedef struct bs_spec {
 
 typedef struct init_block {
     enum opcode  opcode;               /* initialize command             */
-    enum status  status;              /* related status word            */
+    enum status         status;               /* related status word            */
     u32          receive_threshold;    /* not used                       */
     u32          num_connect;          /* ATM connections                */
     u32          cmd_queue_len;        /* length of command queue        */
@@ -827,28 +827,6 @@ typedef struct fore200e_bus {
     int                  (*proc_read)(struct fore200e*, char*);
 } fore200e_bus_t;
 
-
-#if defined(CONFIG_ATM_FORE200E_SBA)
-#  if defined(CONFIG_ATM_FORE200E_PCA)
-#    define FORE200E_DMA_BIDIRECTIONAL PCI_DMA_BIDIRECTIONAL
-#    define FORE200E_DMA_TODEVICE      PCI_DMA_TODEVICE
-#    define FORE200E_DMA_FROMDEVICE    PCI_DMA_FROMDEVICE
-#  else
-#    define FORE200E_DMA_BIDIRECTIONAL SBUS_DMA_BIDIRECTIONAL
-#    define FORE200E_DMA_TODEVICE      SBUS_DMA_TODEVICE
-#    define FORE200E_DMA_FROMDEVICE    SBUS_DMA_FROMDEVICE
-#  endif
-#else
-#  ifndef CONFIG_ATM_FORE200E_PCA
-#    warning compiling the fore200e driver without any hardware support enabled!
-#    include <linux/pci.h>
-#  endif
-#  define FORE200E_DMA_BIDIRECTIONAL PCI_DMA_BIDIRECTIONAL
-#  define FORE200E_DMA_TODEVICE      PCI_DMA_TODEVICE
-#  define FORE200E_DMA_FROMDEVICE    PCI_DMA_FROMDEVICE
-#endif
-
-
 /* vc mapping */
 
 typedef struct fore200e_vc_map {
index 72123ec..ad746d9 100644 (file)
@@ -134,7 +134,7 @@ static char *version = "$Id: he.c,v 1.18 2003/05/06 22:57:15 chas Exp $";
 static int he_open(struct atm_vcc *vcc);
 static void he_close(struct atm_vcc *vcc);
 static int he_send(struct atm_vcc *vcc, struct sk_buff *skb);
-static int he_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg);
+static int he_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg);
 static irqreturn_t he_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
 static void he_tasklet(unsigned long data);
 static int he_proc_read(struct atm_dev *dev,loff_t *pos,char *page);
@@ -2809,7 +2809,7 @@ he_send(struct atm_vcc *vcc, struct sk_buff *skb)
 }
 
 static int
-he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void *arg)
+he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void __user *arg)
 {
        unsigned long flags;
        struct he_dev *he_dev = HE_DEV(atm_dev);
@@ -2821,8 +2821,8 @@ he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void *arg)
                        if (!capable(CAP_NET_ADMIN))
                                return -EPERM;
 
-                       if (copy_from_user(&reg, (struct he_ioctl_reg *) arg,
-                                               sizeof(struct he_ioctl_reg)))
+                       if (copy_from_user(&reg, arg,
+                                          sizeof(struct he_ioctl_reg)))
                                return -EFAULT;
                        
                        spin_lock_irqsave(&he_dev->global_lock, flags);
@@ -2848,7 +2848,7 @@ he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void *arg)
                        }
                        spin_unlock_irqrestore(&he_dev->global_lock, flags);
                        if (err == 0)
-                               if (copy_to_user((struct he_ioctl_reg *) arg, &reg,
+                               if (copy_to_user(arg, &reg,
                                                        sizeof(struct he_ioctl_reg)))
                                        return -EFAULT;
                        break;
index 90e407a..a794610 100644 (file)
@@ -597,126 +597,112 @@ static inline u16 rx_q_entry_to_rx_channel (u32 x) {
 
 // p ranges from 1 to a power of 2
 #define CR_MAXPEXP 4
-
 static int make_rate (const hrz_dev * dev, u32 c, rounding r,
-                     u16 * bits, unsigned int * actual) {
-  
-  // note: rounding the rate down means rounding 'p' up
-  
-  const unsigned long br = test_bit(ultra, &dev->flags) ? BR_ULT : BR_HRZ;
-  
-  u32 div = CR_MIND;
-  u32 pre;
+                     u16 * bits, unsigned int * actual)
+{
+       // note: rounding the rate down means rounding 'p' up
+       const unsigned long br = test_bit(ultra, &dev->flags) ? BR_ULT : BR_HRZ;
   
-  // local fn to build the timer bits
-  int set_cr (void) {
-    // paranoia
-    if (div > CR_MAXD || (!pre) || pre > 1<<CR_MAXPEXP) {
-      PRINTD (DBG_QOS, "set_cr internal failure: d=%u p=%u",
-             div, pre);
-      return -EINVAL;
-    } else {
-      if (bits)
-       *bits = (div<<CLOCK_SELECT_SHIFT) | (pre-1);
-      if (actual) {
-       *actual = (br + (pre<<div) - 1) / (pre<<div);
-       PRINTD (DBG_QOS, "actual rate: %u", *actual);
-      }
-      return 0;
-    }
-  }
+       u32 div = CR_MIND;
+       u32 pre;
   
-  // br_exp and br_man are used to avoid overflowing (c*maxp*2^d) in
-  // the tests below. We could think harder about exact possibilities
-  // of failure...
+       // br_exp and br_man are used to avoid overflowing (c*maxp*2^d) in
+       // the tests below. We could think harder about exact possibilities
+       // of failure...
   
-  unsigned long br_man = br;
-  unsigned int br_exp = 0;
+       unsigned long br_man = br;
+       unsigned int br_exp = 0;
   
-  PRINTD (DBG_QOS|DBG_FLOW, "make_rate b=%lu, c=%u, %s", br, c,
-         (r == round_up) ? "up" : (r == round_down) ? "down" : "nearest");
+       PRINTD (DBG_QOS|DBG_FLOW, "make_rate b=%lu, c=%u, %s", br, c,
+               r == round_up ? "up" : r == round_down ? "down" : "nearest");
   
-  // avoid div by zero
-  if (!c) {
-    PRINTD (DBG_QOS|DBG_ERR, "zero rate is not allowed!");
-    return -EINVAL;
-  }
+       // avoid div by zero
+       if (!c) {
+               PRINTD (DBG_QOS|DBG_ERR, "zero rate is not allowed!");
+               return -EINVAL;
+       }
   
-  while (br_exp < CR_MAXPEXP + CR_MIND && (br_man % 2 == 0)) {
-    br_man = br_man >> 1;
-    ++br_exp;
-  }
-  // (br >>br_exp) <<br_exp == br and
-  // br_exp <= CR_MAXPEXP+CR_MIND
+       while (br_exp < CR_MAXPEXP + CR_MIND && (br_man % 2 == 0)) {
+               br_man = br_man >> 1;
+               ++br_exp;
+       }
+       // (br >>br_exp) <<br_exp == br and
+       // br_exp <= CR_MAXPEXP+CR_MIND
+  
+       if (br_man <= (c << (CR_MAXPEXP+CR_MIND-br_exp))) {
+               // Equivalent to: B <= (c << (MAXPEXP+MIND))
+               // take care of rounding
+               switch (r) {
+                       case round_down:
+                               pre = (br+(c<<div)-1)/(c<<div);
+                               // but p must be non-zero
+                               if (!pre)
+                                       pre = 1;
+                               break;
+                       case round_nearest:
+                               pre = (br+(c<<div)/2)/(c<<div);
+                               // but p must be non-zero
+                               if (!pre)
+                                       pre = 1;
+                               break;
+                       default:        /* round_up */
+                               pre = br/(c<<div);
+                               // but p must be non-zero
+                               if (!pre)
+                                       return -EINVAL;
+               }
+               PRINTD (DBG_QOS, "A: p=%u, d=%u", pre, div);
+               goto got_it;
+       }
   
-  if (br_man <= (c << (CR_MAXPEXP+CR_MIND-br_exp))) {
-    // Equivalent to: B <= (c << (MAXPEXP+MIND))
-    // take care of rounding
-    switch (r) {
-      case round_down:
-       pre = (br+(c<<div)-1)/(c<<div);
-       // but p must be non-zero
-       if (!pre)
-         pre = 1;
-       break;
-      case round_nearest:
-       pre = (br+(c<<div)/2)/(c<<div);
-       // but p must be non-zero
-       if (!pre)
-         pre = 1;
-       break;
-      case round_up:
-       pre = br/(c<<div);
-       // but p must be non-zero
-       if (!pre)
-         return -EINVAL;
-       break;
-    }
-    PRINTD (DBG_QOS, "A: p=%u, d=%u", pre, div);
-    return set_cr ();
-  }
-  
-  // at this point we have
-  // d == MIND and (c << (MAXPEXP+MIND)) < B
-  while (div < CR_MAXD) {
-    div++;
-    if (br_man <= (c << (CR_MAXPEXP+div-br_exp))) {
-      // Equivalent to: B <= (c << (MAXPEXP+d))
-      // c << (MAXPEXP+d-1) < B <= c << (MAXPEXP+d)
-      // 1 << (MAXPEXP-1) < B/2^d/c <= 1 << MAXPEXP
-      // MAXP/2 < B/c2^d <= MAXP
-      // take care of rounding
-      switch (r) {
-       case round_down:
-         pre = (br+(c<<div)-1)/(c<<div);
-         break;
-       case round_nearest:
-         pre = (br+(c<<div)/2)/(c<<div);
-         break;
-       case round_up:
-         pre = br/(c<<div);
-         break;
-      }
-      PRINTD (DBG_QOS, "B: p=%u, d=%u", pre, div);
-      return set_cr ();
-    }
-  }
-  // at this point we have
-  // d == MAXD and (c << (MAXPEXP+MAXD)) < B
-  // but we cannot go any higher
-  // take care of rounding
-  switch (r) {
-    case round_down:
-      return -EINVAL;
-      break;
-    case round_nearest:
-      break;
-    case round_up:
-      break;
-  }
-  pre = 1 << CR_MAXPEXP;
-  PRINTD (DBG_QOS, "C: p=%u, d=%u", pre, div);
-  return set_cr ();
+       // at this point we have
+       // d == MIND and (c << (MAXPEXP+MIND)) < B
+       while (div < CR_MAXD) {
+               div++;
+               if (br_man <= (c << (CR_MAXPEXP+div-br_exp))) {
+                       // Equivalent to: B <= (c << (MAXPEXP+d))
+                       // c << (MAXPEXP+d-1) < B <= c << (MAXPEXP+d)
+                       // 1 << (MAXPEXP-1) < B/2^d/c <= 1 << MAXPEXP
+                       // MAXP/2 < B/c2^d <= MAXP
+                       // take care of rounding
+                       switch (r) {
+                               case round_down:
+                                       pre = (br+(c<<div)-1)/(c<<div);
+                                       break;
+                               case round_nearest:
+                                       pre = (br+(c<<div)/2)/(c<<div);
+                                       break;
+                               default: /* round_up */
+                                       pre = br/(c<<div);
+                       }
+                       PRINTD (DBG_QOS, "B: p=%u, d=%u", pre, div);
+                       goto got_it;
+               }
+       }
+       // at this point we have
+       // d == MAXD and (c << (MAXPEXP+MAXD)) < B
+       // but we cannot go any higher
+       // take care of rounding
+       if (r == round_down)
+               return -EINVAL;
+       pre = 1 << CR_MAXPEXP;
+       PRINTD (DBG_QOS, "C: p=%u, d=%u", pre, div);
+got_it:
+       // paranoia
+       if (div > CR_MAXD || (!pre) || pre > 1<<CR_MAXPEXP) {
+               PRINTD (DBG_QOS, "set_cr internal failure: d=%u p=%u",
+                       div, pre);
+               return -EINVAL;
+       } else {
+               if (bits)
+                       *bits = (div<<CLOCK_SELECT_SHIFT) | (pre-1);
+               if (actual) {
+                       *actual = (br + (pre<<div) - 1) / (pre<<div);
+                       PRINTD (DBG_QOS, "actual rate: %u", *actual);
+               }
+               return 0;
+       }
 }
 
 static int make_rate_with_tolerance (const hrz_dev * dev, u32 c, rounding r, unsigned int tol,
@@ -1823,23 +1809,23 @@ static void hrz_reset (const hrz_dev * dev) {
 
 /********** read the burnt in address **********/
 
-static u16 __init read_bia (const hrz_dev * dev, u16 addr) {
+static inline void WRITE_IT_WAIT (const hrz_dev *dev, u32 ctrl)
+{
+       wr_regl (dev, CONTROL_0_REG, ctrl);
+       udelay (5);
+}
   
+static inline void CLOCK_IT (const hrz_dev *dev, u32 ctrl)
+{
+       // DI must be valid around rising SK edge
+       WRITE_IT_WAIT(dev, ctrl & ~SEEPROM_SK);
+       WRITE_IT_WAIT(dev, ctrl | SEEPROM_SK);
+}
+
+static u16 __init read_bia (const hrz_dev * dev, u16 addr)
+{
   u32 ctrl = rd_regl (dev, CONTROL_0_REG);
   
-  void WRITE_IT_WAIT (void) {
-    wr_regl (dev, CONTROL_0_REG, ctrl);
-    udelay (5);
-  }
-  
-  void CLOCK_IT (void) {
-    // DI must be valid around rising SK edge
-    ctrl &= ~SEEPROM_SK;
-    WRITE_IT_WAIT();
-    ctrl |= SEEPROM_SK;
-    WRITE_IT_WAIT();
-  }
-  
   const unsigned int addr_bits = 6;
   const unsigned int data_bits = 16;
   
@@ -1848,17 +1834,17 @@ static u16 __init read_bia (const hrz_dev * dev, u16 addr) {
   u16 res;
   
   ctrl &= ~(SEEPROM_CS | SEEPROM_SK | SEEPROM_DI);
-  WRITE_IT_WAIT();
+  WRITE_IT_WAIT(dev, ctrl);
   
   // wake Serial EEPROM and send 110 (READ) command
   ctrl |=  (SEEPROM_CS | SEEPROM_DI);
-  CLOCK_IT();
+  CLOCK_IT(dev, ctrl);
   
   ctrl |= SEEPROM_DI;
-  CLOCK_IT();
+  CLOCK_IT(dev, ctrl);
   
   ctrl &= ~SEEPROM_DI;
-  CLOCK_IT();
+  CLOCK_IT(dev, ctrl);
   
   for (i=0; i<addr_bits; i++) {
     if (addr & (1 << (addr_bits-1)))
@@ -1866,7 +1852,7 @@ static u16 __init read_bia (const hrz_dev * dev, u16 addr) {
     else
       ctrl &= ~SEEPROM_DI;
     
-    CLOCK_IT();
+    CLOCK_IT(dev, ctrl);
     
     addr = addr << 1;
   }
@@ -1878,14 +1864,14 @@ static u16 __init read_bia (const hrz_dev * dev, u16 addr) {
   for (i=0;i<data_bits;i++) {
     res = res >> 1;
     
-    CLOCK_IT();
+    CLOCK_IT(dev, ctrl);
     
     if (rd_regl (dev, CONTROL_0_REG) & SEEPROM_DO)
       res |= (1 << (data_bits-1));
   }
   
   ctrl &= ~(SEEPROM_SK | SEEPROM_CS);
-  WRITE_IT_WAIT();
+  WRITE_IT_WAIT(dev, ctrl);
   
   return res;
 }
index c95ca29..c1fb6c7 100644 (file)
@@ -141,7 +141,7 @@ static void idt77105_restart_timer_func(unsigned long dummy)
 }
 
 
-static int fetch_stats(struct atm_dev *dev,struct idt77105_stats *arg,int zero)
+static int fetch_stats(struct atm_dev *dev,struct idt77105_stats __user *arg,int zero)
 {
        unsigned long flags;
        struct idt77105_stats stats;
@@ -188,7 +188,7 @@ static int set_loopback(struct atm_dev *dev,int mode)
 }
 
 
-static int idt77105_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int idt77105_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
 {
         printk(KERN_NOTICE "%s(%d) idt77105_ioctl() called\n",dev->type,dev->number);
        switch (cmd) {
@@ -196,16 +196,15 @@ static int idt77105_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
                        if (!capable(CAP_NET_ADMIN)) return -EPERM;
                        /* fall through */
                case IDT77105_GETSTAT:
-                       return fetch_stats(dev,(struct idt77105_stats *) arg,
-                           cmd == IDT77105_GETSTATZ);
+                       return fetch_stats(dev, arg, cmd == IDT77105_GETSTATZ);
                case ATM_SETLOOP:
                        return set_loopback(dev,(int) (long) arg);
                case ATM_GETLOOP:
-                       return put_user(PRIV(dev)->loop_mode,(int *) arg) ?
+                       return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
                            -EFAULT : 0;
                case ATM_QUERYLOOP:
                        return put_user(ATM_LM_LOC_ATM | ATM_LM_RMT_ATM,
-                           (int *) arg) ? -EFAULT : 0;
+                           (int __user *) arg) ? -EFAULT : 0;
                default:
                        return -ENOIOCTLCMD;
        }
index 2b6b9c6..3c964ec 100644 (file)
@@ -2738,12 +2738,12 @@ static int ia_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags)
        return 0;  
 }  
   
-static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg)  
+static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)  
 {  
    IA_CMDBUF ia_cmds;
    IADEV *iadev;
    int i, board;
-   u16 *tmps;
+   u16 __user *tmps;
    IF_EVENT(printk(">ia_ioctl\n");)  
    if (cmd != IA_CMD) {
       if (!dev->phy->ioctl) return -EINVAL;
@@ -2766,7 +2766,7 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg)
              break;
           case MEMDUMP_SEGREG:
             if (!capable(CAP_NET_ADMIN)) return -EPERM;
-             tmps = (u16 *)ia_cmds.buf;
+             tmps = (u16 __user *)ia_cmds.buf;
              for(i=0; i<0x80; i+=2, tmps++)
                 if(put_user((u16)(readl(iadev->seg_reg+i) & 0xffff), tmps)) return -EFAULT;
              ia_cmds.status = 0;
@@ -2774,7 +2774,7 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg)
              break;
           case MEMDUMP_REASSREG:
             if (!capable(CAP_NET_ADMIN)) return -EPERM;
-             tmps = (u16 *)ia_cmds.buf;
+             tmps = (u16 __user *)ia_cmds.buf;
              for(i=0; i<0x80; i+=2, tmps++)
                 if(put_user((u16)(readl(iadev->reass_reg+i) & 0xffff), tmps)) return -EFAULT;
              ia_cmds.status = 0;
@@ -2874,14 +2874,14 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg)
 }  
   
 static int ia_getsockopt(struct atm_vcc *vcc, int level, int optname,   
-       void *optval, int optlen)  
+       void __user *optval, int optlen)  
 {  
        IF_EVENT(printk(">ia_getsockopt\n");)  
        return -EINVAL;  
 }  
   
 static int ia_setsockopt(struct atm_vcc *vcc, int level, int optname,   
-       void *optval, int optlen)  
+       void __user *optval, int optlen)  
 {  
        IF_EVENT(printk(">ia_setsockopt\n");)  
        return -EINVAL;  
index 1134bda..92e514c 100644 (file)
@@ -141,7 +141,7 @@ typedef struct {
         int len;
         u32 maddr;
         int status;
-        void *buf;
+        void __user *buf;
 } IA_CMDBUF, *PIA_CMDBUF;
 
 /* cmds */
index 5a7037a..ac80b9e 100644 (file)
@@ -2435,7 +2435,7 @@ static int lanai_open(struct atm_vcc *atmvcc)
 #if 0
 /* ioctl operations for card */
 /* NOTE: these are all DEBUGGING ONLY currently */
-static int lanai_ioctl(struct atm_dev *atmdev, unsigned int cmd, void *arg)
+static int lanai_ioctl(struct atm_dev *atmdev, unsigned int cmd, void __user *arg)
 {
        int result = 0;
        struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
index 11875f7..b63669c 100644 (file)
@@ -239,7 +239,7 @@ static void recycle_iov_buf(ns_dev *card, struct sk_buff *iovb);
 static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb);
 static void dequeue_lg_buf(ns_dev *card, struct sk_buff *lb);
 static int ns_proc_read(struct atm_dev *dev, loff_t *pos, char *page);
-static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg);
+static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg);
 static void which_list(ns_dev *card, struct sk_buff *skb);
 static void ns_poll(unsigned long arg);
 static int ns_parse_mac(char *mac, unsigned char *esi);
@@ -2765,7 +2765,7 @@ static int ns_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
 
 
 
-static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg)
+static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
 {
    ns_dev *card;
    pool_levels pl;
@@ -2776,7 +2776,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg)
    switch (cmd)
    {
       case NS_GETPSTAT:
-         if (get_user(pl.buftype, &((pool_levels *) arg)->buftype))
+         if (get_user(pl.buftype, &((pool_levels __user *) arg)->buftype))
            return -EFAULT;
          switch (pl.buftype)
         {
@@ -2812,7 +2812,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg)
               return -ENOIOCTLCMD;
 
         }
-         if (!copy_to_user((pool_levels *) arg, &pl, sizeof(pl)))
+         if (!copy_to_user((pool_levels __user *) arg, &pl, sizeof(pl)))
            return (sizeof(pl));
         else
            return -EFAULT;
@@ -2820,7 +2820,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg)
       case NS_SETBUFLEV:
          if (!capable(CAP_NET_ADMIN))
            return -EPERM;
-         if (copy_from_user(&pl, (pool_levels *) arg, sizeof(pl)))
+         if (copy_from_user(&pl, (pool_levels __user *) arg, sizeof(pl)))
            return -EFAULT;
         if (pl.level.min >= pl.level.init || pl.level.init >= pl.level.max)
            return -EINVAL;
index e245e94..e5a0f5c 100644 (file)
@@ -95,7 +95,7 @@ static void suni_hz(unsigned long from_timer)
 #undef ADD_LIMITED
 
 
-static int fetch_stats(struct atm_dev *dev,struct sonet_stats *arg,int zero)
+static int fetch_stats(struct atm_dev *dev,struct sonet_stats __user *arg,int zero)
 {
        struct sonet_stats tmp;
        int error = 0;
@@ -115,11 +115,11 @@ static int fetch_stats(struct atm_dev *dev,struct sonet_stats *arg,int zero)
   }
 
 
-static int change_diag(struct atm_dev *dev,void *arg,int set)
+static int change_diag(struct atm_dev *dev,void __user *arg,int set)
 {
        int todo;
 
-       if (get_user(todo,(int *) arg)) return -EFAULT;
+       if (get_user(todo,(int __user *)arg)) return -EFAULT;
        HANDLE_FLAG(SONET_INS_SBIP,TSOP_DIAG,SUNI_TSOP_DIAG_DBIP8);
        HANDLE_FLAG(SONET_INS_LBIP,TLOP_DIAG,SUNI_TLOP_DIAG_DBIP);
        HANDLE_FLAG(SONET_INS_PBIP,TPOP_CD,SUNI_TPOP_DIAG_DB3);
@@ -128,14 +128,14 @@ static int change_diag(struct atm_dev *dev,void *arg,int set)
        HANDLE_FLAG(SONET_INS_PAIS,TPOP_CD,SUNI_TPOP_DIAG_PAIS);
        HANDLE_FLAG(SONET_INS_LOS,TSOP_DIAG,SUNI_TSOP_DIAG_DLOS);
        HANDLE_FLAG(SONET_INS_HCS,TACP_CS,SUNI_TACP_CS_DHCS);
-       return put_user(todo,(int *) arg) ? -EFAULT : 0;
+       return put_user(todo,(int __user *)arg) ? -EFAULT : 0;
 }
 
 
 #undef HANDLE_FLAG
 
 
-static int get_diag(struct atm_dev *dev,void *arg)
+static int get_diag(struct atm_dev *dev,void __user *arg)
 {
        int set;
 
@@ -148,7 +148,7 @@ static int get_diag(struct atm_dev *dev,void *arg)
        if (GET(TPOP_CD) & SUNI_TPOP_DIAG_PAIS) set |= SONET_INS_PAIS;
        if (GET(TSOP_DIAG) & SUNI_TSOP_DIAG_DLOS) set |= SONET_INS_LOS;
        if (GET(TACP_CS) & SUNI_TACP_CS_DHCS) set |= SONET_INS_HCS;
-       return put_user(set,(int *) arg) ? -EFAULT : 0;
+       return put_user(set,(int __user *)arg) ? -EFAULT : 0;
 }
 
 
@@ -175,13 +175,12 @@ static int set_loopback(struct atm_dev *dev,int mode)
 }
 
 
-static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
 {
        switch (cmd) {
                case SONET_GETSTATZ:
                case SONET_GETSTAT:
-                       return fetch_stats(dev,(struct sonet_stats *) arg,
-                           cmd == SONET_GETSTATZ);
+                       return fetch_stats(dev, arg, cmd == SONET_GETSTATZ);
                case SONET_SETDIAG:
                        return change_diag(dev,arg,1);
                case SONET_CLRDIAG:
@@ -192,18 +191,18 @@ static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
                        if (arg != SONET_FRAME_SONET) return -EINVAL;
                        return 0;
                case SONET_GETFRAMING:
-                       return put_user(SONET_FRAME_SONET,(int *) arg) ?
+                       return put_user(SONET_FRAME_SONET,(int __user *)arg) ?
                            -EFAULT : 0;
                case SONET_GETFRSENSE:
                        return -EINVAL;
                case ATM_SETLOOP:
                        return set_loopback(dev,(int) (long) arg);
                case ATM_GETLOOP:
-                       return put_user(PRIV(dev)->loop_mode,(int *) arg) ?
+                       return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
                            -EFAULT : 0;
                case ATM_QUERYLOOP:
                        return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY,
-                           (int *) arg) ? -EFAULT : 0;
+                           (int __user *) arg) ? -EFAULT : 0;
                default:
                        return -ENOIOCTLCMD;
        }
index 0bc05c9..da33ead 100644 (file)
@@ -37,7 +37,7 @@ struct uPD98402_priv {
 #define GET(reg) dev->ops->phy_get(dev,uPD98402_##reg)
 
 
-static int fetch_stats(struct atm_dev *dev,struct sonet_stats *arg,int zero)
+static int fetch_stats(struct atm_dev *dev,struct sonet_stats __user *arg,int zero)
 {
        struct sonet_stats tmp;
        int error = 0;
@@ -83,7 +83,7 @@ static int set_framing(struct atm_dev *dev,unsigned char framing)
 }
 
 
-static int get_sense(struct atm_dev *dev,u8 *arg)
+static int get_sense(struct atm_dev *dev,u8 __user *arg)
 {
        unsigned long flags;
        unsigned char s[3];
@@ -132,29 +132,28 @@ static int set_loopback(struct atm_dev *dev,int mode)
 }
 
 
-static int uPD98402_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int uPD98402_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
 {
        switch (cmd) {
 
                case SONET_GETSTATZ:
                 case SONET_GETSTAT:
-                       return fetch_stats(dev,(struct sonet_stats *) arg,
-                           cmd == SONET_GETSTATZ);
+                       return fetch_stats(dev,arg, cmd == SONET_GETSTATZ);
                case SONET_SETFRAMING:
                        return set_framing(dev,(int) (long) arg);
                case SONET_GETFRAMING:
-                       return put_user(PRIV(dev)->framing,(int *) arg) ?
+                       return put_user(PRIV(dev)->framing,(int __user *)arg) ?
                            -EFAULT : 0;
                case SONET_GETFRSENSE:
                        return get_sense(dev,arg);
                case ATM_SETLOOP:
                        return set_loopback(dev,(int) (long) arg);
                case ATM_GETLOOP:
-                       return put_user(PRIV(dev)->loop_mode,(int *) arg) ?
+                       return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
                            -EFAULT : 0;
                case ATM_QUERYLOOP:
                        return put_user(ATM_LM_LOC_PHY | ATM_LM_LOC_ATM |
-                           ATM_LM_RMT_PHY,(int *) arg) ? -EFAULT : 0;
+                           ATM_LM_RMT_PHY,(int __user *)arg) ? -EFAULT : 0;
                default:
                        return -ENOIOCTLCMD;
        }
index 9027baa..88d548a 100644 (file)
@@ -1429,7 +1429,7 @@ static int zatm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flags)
 }
 
 
-static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
 {
        struct zatm_dev *zatm_dev;
        unsigned long flags;
@@ -1445,7 +1445,7 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
                                int pool;
 
                                if (get_user(pool,
-                                   &((struct zatm_pool_req *) arg)->pool_num))
+                                   &((struct zatm_pool_req __user *) arg)->pool_num))
                                        return -EFAULT;
                                if (pool < 0 || pool > ZATM_LAST_POOL)
                                        return -EINVAL;
@@ -1457,7 +1457,7 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
                                }
                                spin_unlock_irqrestore(&zatm_dev->lock, flags);
                                return copy_to_user(
-                                   &((struct zatm_pool_req *) arg)->info,
+                                   &((struct zatm_pool_req __user *) arg)->info,
                                    &info,sizeof(info)) ? -EFAULT : 0;
                        }
                case ZATM_SETPOOL:
@@ -1467,12 +1467,12 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
 
                                if (!capable(CAP_NET_ADMIN)) return -EPERM;
                                if (get_user(pool,
-                                   &((struct zatm_pool_req *) arg)->pool_num))
+                                   &((struct zatm_pool_req __user *) arg)->pool_num))
                                        return -EFAULT;
                                if (pool < 0 || pool > ZATM_LAST_POOL)
                                        return -EINVAL;
                                if (copy_from_user(&info,
-                                   &((struct zatm_pool_req *) arg)->info,
+                                   &((struct zatm_pool_req __user *) arg)->info,
                                    sizeof(info))) return -EFAULT;
                                if (!info.low_water)
                                        info.low_water = zatm_dev->
@@ -1504,14 +1504,14 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
 
 
 static int zatm_getsockopt(struct atm_vcc *vcc,int level,int optname,
-    void *optval,int optlen)
+    void __user *optval,int optlen)
 {
        return -EINVAL;
 }
 
 
 static int zatm_setsockopt(struct atm_vcc *vcc,int level,int optname,
-    void *optval,int optlen)
+    void __user *optval,int optlen)
 {
        return -EINVAL;
 }
index 82b4430..aa66d71 100644 (file)
@@ -58,6 +58,8 @@ static inline void register_cpu_control(struct cpu *cpu)
 
 /*
  * register_cpu - Setup a driverfs device for a CPU.
+ * @cpu - Callers can set the cpu->no_control field to 1, to indicate not to
+ *               generate a control file in sysfs for this CPU.
  * @num - CPU number to use when creating the device.
  *
  * Initialize and register the CPU device.
@@ -75,7 +77,7 @@ int __init register_cpu(struct cpu *cpu, int num, struct node *root)
                error = sysfs_create_link(&root->sysdev.kobj,
                                          &cpu->sysdev.kobj,
                                          kobject_name(&cpu->sysdev.kobj));
-       if (!error)
+       if (!error && !cpu->no_control)
                register_cpu_control(cpu);
        return error;
 }
index 7508df3..b5aa9dc 100644 (file)
@@ -21,9 +21,10 @@ static ssize_t node_read_cpumap(struct sys_device * dev, char * buf)
        cpumask_t mask = node_dev->cpumap;
        int len;
 
-       /* FIXME - someone should pass us a buffer size (count) or
-        * use seq_file or something to avoid buffer overrun risk. */
-       len = cpumask_scnprintf(buf, 99 /* XXX FIXME */, mask);
+       /* 2004/06/03: buf currently PAGE_SIZE, need > 1 char per 4 bits. */
+       BUILD_BUG_ON(NR_CPUS/4 > PAGE_SIZE/2);
+
+       len = cpumask_scnprintf(buf, PAGE_SIZE-1, mask);
        len += sprintf(buf + len, "\n");
        return len;
 }
index 02a29e8..040acbb 100644 (file)
@@ -97,7 +97,8 @@ static int DAC960_ioctl(struct inode *inode, struct file *file,
        struct gendisk *disk = inode->i_bdev->bd_disk;
        DAC960_Controller_T *p = disk->queue->queuedata;
        int drive_nr = (long)disk->private_data;
-       struct hd_geometry g, *loc = (struct hd_geometry *)arg;
+       struct hd_geometry g;
+       struct hd_geometry __user *loc = (struct hd_geometry __user *)arg;
 
        if (cmd != HDIO_GETGEO || !loc)
                return -EINVAL;
@@ -6465,7 +6466,8 @@ static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset,
   DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command.
 */
 
-static int DAC960_ProcWriteUserCommand(struct file *file, const char *Buffer,
+static int DAC960_ProcWriteUserCommand(struct file *file,
+                                      const char __user *Buffer,
                                       unsigned long Count, void *Data)
 {
   DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
@@ -6553,8 +6555,8 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
       return DAC960_ControllerCount;
     case DAC960_IOCTL_GET_CONTROLLER_INFO:
       {
-       DAC960_ControllerInfo_T *UserSpaceControllerInfo =
-         (DAC960_ControllerInfo_T *) Argument;
+       DAC960_ControllerInfo_T __user *UserSpaceControllerInfo =
+         (DAC960_ControllerInfo_T __user *) Argument;
        DAC960_ControllerInfo_T ControllerInfo;
        DAC960_Controller_T *Controller;
        int ControllerNumber;
@@ -6584,8 +6586,8 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
       }
     case DAC960_IOCTL_V1_EXECUTE_COMMAND:
       {
-       DAC960_V1_UserCommand_T *UserSpaceUserCommand =
-         (DAC960_V1_UserCommand_T *) Argument;
+       DAC960_V1_UserCommand_T __user *UserSpaceUserCommand =
+         (DAC960_V1_UserCommand_T __user *) Argument;
        DAC960_V1_UserCommand_T UserCommand;
        DAC960_Controller_T *Controller;
        DAC960_Command_T *Command = NULL;
@@ -6744,8 +6746,8 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
       }
     case DAC960_IOCTL_V2_EXECUTE_COMMAND:
       {
-       DAC960_V2_UserCommand_T *UserSpaceUserCommand =
-         (DAC960_V2_UserCommand_T *) Argument;
+       DAC960_V2_UserCommand_T __user *UserSpaceUserCommand =
+         (DAC960_V2_UserCommand_T __user *) Argument;
        DAC960_V2_UserCommand_T UserCommand;
        DAC960_Controller_T *Controller;
        DAC960_Command_T *Command = NULL;
@@ -6898,8 +6900,8 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
       }
     case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
       {
-       DAC960_V2_GetHealthStatus_T *UserSpaceGetHealthStatus =
-         (DAC960_V2_GetHealthStatus_T *) Argument;
+       DAC960_V2_GetHealthStatus_T __user *UserSpaceGetHealthStatus =
+         (DAC960_V2_GetHealthStatus_T __user *) Argument;
        DAC960_V2_GetHealthStatus_T GetHealthStatus;
        DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
        DAC960_Controller_T *Controller;
index 676c078..be8f899 100644 (file)
@@ -1914,8 +1914,8 @@ typedef struct DAC960_V1_UserCommand
   unsigned char ControllerNumber;
   DAC960_V1_CommandMailbox_T CommandMailbox;
   int DataTransferLength;
-  void *DataTransferBuffer;
-  DAC960_V1_DCDB_T *DCDB;
+  void __user *DataTransferBuffer;
+  DAC960_V1_DCDB_T __user *DCDB;
 }
 DAC960_V1_UserCommand_T;
 
@@ -1948,8 +1948,8 @@ typedef struct DAC960_V2_UserCommand
   DAC960_V2_CommandMailbox_T CommandMailbox;
   int DataTransferLength;
   int RequestSenseLength;
-  void *DataTransferBuffer;
-  void *RequestSenseBuffer;
+  void __user *DataTransferBuffer;
+  void __user *RequestSenseBuffer;
 }
 DAC960_V2_UserCommand_T;
 
@@ -1980,7 +1980,7 @@ DAC960_V2_KernelCommand_T;
 typedef struct DAC960_V2_GetHealthStatus
 {
   unsigned char ControllerNumber;
-  DAC960_V2_HealthStatusBuffer_T *HealthStatusBuffer;
+  DAC960_V2_HealthStatusBuffer_T __user *HealthStatusBuffer;
 }
 DAC960_V2_GetHealthStatus_T;
 
index ecbc4e4..0e18df6 100644 (file)
@@ -6,7 +6,7 @@ menu "Block devices"
 
 config BLK_DEV_FD
        tristate "Normal floppy disk support"
-       depends on (!X86_PC9800 && !ARCH_S390 && !M68K && !IA64) || Q40 || (SUN3X && BROKEN)
+       depends on (!ARCH_S390 && !M68K && !IA64) || Q40 || (SUN3X && BROKEN)
        ---help---
          If you want to use the floppy disk drive(s) of your PC under Linux,
          say Y. Information about this driver, especially important for IBM
@@ -26,13 +26,6 @@ config ATARI_FLOPPY
        tristate "Atari floppy support"
        depends on ATARI
 
-config BLK_DEV_FD98
-       tristate "NEC PC-9800 floppy disk support"
-       depends on X86_PC9800
-       ---help---
-         If you want to use the floppy disk drive(s) of NEC PC-9801/PC-9821,
-         say Y.
-
 config BLK_DEV_SWIM_IOP
        bool "Macintosh IIfx/Quadra 900/Quadra 950 floppy support (EXPERIMENTAL)"
        depends on MAC && EXPERIMENTAL && BROKEN
index 6a5ed64..38fd6fe 100644 (file)
@@ -413,7 +413,7 @@ static unsigned long carm_major_alloc;
 static int carm_bdev_ioctl(struct inode *ino, struct file *fil,
                           unsigned int cmd, unsigned long arg)
 {
-       void __user *usermem = (void *) arg;
+       void __user *usermem = (void __user *) arg;
        struct carm_port *port = ino->i_bdev->bd_disk->private_data;
        struct hd_geometry geom;
 
index b22099f..24d72c7 100644 (file)
@@ -135,7 +135,6 @@ static int register_new_disk(ctlr_info_t *h);
 
 static void cciss_getgeometry(int cntl_num);
 
-static inline void addQ(CommandList_struct **Qptr, CommandList_struct *c);
 static void start_io( ctlr_info_t *h);
 static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size,
        unsigned int use_unit_num, unsigned int log_unit, __u8 page_code,
@@ -157,6 +156,36 @@ static struct block_device_operations cciss_fops  = {
        .revalidate_disk= cciss_revalidate,
 };
 
+/*
+ * Enqueuing and dequeuing functions for cmdlists.
+ */
+static inline void addQ(CommandList_struct **Qptr, CommandList_struct *c)
+{
+        if (*Qptr == NULL) {
+                *Qptr = c;
+                c->next = c->prev = c;
+        } else {
+                c->prev = (*Qptr)->prev;
+                c->next = (*Qptr);
+                (*Qptr)->prev->next = c;
+                (*Qptr)->prev = c;
+        }
+}
+
+static inline CommandList_struct *removeQ(CommandList_struct **Qptr, 
+                                               CommandList_struct *c)
+{
+        if (c && c->next != c) {
+                if (*Qptr == c) *Qptr = c->next;
+                c->prev->next = c->next;
+                c->next->prev = c->prev;
+        } else {
+                *Qptr = NULL;
+        }
+        return c;
+}
+#ifdef CONFIG_PROC_FS
+
 #include "cciss_scsi.c"                /* For SCSI tape support */
 
 /*
@@ -167,7 +196,6 @@ static struct block_device_operations cciss_fops  = {
 #define RAID_UNKNOWN 6
 static const char *raid_label[] = {"0","4","1(0+1)","5","5+1","ADG",
                                           "UNKNOWN"};
-#ifdef CONFIG_PROC_FS
 
 static struct proc_dir_entry *proc_cciss;
 
@@ -257,7 +285,7 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
 }
 
 static int 
-cciss_proc_write(struct file *file, const char *buffer, 
+cciss_proc_write(struct file *file, const char __user *buffer, 
                        unsigned long count, void *data)
 {
        unsigned char cmd[80];
@@ -451,6 +479,148 @@ static int cciss_release(struct inode *inode, struct file *filep)
        return 0;
 }
 
+#ifdef CONFIG_COMPAT
+/* for AMD 64 bit kernel compatibility with 32-bit userland ioctls */
+extern long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
+extern int
+register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int,
+      unsigned int, unsigned long, struct file *));
+extern int unregister_ioctl32_conversion(unsigned int cmd);
+
+static int cciss_ioctl32_passthru(unsigned int fd, unsigned cmd, unsigned long arg, struct file *file);
+static int cciss_ioctl32_big_passthru(unsigned int fd, unsigned cmd, unsigned long arg,
+       struct file *file);
+
+typedef int (*handler_type) (unsigned int, unsigned int, unsigned long, struct file *);
+
+static struct ioctl32_map {
+       unsigned int cmd;
+       handler_type handler;
+       int registered;
+} cciss_ioctl32_map[] = {
+       { CCISS_GETPCIINFO,     (handler_type) sys_ioctl, 0 },
+       { CCISS_GETINTINFO,     (handler_type) sys_ioctl, 0 },
+       { CCISS_SETINTINFO,     (handler_type) sys_ioctl, 0 },
+       { CCISS_GETNODENAME,    (handler_type) sys_ioctl, 0 },
+       { CCISS_SETNODENAME,    (handler_type) sys_ioctl, 0 },
+       { CCISS_GETHEARTBEAT,   (handler_type) sys_ioctl, 0 },
+       { CCISS_GETBUSTYPES,    (handler_type) sys_ioctl, 0 },
+       { CCISS_GETFIRMVER,     (handler_type) sys_ioctl, 0 },
+       { CCISS_GETDRIVVER,     (handler_type) sys_ioctl, 0 },
+       { CCISS_REVALIDVOLS,    (handler_type) sys_ioctl, 0 },
+       { CCISS_PASSTHRU32,     cciss_ioctl32_passthru, 0 },
+       { CCISS_DEREGDISK,      (handler_type) sys_ioctl, 0 },
+       { CCISS_REGNEWDISK,     (handler_type) sys_ioctl, 0 },
+       { CCISS_REGNEWD,        (handler_type) sys_ioctl, 0 },
+       { CCISS_RESCANDISK,     (handler_type) sys_ioctl, 0 },
+       { CCISS_GETLUNINFO,     (handler_type) sys_ioctl, 0 },
+       { CCISS_BIG_PASSTHRU32, cciss_ioctl32_big_passthru, 0 },
+};
+#define NCCISS_IOCTL32_ENTRIES (sizeof(cciss_ioctl32_map) / sizeof(cciss_ioctl32_map[0]))
+static void register_cciss_ioctl32(void)
+{
+       int i, rc;
+
+       for (i=0; i < NCCISS_IOCTL32_ENTRIES; i++) {
+               rc = register_ioctl32_conversion(
+                       cciss_ioctl32_map[i].cmd,
+                       cciss_ioctl32_map[i].handler);
+               if (rc != 0) {
+                       printk(KERN_WARNING "cciss: failed to register "
+                               "32 bit compatible ioctl 0x%08x\n",
+                               cciss_ioctl32_map[i].cmd);
+                       cciss_ioctl32_map[i].registered = 0;
+               } else
+                       cciss_ioctl32_map[i].registered = 1;
+       }
+}
+static void unregister_cciss_ioctl32(void)
+{
+       int i, rc;
+
+       for (i=0; i < NCCISS_IOCTL32_ENTRIES; i++) {
+               if (!cciss_ioctl32_map[i].registered)
+                       continue;
+               rc = unregister_ioctl32_conversion(
+                       cciss_ioctl32_map[i].cmd);
+               if (rc == 0) {
+                       cciss_ioctl32_map[i].registered = 0;
+                       continue;
+               }
+               printk(KERN_WARNING "cciss: failed to unregister "
+                       "32 bit compatible ioctl 0x%08x\n",
+                       cciss_ioctl32_map[i].cmd);
+       }
+}
+int cciss_ioctl32_passthru(unsigned int fd, unsigned cmd, unsigned long arg,
+       struct file *file)
+{
+       IOCTL32_Command_struct *arg32 =
+               (IOCTL32_Command_struct *) arg;
+       IOCTL_Command_struct arg64;
+       mm_segment_t old_fs;
+       int err;
+       unsigned long cp;
+
+       err = 0;
+       err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, sizeof(arg64.LUN_info));
+       err |= copy_from_user(&arg64.Request, &arg32->Request, sizeof(arg64.Request));
+       err |= copy_from_user(&arg64.error_info, &arg32->error_info, sizeof(arg64.error_info));
+       err |= get_user(arg64.buf_size, &arg32->buf_size);
+       err |= get_user(cp, &arg32->buf);
+       arg64.buf = (BYTE *)cp;
+
+       if (err)
+               return -EFAULT;
+
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       err = sys_ioctl(fd, CCISS_PASSTHRU, (unsigned long) &arg64);
+       set_fs(old_fs);
+       if (err)
+               return err;
+       err |= copy_to_user(&arg32->error_info, &arg64.error_info, sizeof(&arg32->error_info));
+       if (err)
+               return -EFAULT;
+       return err;
+}
+int cciss_ioctl32_big_passthru(unsigned int fd, unsigned cmd, unsigned long arg,
+       struct file *file)
+{
+       BIG_IOCTL32_Command_struct *arg32 =
+               (BIG_IOCTL32_Command_struct *) arg;
+       BIG_IOCTL_Command_struct arg64;
+       mm_segment_t old_fs;
+       int err;
+       unsigned long cp;
+
+       err = 0;
+       err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, sizeof(arg64.LUN_info));
+       err |= copy_from_user(&arg64.Request, &arg32->Request, sizeof(arg64.Request));
+       err |= copy_from_user(&arg64.error_info, &arg32->error_info, sizeof(arg64.error_info));
+       err |= get_user(arg64.buf_size, &arg32->buf_size);
+       err |= get_user(arg64.malloc_size, &arg32->malloc_size);
+       err |= get_user(cp, &arg32->buf);
+       arg64.buf = (BYTE *)cp;
+
+       if (err)
+                return -EFAULT;
+
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       err = sys_ioctl(fd, CCISS_BIG_PASSTHRU, (unsigned long) &arg64);
+       set_fs(old_fs);
+       if (err)
+               return err;
+       err |= copy_to_user(&arg32->error_info, &arg64.error_info, sizeof(&arg32->error_info));
+       if (err)
+               return -EFAULT;
+       return err;
+}
+#else
+static inline void register_cciss_ioctl32(void) {}
+static inline void unregister_cciss_ioctl32(void) {}
+#endif
 /*
  * ioctl 
  */
@@ -462,6 +632,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
        ctlr_info_t *host = get_host(disk);
        drive_info_struct *drv = get_drv(disk);
        int ctlr = host->ctlr;
+       void __user *argp = (void __user *)arg;
 
 #ifdef CCISS_DEBUG
        printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg);
@@ -478,8 +649,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                 } else
                        return -ENXIO;
                 driver_geo.start= get_start_sect(inode->i_bdev);
-                if (copy_to_user((void *) arg, &driver_geo,
-                                sizeof( struct hd_geometry)))
+                if (copy_to_user(argp, &driver_geo, sizeof(struct hd_geometry)))
                         return  -EFAULT;
                 return(0);
        }
@@ -492,7 +662,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                pciinfo.bus = host->pdev->bus->number;
                pciinfo.dev_fn = host->pdev->devfn;
                pciinfo.board_id = host->board_id;
-               if (copy_to_user((void *) arg, &pciinfo,  sizeof( cciss_pci_info_struct )))
+               if (copy_to_user(argp, &pciinfo,  sizeof( cciss_pci_info_struct )))
                        return  -EFAULT;
                return(0);
        }       
@@ -502,7 +672,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                if (!arg) return -EINVAL;
                intinfo.delay = readl(&host->cfgtable->HostWrite.CoalIntDelay);
                intinfo.count = readl(&host->cfgtable->HostWrite.CoalIntCount);
-               if (copy_to_user((void *) arg, &intinfo, sizeof( cciss_coalint_struct )))
+               if (copy_to_user(argp, &intinfo, sizeof( cciss_coalint_struct )))
                        return -EFAULT;
                 return(0);
         }
@@ -514,7 +684,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
 
                if (!arg) return -EINVAL;       
                if (!capable(CAP_SYS_ADMIN)) return -EPERM;
-               if (copy_from_user(&intinfo, (void *) arg, sizeof( cciss_coalint_struct)))
+               if (copy_from_user(&intinfo, argp, sizeof( cciss_coalint_struct)))
                        return -EFAULT;
                if ( (intinfo.delay == 0 ) && (intinfo.count == 0))
 
@@ -550,7 +720,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                if (!arg) return -EINVAL;
                for(i=0;i<16;i++)
                        NodeName[i] = readb(&host->cfgtable->ServerName[i]);
-                if (copy_to_user((void *) arg, NodeName, sizeof( NodeName_type)))
+                if (copy_to_user(argp, NodeName, sizeof( NodeName_type)))
                        return  -EFAULT;
                 return(0);
         }
@@ -563,7 +733,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                if (!arg) return -EINVAL;
                if (!capable(CAP_SYS_ADMIN)) return -EPERM;
                
-               if (copy_from_user(NodeName, (void *) arg, sizeof( NodeName_type)))
+               if (copy_from_user(NodeName, argp, sizeof( NodeName_type)))
                        return -EFAULT;
 
                spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
@@ -593,7 +763,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
 
                if (!arg) return -EINVAL;
                 heartbeat = readl(&host->cfgtable->HeartBeat);
-                if (copy_to_user((void *) arg, &heartbeat, sizeof( Heartbeat_type)))
+                if (copy_to_user(argp, &heartbeat, sizeof( Heartbeat_type)))
                        return -EFAULT;
                 return(0);
         }
@@ -603,7 +773,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
 
                if (!arg) return -EINVAL;
                 BusTypes = readl(&host->cfgtable->BusTypes);
-                if (copy_to_user((void *) arg, &BusTypes, sizeof( BusTypes_type) ))
+                if (copy_to_user(argp, &BusTypes, sizeof( BusTypes_type) ))
                        return  -EFAULT;
                 return(0);
         }
@@ -614,7 +784,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                if (!arg) return -EINVAL;
                memcpy(firmware, host->firm_ver, 4);
 
-                if (copy_to_user((void *) arg, firmware, sizeof( FirmwareVer_type)))
+                if (copy_to_user(argp, firmware, sizeof( FirmwareVer_type)))
                        return -EFAULT;
                 return(0);
         }
@@ -624,7 +794,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
 
                 if (!arg) return -EINVAL;
 
-                if (copy_to_user((void *) arg, &DriverVer, sizeof( DriverVer_type) ))
+                if (copy_to_user(argp, &DriverVer, sizeof( DriverVer_type) ))
                        return -EFAULT;
                 return(0);
         }
@@ -648,7 +818,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                        if (disk->part[i]->nr_sects != 0)
                                luninfo.num_parts++;
                }
-               if (copy_to_user((void *) arg, &luninfo,
+               if (copy_to_user(argp, &luninfo,
                                sizeof(LogvolInfo_struct)))
                        return -EFAULT;
                return(0);
@@ -672,7 +842,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
        
                if (!capable(CAP_SYS_RAWIO)) return -EPERM;
 
-               if (copy_from_user(&iocommand, (void *) arg, sizeof( IOCTL_Command_struct) ))
+               if (copy_from_user(&iocommand, argp, sizeof( IOCTL_Command_struct) ))
                        return -EFAULT;
                if((iocommand.buf_size < 1) && 
                                (iocommand.Request.Type.Direction != XFER_NONE))
@@ -753,7 +923,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
 
                /* Copy the error information out */ 
                iocommand.error_info = *(c->err_info);
-               if ( copy_to_user((void *) arg, &iocommand, sizeof( IOCTL_Command_struct) ) )
+               if ( copy_to_user(argp, &iocommand, sizeof( IOCTL_Command_struct) ) )
                {
                        kfree(buff);
                        cmd_free(host, c, 0);
@@ -787,7 +957,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                DECLARE_COMPLETION(wait);
                __u32   left;
                __u32   sz;
-               BYTE    *data_ptr;
+               BYTE    __user *data_ptr;
 
                if (!arg)
                        return -EINVAL;
@@ -799,7 +969,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                        status = -ENOMEM;
                        goto cleanup1;
                }
-               if (copy_from_user(ioc, (void *) arg, sizeof(*ioc))) {
+               if (copy_from_user(ioc, argp, sizeof(*ioc))) {
                        status = -EFAULT;
                        goto cleanup1;
                }
@@ -831,7 +1001,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                        goto cleanup1;
                }
                left = ioc->buf_size;
-               data_ptr = (BYTE *) ioc->buf;
+               data_ptr = ioc->buf;
                while (left) {
                        sz = (left > ioc->malloc_size) ? ioc->malloc_size : left;
                        buff_size[sg_used] = sz;
@@ -896,14 +1066,14 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                }
                /* Copy the error information out */
                ioc->error_info = *(c->err_info);
-               if (copy_to_user((void *) arg, ioc, sizeof(*ioc))) {
+               if (copy_to_user(argp, ioc, sizeof(*ioc))) {
                        cmd_free(host, c, 0);
                        status = -EFAULT;
                        goto cleanup1;
                }
                if (ioc->Request.Type.Direction == XFER_READ) {
                        /* Copy the data out of the buffer we created */
-                       BYTE *ptr = (BYTE  *) ioc->buf;
+                       BYTE __user *ptr = ioc->buf;
                        for(i=0; i< sg_used; i++) {
                                if (copy_to_user(ptr, buff[i], buff_size[i])) {
                                        cmd_free(host, c, 0);
@@ -1685,35 +1855,6 @@ static ulong remap_pci_mem(ulong base, ulong size)
         return (ulong) (page_remapped ? (page_remapped + page_offs) : 0UL);
 }
 
-/*
- * Enqueuing and dequeuing functions for cmdlists.
- */
-static inline void addQ(CommandList_struct **Qptr, CommandList_struct *c)
-{
-        if (*Qptr == NULL) {
-                *Qptr = c;
-                c->next = c->prev = c;
-        } else {
-                c->prev = (*Qptr)->prev;
-                c->next = (*Qptr);
-                (*Qptr)->prev->next = c;
-                (*Qptr)->prev = c;
-        }
-}
-
-static inline CommandList_struct *removeQ(CommandList_struct **Qptr, 
-                                               CommandList_struct *c)
-{
-        if (c && c->next != c) {
-                if (*Qptr == c) *Qptr = c->next;
-                c->prev->next = c->next;
-                c->next->prev = c->prev;
-        } else {
-                *Qptr = NULL;
-        }
-        return c;
-}
-
 /* 
  * Takes jobs of the Q and sends them to the hardware, then puts it on 
  * the Q to wait for completion. 
@@ -2729,6 +2870,7 @@ int __init cciss_init(void)
 
 static int __init init_cciss_module(void)
 {
+       register_cciss_ioctl32();
        return ( cciss_init());
 }
 
@@ -2736,6 +2878,7 @@ static void __exit cleanup_cciss_module(void)
 {
        int i;
 
+       unregister_cciss_ioctl32();
        pci_unregister_driver(&cciss_pci_driver);
        /* double check that all controller entrys have been removed */
        for (i=0; i< MAX_CTLR; i++) 
index 9636ac5..9df82b8 100644 (file)
@@ -29,7 +29,7 @@
    physical nor logical disks are presented through the scsi layer. */
 
 #include "../scsi/scsi.h" 
-#include "../scsi/hosts.h" 
+#include <scsi/scsi_host.h> 
 #include <asm/atomic.h>
 #include <linux/timer.h>
 #include <linux/completion.h>
index 977d32d..3b8059a 100644 (file)
@@ -59,6 +59,14 @@ struct cfq_data {
        unsigned int max_queued;
 
        mempool_t *crq_pool;
+
+       request_queue_t *queue;
+
+       /*
+        * tunables
+        */
+       unsigned int cfq_quantum;
+       unsigned int cfq_queued;
 };
 
 struct cfq_queue {
@@ -89,7 +97,8 @@ struct cfq_rq {
 
 static void cfq_put_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq);
 static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *cfqd, int pid);
-static void cfq_dispatch_sort(struct list_head *head, struct cfq_rq *crq);
+static void cfq_dispatch_sort(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+                             struct cfq_rq *crq);
 
 /*
  * lots of deadline iosched dupes, can be abstracted later...
@@ -206,8 +215,7 @@ retry:
                return;
        }
 
-       cfq_del_crq_rb(cfqq, __alias);
-       cfq_dispatch_sort(cfqd->dispatch, __alias);
+       cfq_dispatch_sort(cfqd, cfqq, __alias);
        goto retry;
 }
 
@@ -321,11 +329,16 @@ cfq_merged_requests(request_queue_t *q, struct request *req,
        cfq_remove_request(q, next);
 }
 
-static void cfq_dispatch_sort(struct list_head *head, struct cfq_rq *crq)
+static void
+cfq_dispatch_sort(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+                 struct cfq_rq *crq)
 {
-       struct list_head *entry = head;
+       struct list_head *head = cfqd->dispatch, *entry = head;
        struct request *__rq;
 
+       cfq_del_crq_rb(cfqq, crq);
+       cfq_remove_merge_hints(cfqd->queue, crq);
+
        if (!list_empty(head)) {
                __rq = list_entry_rq(head->next);
 
@@ -352,9 +365,7 @@ __cfq_dispatch_requests(request_queue_t *q, struct cfq_data *cfqd,
 {
        struct cfq_rq *crq = rb_entry_crq(rb_first(&cfqq->sort_list));
 
-       cfq_del_crq_rb(cfqq, crq);
-       cfq_remove_merge_hints(q, crq);
-       cfq_dispatch_sort(cfqd->dispatch, crq);
+       cfq_dispatch_sort(cfqd, cfqq, crq);
 }
 
 static int cfq_dispatch_requests(request_queue_t *q, struct cfq_data *cfqd)
@@ -385,7 +396,7 @@ restart:
                ret = 1;
        }
 
-       if ((queued < cfq_quantum) && good_queues)
+       if ((queued < cfqd->cfq_quantum) && good_queues)
                goto restart;
 
        return ret;
@@ -556,7 +567,7 @@ static int cfq_may_queue(request_queue_t *q, int rw)
 
        cfqq = cfq_find_cfq_hash(cfqd, current->tgid);
        if (cfqq) {
-               int limit = (q->nr_requests - cfq_queued) / cfqd->busy_queues;
+               int limit = (q->nr_requests - cfqd->cfq_queued) / cfqd->busy_queues;
 
                if (limit < 3)
                        limit = 3;
@@ -574,6 +585,8 @@ static void cfq_put_request(request_queue_t *q, struct request *rq)
 {
        struct cfq_data *cfqd = q->elevator.elevator_data;
        struct cfq_rq *crq = RQ_DATA(rq);
+       struct request_list *rl;
+       int other_rw;
 
        if (crq) {
                BUG_ON(q->last_merge == rq);
@@ -582,6 +595,23 @@ static void cfq_put_request(request_queue_t *q, struct request *rq)
                mempool_free(crq, cfqd->crq_pool);
                rq->elevator_private = NULL;
        }
+
+       /*
+        * work-around for may_queue "bug": if a read gets issued and refused
+        * to queue because writes ate all the allowed slots and no other
+        * reads are pending for this queue, it could get stuck infinitely
+        * since freed_request() only checks the waitqueue for writes when
+        * freeing them. or vice versa for a single write vs many reads.
+        * so check here whether "the other" data direction might be able
+        * to queue and wake them
+        */
+       rl = &q->rq;
+       other_rw = rq_data_dir(rq) ^ 1;
+       if (rl->count[other_rw] <= q->nr_requests) {
+               smp_mb();
+               if (waitqueue_active(&rl->wait[other_rw]))
+                       wake_up(&rl->wait[other_rw]);
+       }
 }
 
 static int cfq_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
@@ -643,6 +673,7 @@ static int cfq_init(request_queue_t *q, elevator_t *e)
 
        cfqd->dispatch = &q->queue_head;
        e->elevator_data = cfqd;
+       cfqd->queue = q;
 
        /*
         * just set it to some high value, we want anyone to be able to queue
@@ -651,6 +682,9 @@ static int cfq_init(request_queue_t *q, elevator_t *e)
        cfqd->max_queued = q->nr_requests;
        q->nr_requests = 8192;
 
+       cfqd->cfq_queued = cfq_queued;
+       cfqd->cfq_quantum = cfq_quantum;
+
        return 0;
 out_crqpool:
        kfree(cfqd->cfq_hash);
@@ -685,8 +719,110 @@ static int __init cfq_slab_setup(void)
 
 subsys_initcall(cfq_slab_setup);
 
+/*
+ * sysfs parts below -->
+ */
+struct cfq_fs_entry {
+       struct attribute attr;
+       ssize_t (*show)(struct cfq_data *, char *);
+       ssize_t (*store)(struct cfq_data *, const char *, size_t);
+};
+
+static ssize_t
+cfq_var_show(unsigned int var, char *page)
+{
+       return sprintf(page, "%d\n", var);
+}
+
+static ssize_t
+cfq_var_store(unsigned int *var, const char *page, size_t count)
+{
+       char *p = (char *) page;
+
+       *var = simple_strtoul(p, &p, 10);
+       return count;
+}
+
+#define SHOW_FUNCTION(__FUNC, __VAR)                                   \
+static ssize_t __FUNC(struct cfq_data *cfqd, char *page)               \
+{                                                                      \
+       return cfq_var_show(__VAR, (page));                             \
+}
+SHOW_FUNCTION(cfq_quantum_show, cfqd->cfq_quantum);
+SHOW_FUNCTION(cfq_queued_show, cfqd->cfq_queued);
+#undef SHOW_FUNCTION
+
+#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX)                                \
+static ssize_t __FUNC(struct cfq_data *cfqd, const char *page, size_t count)   \
+{                                                                      \
+       int ret = cfq_var_store(__PTR, (page), count);                  \
+       if (*(__PTR) < (MIN))                                           \
+               *(__PTR) = (MIN);                                       \
+       else if (*(__PTR) > (MAX))                                      \
+               *(__PTR) = (MAX);                                       \
+       return ret;                                                     \
+}
+STORE_FUNCTION(cfq_quantum_store, &cfqd->cfq_quantum, 1, INT_MAX);
+STORE_FUNCTION(cfq_queued_store, &cfqd->cfq_queued, 1, INT_MAX);
+#undef STORE_FUNCTION
+
+static struct cfq_fs_entry cfq_quantum_entry = {
+       .attr = {.name = "quantum", .mode = S_IRUGO | S_IWUSR },
+       .show = cfq_quantum_show,
+       .store = cfq_quantum_store,
+};
+static struct cfq_fs_entry cfq_queued_entry = {
+       .attr = {.name = "queued", .mode = S_IRUGO | S_IWUSR },
+       .show = cfq_queued_show,
+       .store = cfq_queued_store,
+};
+
+static struct attribute *default_attrs[] = {
+       &cfq_quantum_entry.attr,
+       &cfq_queued_entry.attr,
+       NULL,
+};
+
+#define to_cfq(atr) container_of((atr), struct cfq_fs_entry, attr)
+
+static ssize_t
+cfq_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
+{
+       elevator_t *e = container_of(kobj, elevator_t, kobj);
+       struct cfq_fs_entry *entry = to_cfq(attr);
+
+       if (!entry->show)
+               return 0;
+
+       return entry->show(e->elevator_data, page);
+}
+
+static ssize_t
+cfq_attr_store(struct kobject *kobj, struct attribute *attr,
+              const char *page, size_t length)
+{
+       elevator_t *e = container_of(kobj, elevator_t, kobj);
+       struct cfq_fs_entry *entry = to_cfq(attr);
+
+       if (!entry->store)
+               return -EINVAL;
+
+       return entry->store(e->elevator_data, page, length);
+}
+
+static struct sysfs_ops cfq_sysfs_ops = {
+       .show   = cfq_attr_show,
+       .store  = cfq_attr_store,
+};
+
+struct kobj_type cfq_ktype = {
+       .sysfs_ops      = &cfq_sysfs_ops,
+       .default_attrs  = default_attrs,
+};
+
 elevator_t iosched_cfq = {
        .elevator_name =                "cfq",
+       .elevator_ktype =               &cfq_ktype,
        .elevator_merge_fn =            cfq_merge,
        .elevator_merged_fn =           cfq_merged_request,
        .elevator_merge_req_fn =        cfq_merged_requests,
index f6f7818..b42a8d3 100644 (file)
@@ -1157,8 +1157,8 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
        ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
        int error;
        int diskinfo[4];
-       struct hd_geometry *geo = (struct hd_geometry *)arg;
-       ida_ioctl_t *io = (ida_ioctl_t*)arg;
+       struct hd_geometry __user *geo = (struct hd_geometry __user *)arg;
+       ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg;
        ida_ioctl_t *my_io;
 
        switch(cmd) {
@@ -1202,7 +1202,7 @@ out_passthru:
                return error;
        case IDAGETCTLRSIG:
                if (!arg) return -EINVAL;
-               put_user(host->ctlr_sig, (int*)arg);
+               put_user(host->ctlr_sig, (int __user *)arg);
                return 0;
        case IDAREVALIDATEVOLS:
                if (iminor(inode) != 0)
@@ -1210,7 +1210,7 @@ out_passthru:
                return revalidate_allvol(host);
        case IDADRIVERVERSION:
                if (!arg) return -EINVAL;
-               put_user(DRIVER_VERSION, (unsigned long*)arg);
+               put_user(DRIVER_VERSION, (unsigned long __user *)arg);
                return 0;
        case IDAGETPCIINFO:
        {
@@ -1221,7 +1221,7 @@ out_passthru:
                pciinfo.bus = host->pci_dev->bus->number;
                pciinfo.dev_fn = host->pci_dev->devfn;
                pciinfo.board_id = host->board_id;
-               if(copy_to_user((void *) arg, &pciinfo,  
+               if(copy_to_user((void __user *) arg, &pciinfo,  
                        sizeof( ida_pci_info_struct)))
                                return -EFAULT;
                return(0);
@@ -1272,7 +1272,7 @@ static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io)
                        cmd_free(h, c, 0); 
                        return(error);
                }
-               if (copy_from_user(p, (void*)io->sg[0].addr, io->sg[0].size)) {
+               if (copy_from_user(p, io->sg[0].addr, io->sg[0].size)) {
                        kfree(p);
                        cmd_free(h, c, 0); 
                        return -EFAULT;
@@ -1313,7 +1313,7 @@ static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io)
                         cmd_free(h, c, 0);
                         return(error);
                 }
-               if (copy_from_user(p, (void*)io->sg[0].addr, io->sg[0].size)) {
+               if (copy_from_user(p, io->sg[0].addr, io->sg[0].size)) {
                        kfree(p);
                         cmd_free(h, c, 0);
                        return -EFAULT;
@@ -1354,7 +1354,7 @@ static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io)
        case DIAG_PASS_THRU:
        case SENSE_CONTROLLER_PERFORMANCE:
        case READ_FLASH_ROM:
-               if (copy_to_user((void*)io->sg[0].addr, p, io->sg[0].size)) {
+               if (copy_to_user(io->sg[0].addr, p, io->sg[0].size)) {
                        kfree(p);
                        return -EFAULT;
                }
index 4ce5ca1..da60f83 100644 (file)
@@ -181,6 +181,14 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
 
        rq->q = q;
        q->elevator.elevator_add_req_fn(q, rq, where);
+
+       if (blk_queue_plugged(q)) {
+               int nrq = q->rq.count[READ] + q->rq.count[WRITE] - q->in_flight;
+
+               if (nrq == q->unplug_thresh)
+                       __generic_unplug_device(q);
+       }
+
 }
 
 void elv_add_request(request_queue_t *q, struct request *rq, int where,
index f1cc334..70375a0 100644 (file)
@@ -4238,7 +4238,7 @@ int __init floppy_init(void)
                }
 
                disks[dr]->major = FLOPPY_MAJOR;
-               disks[dr]->first_minor = TOMINOR(i);
+               disks[dr]->first_minor = TOMINOR(dr);
                disks[dr]->fops = &floppy_fops;
                sprintf(disks[dr]->disk_name, "fd%d", dr);
 
index e90825b..4159e52 100644 (file)
@@ -57,7 +57,7 @@ typedef struct {
 
 /* currently, sg_cnt is assumed to be 1: only the 0th element of sg is used */
        struct {
-               void    *addr;
+               void    __user *addr;
                size_t  size;
        } sg[SG_MAX];
        int     sg_cnt;
index e4a8c0d..8d3d38b 100644 (file)
@@ -1123,7 +1123,7 @@ EXPORT_SYMBOL(blk_remove_plug);
 /*
  * remove the plug and let it rip..
  */
-static inline void __generic_unplug_device(request_queue_t *q)
+inline void __generic_unplug_device(request_queue_t *q)
 {
        if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags))
                return;
@@ -1137,6 +1137,7 @@ static inline void __generic_unplug_device(request_queue_t *q)
        if (elv_next_request(q))
                q->request_fn(q);
 }
+EXPORT_SYMBOL(__generic_unplug_device);
 
 /**
  * generic_unplug_device - fire a request queue
@@ -2280,13 +2281,9 @@ get_rq:
 out:
        if (freereq)
                __blk_put_request(q, freereq);
+       if (bio_sync(bio))
+               __generic_unplug_device(q);
 
-       if (blk_queue_plugged(q)) {
-               int nrq = q->rq.count[READ] + q->rq.count[WRITE] - q->in_flight;
-
-               if (nrq == q->unplug_thresh || bio_sync(bio))
-                       __generic_unplug_device(q);
-       }
        spin_unlock_irq(q->queue_lock);
        return 0;
 
index 95ec95c..f125094 100644 (file)
@@ -308,7 +308,9 @@ lo_read_actor(read_descriptor_t *desc, struct page *page,
                       page->index);
                desc->error = -EINVAL;
        }
-       
+
+       flush_dcache_page(p->page);
+
        desc->count = count - size;
        desc->written += size;
        p->offset += size;
index 4f090dc..55d1c0a 100644 (file)
 #define j44(a,b)               (((a>>4)&0x0f)+(b&0xf0))
 #define j53(a,b)               (((a>>3)&0x1f)+((b<<4)&0xe0))
 
+static int epatc8;
+
+module_param(epatc8, int, 0);
+MODULE_PARM_DESC(epatc8, "support for the Shuttle EP1284 chip, "
+       "used in any recent Imation SuperDisk (LS-120) drive.");
+
 /* cont =  0   IDE register file
    cont =  1   IDE control registers
    cont =  2   internal EPAT registers
@@ -209,15 +215,18 @@ static void epat_connect ( PIA *pi )
 {       pi->saved_r0 = r0();
         pi->saved_r2 = r2();
 
-#ifdef CONFIG_PARIDE_EPATC8
        /* Initialize the chip */
-        CPP(0);CPP(0x40);CPP(0xe0);              
-        w0(0);w2(1);w2(4);
-        WR(0x8,0x12);WR(0xc,0x14);WR(0x12,0x10);
-        WR(0xe,0xf);WR(0xf,4);
-     /* WR(0xe,0xa);WR(0xf,4); */
-        WR(0xe,0xd);WR(0xf,0);
-     /* CPP(0x30); */
+       CPP(0);
+
+       if (epatc8) {
+               CPP(0x40);CPP(0xe0);
+               w0(0);w2(1);w2(4);
+               WR(0x8,0x12);WR(0xc,0x14);WR(0x12,0x10);
+               WR(0xe,0xf);WR(0xf,4);
+               /* WR(0xe,0xa);WR(0xf,4); */
+               WR(0xe,0xd);WR(0xf,0);
+               /* CPP(0x30); */
+       }
 
         /* Connect to the chip */
        CPP(0xe0);
@@ -227,15 +236,10 @@ static void epat_connect ( PIA *pi )
           /* Request EPP */
           w0(0x40);w2(6);w2(7);w2(4);w2(0xc);w2(4);
         }
-#else
-       CPP(0); CPP(0xe0);
-       w0(0); w2(1); w2(4);
-       if (pi->mode >= 3) {
-               w0(0); w2(1); w2(4); w2(0xc);
-               w0(0x40); w2(6); w2(7); w2(4); w2(0xc); w2(4);
+
+       if (!epatc8) {
+               WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10);
        }
-       WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10);
-#endif
 }
 
 static void epat_disconnect (PIA *pi)
@@ -320,6 +324,9 @@ static struct pi_protocol epat = {
 
 static int __init epat_init(void)
 {
+#ifdef CONFIG_PARIDE_EPATC8
+       epatc8 = 1;
+#endif
        return pi_register(&epat)-1;
 }
 
index 1e430e5..b4a696e 100644 (file)
@@ -337,7 +337,7 @@ static int pf_open(struct inode *inode, struct file *file)
 static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
-       struct hd_geometry *geo = (struct hd_geometry *) arg;
+       struct hd_geometry __user *geo = (struct hd_geometry __user *) arg;
        struct hd_geometry g;
        sector_t capacity;
 
index 5ccc106..d73e3ec 100644 (file)
@@ -212,9 +212,9 @@ MODULE_PARM(drive3, "1-6i");
 
 static int pg_open(struct inode *inode, struct file *file);
 static int pg_release(struct inode *inode, struct file *file);
-static ssize_t pg_read(struct file *filp, char *buf,
+static ssize_t pg_read(struct file *filp, char __user *buf,
                       size_t count, loff_t * ppos);
-static ssize_t pg_write(struct file *filp, const char *buf,
+static ssize_t pg_write(struct file *filp, const char __user *buf,
                        size_t count, loff_t * ppos);
 static int pg_detect(void);
 
@@ -571,7 +571,7 @@ static int pg_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t pg_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
+static ssize_t pg_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
 {
        struct pg *dev = filp->private_data;
        struct pg_write_hdr hdr;
@@ -582,7 +582,7 @@ static ssize_t pg_write(struct file *filp, const char *buf, size_t count, loff_t
        if (count < hs)
                return -EINVAL;
 
-       if (copy_from_user((char *) &hdr, buf, hs))
+       if (copy_from_user(&hdr, buf, hs))
                return -EFAULT;
 
        if (hdr.magic != PG_MAGIC)
@@ -619,7 +619,7 @@ static ssize_t pg_write(struct file *filp, const char *buf, size_t count, loff_t
        return count;
 }
 
-static ssize_t pg_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
+static ssize_t pg_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
 {
        struct pg *dev = filp->private_data;
        struct pg_read_hdr hdr;
@@ -651,7 +651,7 @@ static ssize_t pg_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
        hdr.duration = (jiffies - dev->start + HZ / 2) / HZ;
        hdr.scsi = dev->status & 0x0f;
 
-       if (copy_to_user(buf, (char *) &hdr, hs))
+       if (copy_to_user(buf, &hdr, hs))
                return -EFAULT;
        if (copy > 0)
                if (copy_to_user(buf + hs, dev->bufptr, copy))
index 81c4690..44b1213 100644 (file)
@@ -212,9 +212,9 @@ static int pt_open(struct inode *inode, struct file *file);
 static int pt_ioctl(struct inode *inode, struct file *file,
                    unsigned int cmd, unsigned long arg);
 static int pt_release(struct inode *inode, struct file *file);
-static ssize_t pt_read(struct file *filp, char *buf,
+static ssize_t pt_read(struct file *filp, char __user *buf,
                       size_t count, loff_t * ppos);
-static ssize_t pt_write(struct file *filp, const char *buf,
+static ssize_t pt_write(struct file *filp, const char __user *buf,
                        size_t count, loff_t * ppos);
 static int pt_detect(void);
 
@@ -710,12 +710,12 @@ static int pt_ioctl(struct inode *inode, struct file *file,
         unsigned int cmd, unsigned long arg)
 {
        struct pt_unit *tape = file->private_data;
+       struct mtop __user *p = (void __user *)arg;
        struct mtop mtop;
 
        switch (cmd) {
        case MTIOCTOP:
-               if (copy_from_user((char *) &mtop, (char *) arg,
-                                  sizeof (struct mtop)))
+               if (copy_from_user(&mtop, p, sizeof(struct mtop)))
                        return -EFAULT;
 
                switch (mtop.mt_op) {
@@ -764,7 +764,7 @@ pt_release(struct inode *inode, struct file *file)
 
 }
 
-static ssize_t pt_read(struct file *filp, char *buf, size_t count, loff_t * ppos)
+static ssize_t pt_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
 {
        struct pt_unit *tape = filp->private_data;
        struct pi_adapter *pi = tape->pi;
@@ -861,7 +861,7 @@ static ssize_t pt_read(struct file *filp, char *buf, size_t count, loff_t * ppos
 
 }
 
-static ssize_t pt_write(struct file *filp, const char *buf, size_t count, loff_t * ppos)
+static ssize_t pt_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
 {
        struct pt_unit *tape = filp->private_data;
        struct pi_adapter *pi = tape->pi;
index 87b3240..82a5f19 100644 (file)
@@ -1063,17 +1063,17 @@ static int ps2esdi_ioctl(struct inode *inode,
                         struct file *file, u_int cmd, u_long arg)
 {
        struct ps2esdi_i_struct *p = inode->i_bdev->bd_disk->private_data;
-       struct ps2esdi_geometry *geometry = (struct ps2esdi_geometry *) arg;
-       int err;
+       struct ps2esdi_geometry geom;
 
        if (cmd != HDIO_GETGEO)
                return -EINVAL;
-       if ((err = verify_area(VERIFY_WRITE, geometry, sizeof(*geometry))))
-               return (err);
-       put_user(p->head, (char *) &geometry->heads);
-       put_user(p->sect, (char *) &geometry->sectors);
-       put_user(p->cyl, (short *) &geometry->cylinders);
-       put_user(get_start_sect(inode->i_bdev), (long *) &geometry->start);
+       memset(&geom, 0, sizeof(geom));
+       geom.heads = p->head;
+       geom.sectors = p->sect;
+       geom.cylinders = p->cyl;
+       geom.start = get_start_sect(inode->i_bdev);
+       if (copy_to_user((void __user *)arg, &geom, sizeof(geom)))
+               return -EFAULT;
        return 0;
 }
 
index 5566351..fe8332e 100644 (file)
@@ -108,8 +108,21 @@ static void make_page_uptodate(struct page *page)
                struct buffer_head *head = bh;
 
                do {
-                       if (!buffer_uptodate(bh))
+                       if (!buffer_uptodate(bh)) {
                                memset(bh->b_data, 0, bh->b_size);
+                               /*
+                                * akpm: I'm totally undecided about this.  The
+                                * buffer has just been magically brought "up to
+                                * date", but nobody should want to be reading
+                                * it anyway, because it hasn't been used for
+                                * anything yet.  It is still in a "not read
+                                * from disk yet" state.
+                                *
+                                * But non-uptodate buffers against an uptodate
+                                * page are against the rules.  So do it anyway.
+                                */
+                                set_buffer_uptodate(bh);
+                       }
                } while ((bh = bh->b_this_page) != head);
        } else {
                memset(page_address(page), 0, PAGE_CACHE_SIZE);
index f7488ae..2b126d8 100644 (file)
@@ -833,7 +833,7 @@ static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned
                geo.start     = get_start_sect(i->i_bdev);
                geo.cylinders = size / (geo.heads * geo.sectors);
 
-               if (copy_to_user((void *) arg, &geo, sizeof(geo)))
+               if (copy_to_user((void __user *) arg, &geo, sizeof(geo)))
                        return -EFAULT;
                return 0;
        }
index b4ae841..1fd72e0 100644 (file)
@@ -330,12 +330,12 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
                case HDIO_GETGEO:
                {
                        struct hd_geometry g;
-                       struct hd_geometry *geometry = (struct hd_geometry *) arg;
+                       struct hd_geometry __user *geom= (void __user *)arg;
                        g.heads = p->heads;
                        g.sectors = p->sectors;
                        g.cylinders = p->cylinders;
                        g.start = get_start_sect(inode->i_bdev);
-                       return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
+                       return copy_to_user(geom, &g, sizeof(g)) ? -EFAULT : 0;
                }
                case HDIO_SET_DMA:
                        if (!capable(CAP_SYS_ADMIN)) return -EACCES;
@@ -354,9 +354,9 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
                        }
                        return 0;
                case HDIO_GET_DMA:
-                       return put_user(!nodma, (long *) arg);
+                       return put_user(!nodma, (long __user *) arg);
                case HDIO_GET_MULTCOUNT:
-                       return put_user(xd_maxsectors, (long *) arg);
+                       return put_user(xd_maxsectors, (long __user *) arg);
                default:
                        return -EINVAL;
        }
index dda06e9..5ba1342 100644 (file)
@@ -498,11 +498,11 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
 /*
  * We don't provide read/write/poll interface for user space.
  */
-static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
+static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char __user *buf, size_t nr)
 {
        return 0;
 }
-static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
+static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char __user *data, size_t count)
 {
        return 0;
 }
index 871f383..9faa8a0 100644 (file)
@@ -127,7 +127,7 @@ static unsigned int hci_vhci_chr_poll(struct file *file, poll_table * wait)
 }
 
 /* Get packet from user space buffer(already verified) */
-static inline ssize_t hci_vhci_get_user(struct hci_vhci_struct *hci_vhci, const char *buf, size_t count)
+static inline ssize_t hci_vhci_get_user(struct hci_vhci_struct *hci_vhci, const char __user *buf, size_t count)
 {
        struct sk_buff *skb;
 
@@ -152,7 +152,7 @@ static inline ssize_t hci_vhci_get_user(struct hci_vhci_struct *hci_vhci, const
 } 
 
 /* Write */
-static ssize_t hci_vhci_chr_write(struct file * file, const char * buf, 
+static ssize_t hci_vhci_chr_write(struct file * file, const char __user * buf, 
                             size_t count, loff_t *pos)
 {
        struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
@@ -165,10 +165,11 @@ static ssize_t hci_vhci_chr_write(struct file * file, const char * buf,
 
 /* Put packet to user space buffer(already verified) */
 static inline ssize_t hci_vhci_put_user(struct hci_vhci_struct *hci_vhci,
-                                      struct sk_buff *skb, char *buf, int count)
+                                      struct sk_buff *skb, char __user *buf,
+                                      int count)
 {
        int len = count, total = 0;
-       char *ptr = buf;
+       char __user *ptr = buf;
 
        len = min_t(unsigned int, skb->len, len);
        if (copy_to_user(ptr, skb->data, len))
@@ -194,7 +195,7 @@ static inline ssize_t hci_vhci_put_user(struct hci_vhci_struct *hci_vhci,
 }
 
 /* Read */
-static ssize_t hci_vhci_chr_read(struct file * file, char * buf, size_t count, loff_t *pos)
+static ssize_t hci_vhci_chr_read(struct file * file, char __user * buf, size_t count, loff_t *pos)
 {
        struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
        DECLARE_WAITQUEUE(wait, current);
index 8308676..97ab1b3 100644 (file)
@@ -873,7 +873,7 @@ static int aztUpdateToc(void)
 /* Read the table of contents header, i.e. no. of tracks and start of first 
  * track
  */
-static int aztGetDiskInfo()
+static int aztGetDiskInfo(void)
 {
        int limit;
        unsigned char test;
@@ -1167,6 +1167,7 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
        struct azt_Toc *tocPtr;
        struct cdrom_subchnl subchnl;
        struct cdrom_volctrl volctrl;
+       void __user *argp = (void __user *)arg;
 
 #ifdef AZT_DEBUG
        printk("aztcd: starting aztcd_ioctl - Command:%x   Time: %li\n",
@@ -1230,8 +1231,7 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
 #ifdef AZT_DEBUG
                        printk("aztcd ioctl MULTISESSION\n");
 #endif
-                       if (copy_from_user
-                           (&ms, (void *) arg,
+                       if (copy_from_user(&ms, argp,
                             sizeof(struct cdrom_multisession)))
                                return -EFAULT;
                        if (ms.addr_format == CDROM_MSF) {
@@ -1248,8 +1248,7 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                        else
                                return -EINVAL;
                        ms.xa_flag = DiskInfo.xa;
-                       if (copy_to_user
-                           ((void *) arg, &ms,
+                       if (copy_to_user(argp, &ms,
                             sizeof(struct cdrom_multisession)))
                                return -EFAULT;
 #ifdef AZT_DEBUG
@@ -1272,7 +1271,7 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                        return 0;
                }
        case CDROMPLAYTRKIND:   /* Play a track.  This currently ignores index. */
-               if (copy_from_user(&ti, (void *) arg, sizeof ti))
+               if (copy_from_user(&ti, argp, sizeof ti))
                        return -EFAULT;
                if (ti.cdti_trk0 < DiskInfo.first
                    || ti.cdti_trk0 > DiskInfo.last
@@ -1303,7 +1302,7 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                  aztAudioStatus = CDROM_AUDIO_NO_STATUS;
                }
 */
-               if (copy_from_user(&msf, (void *) arg, sizeof msf))
+               if (copy_from_user(&msf, argp, sizeof msf))
                        return -EFAULT;
                /* convert to bcd */
                azt_bin2bcd(&msf.cdmsf_min0);
@@ -1335,11 +1334,11 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
        case CDROMREADTOCHDR:   /* Read the table of contents header */
                tocHdr.cdth_trk0 = DiskInfo.first;
                tocHdr.cdth_trk1 = DiskInfo.last;
-               if (copy_to_user((void *) arg, &tocHdr, sizeof tocHdr))
+               if (copy_to_user(argp, &tocHdr, sizeof tocHdr))
                        return -EFAULT;
                break;
        case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
-               if (copy_from_user(&entry, (void *) arg, sizeof entry))
+               if (copy_from_user(&entry, argp, sizeof entry))
                        return -EFAULT;
                if ((!aztTocUpToDate) || aztDiskChanged)
                        aztUpdateToc();
@@ -1365,12 +1364,12 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                } else {
                        return -EINVAL;
                }
-               if (copy_to_user((void *) arg, &entry, sizeof entry))
+               if (copy_to_user(argp, &entry, sizeof entry))
                        return -EFAULT;
                break;
        case CDROMSUBCHNL:      /* Get subchannel info */
                if (copy_from_user
-                   (&subchnl, (void *) arg, sizeof(struct cdrom_subchnl)))
+                   (&subchnl, argp, sizeof(struct cdrom_subchnl)))
                        return -EFAULT;
                if (aztGetQChannelInfo(&qInfo) < 0) {
 #ifdef AZT_DEBUG
@@ -1405,16 +1404,14 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                        subchnl.cdsc_reladdr.msf.frame =
                            azt_bcd2bin(qInfo.trackTime.frame);
                }
-               if (copy_to_user
-                   ((void *) arg, &subchnl, sizeof(struct cdrom_subchnl)))
+               if (copy_to_user(argp, &subchnl, sizeof(struct cdrom_subchnl)))
                        return -EFAULT;
                break;
        case CDROMVOLCTRL:      /* Volume control 
                                   * With my Aztech CD268-01A volume control does not work, I can only
                                   turn the channels on (any value !=0) or off (value==0). Maybe it
                                   works better with your drive */
-               if (copy_from_user
-                   (&volctrl, (char *) arg, sizeof(volctrl)))
+               if (copy_from_user(&volctrl, argp, sizeof(volctrl)))
                        return -EFAULT;
                azt_Play.start.min = 0x21;
                azt_Play.start.sec = 0x84;
@@ -1457,7 +1454,7 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
        case CDROMREADCOOKED:   /*read data in mode 1 (2048 Bytes) */
        case CDROMREADRAW:      /*read data in mode 2 (2336 Bytes) */
                {
-                       if (copy_from_user(&msf, (void *) arg, sizeof msf))
+                       if (copy_from_user(&msf, argp, sizeof msf))
                                return -EFAULT;
                        /* convert to bcd */
                        azt_bin2bcd(&msf.cdmsf_min0);
@@ -1476,16 +1473,11 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                                if (DiskInfo.xa) {
                                        return -1;      /*XA Disks can't be read raw */
                                } else {
-                                       if (sendAztCmd
-                                           (ACMD_PLAY_READ_RAW,
-                                            &azt_Play))
+                                       if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play))
                                                return -1;
                                        DTEN_LOW;
-                                       insb(DATA_PORT, buf,
-                                            CD_FRAMESIZE_RAW);
-                                       if (copy_to_user
-                                           ((void *) arg, &buf,
-                                            CD_FRAMESIZE_RAW))
+                                       insb(DATA_PORT, buf, CD_FRAMESIZE_RAW);
+                                       if (copy_to_user(argp, &buf, CD_FRAMESIZE_RAW))
                                                return -EFAULT;
                                }
                        } else
@@ -1494,14 +1486,13 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                                        return -1;
                                DTEN_LOW;
                                insb(DATA_PORT, buf, CD_FRAMESIZE);
-                               if (copy_to_user
-                                   ((void *) arg, &buf, CD_FRAMESIZE))
+                               if (copy_to_user(argp, &buf, CD_FRAMESIZE))
                                        return -EFAULT;
                                }
                }
                break;
        case CDROMSEEK: /*seek msf address */
-               if (copy_from_user(&msf, (void *) arg, sizeof msf))
+               if (copy_from_user(&msf, argp, sizeof msf))
                        return -EFAULT;
                /* convert to bcd */
                azt_bin2bcd(&msf.cdmsf_min0);
index 0186710..e4c1ae3 100644 (file)
@@ -508,6 +508,8 @@ int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write)
        unsigned char buffer[16];
        int ret;
 
+       *write = 0;
+
        init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
 
        cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
@@ -521,8 +523,10 @@ int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write)
        mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)];
        *write = mfd->write;
 
-       if ((ret = cdrom_mrw_probe_pc(cdi)))
+       if ((ret = cdrom_mrw_probe_pc(cdi))) {
+               *write = 0;
                return ret;
+       }
 
        return 0;
 }
@@ -651,7 +655,6 @@ int cdrom_get_random_writable(struct cdrom_device_info *cdi,
 {
        struct packet_command cgc;
        char buffer[24];
-       struct feature_header *fh;
        int ret;
 
        init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
@@ -664,14 +667,7 @@ int cdrom_get_random_writable(struct cdrom_device_info *cdi,
        if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
                return ret;
 
-       fh = (struct feature_header *)&buffer[0];
-       if (be32_to_cpu(fh->data_len) >= (sizeof(struct feature_header)+
-                                         sizeof(struct rwrt_feature_desc)))
-               memcpy(rfd, &buffer[sizeof(struct feature_header)],
-                      sizeof (*rfd));
-       else
-               memset(rfd, 0, sizeof(*rfd));
-
+       memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd));
        return 0;
 }
 
@@ -679,28 +675,24 @@ int cdrom_has_defect_mgt(struct cdrom_device_info *cdi)
 {
        struct packet_command cgc;
        char buffer[16];
-       struct feature_header *fh;
        __u16 *feature_code;
        int ret;
 
        init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
 
-       cgc.cmd[0] = GPCMD_GET_CONFIGURATION;   /* often 0x46 */
-       cgc.cmd[3] = CDF_HWDM;                  /* often 0x0024 */
-       cgc.cmd[8] = sizeof(buffer);            /* often 0x10 */
+       cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
+       cgc.cmd[3] = CDF_HWDM;
+       cgc.cmd[8] = sizeof(buffer);
        cgc.quiet = 1;
 
        if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
                return ret;
 
-       fh = (struct feature_header *)&buffer[0];
-       ret = 1;
-       if (be32_to_cpu(fh->data_len) >= (sizeof(struct feature_header)+8)) {
-               feature_code = (__u16 *)&buffer[sizeof(struct feature_header)];
-               if (CDF_HWDM == be16_to_cpu(*feature_code))
-                       ret = 0;
-       }
-       return ret;
+       feature_code = (__u16 *) &buffer[sizeof(struct feature_header)];
+       if (be16_to_cpu(*feature_code) == CDF_HWDM)
+               return 0;
+
+       return 1;
 }
 
 
@@ -834,8 +826,30 @@ static int cdrom_ram_open_write(struct cdrom_device_info *cdi)
  */
 static int cdrom_open_write(struct cdrom_device_info *cdi)
 {
+       int mrw, mrw_write, ram_write;
        int ret = 1;
 
+       mrw = 0;
+       if (!cdrom_is_mrw(cdi, &mrw_write))
+               mrw = 1;
+
+       (void) cdrom_is_random_writable(cdi, &ram_write);
+
+       if (mrw)
+               cdi->mask &= ~CDC_MRW;
+       else
+               cdi->mask |= CDC_MRW;
+
+       if (mrw_write)
+               cdi->mask &= ~CDC_MRW_W;
+       else
+               cdi->mask |= CDC_MRW_W;
+
+       if (ram_write)
+               cdi->mask &= ~CDC_RAM;
+       else
+               cdi->mask |= CDC_RAM;
+
        if (CDROM_CAN(CDC_MRW_W))
                ret = cdrom_mrw_open_write(cdi);
        else if (CDROM_CAN(CDC_DVD_RAM))
@@ -878,6 +892,9 @@ int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp)
        if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) {
                ret = cdi->ops->open(cdi, 1);
        } else {
+               ret = open_for_data(cdi);
+               if (ret)
+                       goto err;
                if (fp->f_mode & FMODE_WRITE) {
                        ret = -EROFS;
                        if (!CDROM_CAN(CDC_RAM))
@@ -885,7 +902,6 @@ int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp)
                        if (cdrom_open_write(cdi))
                                goto err;
                }
-               ret = open_for_data(cdi);
        }
 
        if (ret)
index 4b38349..3a758a0 100644 (file)
@@ -2595,11 +2595,10 @@ static int read_audio(struct cdrom_read_audio *ra)
                                                retval = -EIO;
                                                goto exit_read_audio;
                                        }
-                               } else if (copy_to_user((char *)(ra->buf +
+                               } else if (copy_to_user(ra->buf +
                                                               (CD_FRAMESIZE_RAW
-                                                               * cframe)),
-                                                       (char *)
-                                                              readahead_buffer,
+                                                               * cframe),
+                                                       readahead_buffer,
                                                        CD_FRAMESIZE_RAW)) {
                                        retval = -EFAULT;
                                        goto exit_read_audio;
@@ -2612,8 +2611,7 @@ static int read_audio(struct cdrom_read_audio *ra)
                                retval = -EIO;
                                goto exit_read_audio;
                        }
-               } else if (copy_to_user((char *)(ra->buf + (CD_FRAMESIZE_RAW *
-                                                           cframe)),
+               } else if (copy_to_user(ra->buf + (CD_FRAMESIZE_RAW * cframe),
                                        (char *)readahead_buffer,
                                        CD_FRAMESIZE_RAW)) {
                        retval = -EFAULT;
@@ -2945,6 +2943,7 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi,
 static int scd_dev_ioctl(struct cdrom_device_info *cdi,
                         unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
        int i;
 
        switch (cmd) {
@@ -2959,7 +2958,7 @@ static int scd_dev_ioctl(struct cdrom_device_info *cdi,
                                return -EIO;
                        }
 
-                       if (copy_from_user(&ra, (char *) arg, sizeof(ra)))
+                       if (copy_from_user(&ra, argp, sizeof(ra)))
                                return -EFAULT;
 
                        if (ra.nframes == 0) {
index 7e9758f..62e2d11 100644 (file)
@@ -1440,12 +1440,12 @@ static int cdromresume(void)
 }
 
 
-static int cdromplaymsf(unsigned long arg)
+static int cdromplaymsf(void __user *arg)
 {
        int status;
        struct cdrom_msf msf;
 
-       if (copy_from_user(&msf, (void *) arg, sizeof msf))
+       if (copy_from_user(&msf, arg, sizeof msf))
                return -EFAULT;
 
        bin2bcd(&msf);
@@ -1461,13 +1461,13 @@ static int cdromplaymsf(unsigned long arg)
 }
 
 
-static int cdromplaytrkind(unsigned long arg)
+static int cdromplaytrkind(void __user *arg)
 {
        int status;
        struct cdrom_ti ti;
        struct cdrom_msf msf;
 
-       if (copy_from_user(&ti, (void *) arg, sizeof ti))
+       if (copy_from_user(&ti, arg, sizeof ti))
                return -EFAULT;
 
        if (ti.cdti_trk0 < disk_info.first
@@ -1505,23 +1505,23 @@ static int cdromplaytrkind(unsigned long arg)
 }
 
 
-static int cdromreadtochdr(unsigned long arg)
+static int cdromreadtochdr(void __user *arg)
 {
        struct cdrom_tochdr tochdr;
 
        tochdr.cdth_trk0 = disk_info.first;
        tochdr.cdth_trk1 = disk_info.last;
 
-       return copy_to_user((void *)arg, &tochdr, sizeof tochdr) ? -EFAULT : 0;
+       return copy_to_user(arg, &tochdr, sizeof tochdr) ? -EFAULT : 0;
 }
 
 
-static int cdromreadtocentry(unsigned long arg)
+static int cdromreadtocentry(void __user *arg)
 {
        struct cdrom_tocentry entry;
        struct cdrom_subchnl *tocptr;
 
-       if (copy_from_user(&entry, (void *) arg, sizeof entry))
+       if (copy_from_user(&entry, arg, sizeof entry))
                return -EFAULT;
 
        if (entry.cdte_track == CDROM_LEADOUT)
@@ -1544,17 +1544,17 @@ static int cdromreadtocentry(unsigned long arg)
        else if (entry.cdte_format != CDROM_MSF)
                return -EINVAL;
 
-       return copy_to_user((void *)arg, &entry, sizeof entry) ? -EFAULT : 0;
+       return copy_to_user(arg, &entry, sizeof entry) ? -EFAULT : 0;
 }
 
 
-static int cdromvolctrl(unsigned long arg)
+static int cdromvolctrl(void __user *arg)
 {
        int status;
        struct cdrom_volctrl volctrl;
        struct cdrom_msf msf;
 
-       if (copy_from_user(&volctrl, (char *) arg, sizeof volctrl))
+       if (copy_from_user(&volctrl, arg, sizeof volctrl))
                return -EFAULT;
 
        msf.cdmsf_min0 = 0x10;
@@ -1573,12 +1573,12 @@ static int cdromvolctrl(unsigned long arg)
 }
 
 
-static int cdromsubchnl(unsigned long arg)
+static int cdromsubchnl(void __user *arg)
 {
        int status;
        struct cdrom_subchnl subchnl;
 
-       if (copy_from_user(&subchnl, (void *) arg, sizeof subchnl))
+       if (copy_from_user(&subchnl, arg, sizeof subchnl))
                return -EFAULT;
 
        if (subchnl.cdsc_format != CDROM_LBA
@@ -1591,7 +1591,7 @@ static int cdromsubchnl(unsigned long arg)
                return -EIO;
        }
 
-       if (copy_to_user((void *)arg, &subchnl, sizeof subchnl))
+       if (copy_to_user(arg, &subchnl, sizeof subchnl))
                return -EFAULT;
        return 0;
 }
@@ -1600,12 +1600,12 @@ static int cdromsubchnl(unsigned long arg)
 static struct gendisk *optcd_disk;
 
 
-static int cdromread(unsigned long arg, int blocksize, int cmd)
+static int cdromread(void __user *arg, int blocksize, int cmd)
 {
        int status;
        struct cdrom_msf msf;
 
-       if (copy_from_user(&msf, (void *) arg, sizeof msf))
+       if (copy_from_user(&msf, arg, sizeof msf))
                return -EFAULT;
 
        bin2bcd(&msf);
@@ -1621,19 +1621,19 @@ static int cdromread(unsigned long arg, int blocksize, int cmd)
 
        fetch_data(optcd_disk->private_data, blocksize);
 
-       if (copy_to_user((void *)arg, optcd_disk->private_data, blocksize))
+       if (copy_to_user(arg, optcd_disk->private_data, blocksize))
                return -EFAULT;
 
        return 0;
 }
 
 
-static int cdromseek(unsigned long arg)
+static int cdromseek(void __user *arg)
 {
        int status;
        struct cdrom_msf msf;
 
-       if (copy_from_user(&msf, (void *)arg, sizeof msf))
+       if (copy_from_user(&msf, arg, sizeof msf))
                return -EFAULT;
 
        bin2bcd(&msf);
@@ -1648,11 +1648,11 @@ static int cdromseek(unsigned long arg)
 
 
 #ifdef MULTISESSION
-static int cdrommultisession(unsigned long arg)
+static int cdrommultisession(void __user *arg)
 {
        struct cdrom_multisession ms;
 
-       if (copy_from_user(&ms, (void*) arg, sizeof ms))
+       if (copy_from_user(&ms, arg, sizeof ms))
                return -EFAULT;
 
        ms.addr.msf.minute = disk_info.last_session.minute;
@@ -1667,7 +1667,7 @@ static int cdrommultisession(unsigned long arg)
 
        ms.xa_flag = disk_info.xa;
 
-       if (copy_to_user((void *)arg, &ms, sizeof(struct cdrom_multisession)))
+       if (copy_to_user(arg, &ms, sizeof(struct cdrom_multisession)))
                return -EFAULT;
 
 #if DEBUG_MULTIS
@@ -1717,6 +1717,7 @@ static int opt_ioctl(struct inode *ip, struct file *fp,
                      unsigned int cmd, unsigned long arg)
 {
        int status, err, retval = 0;
+       void __user *argp = (void __user *)arg;
 
        DEBUG((DEBUG_VFS, "starting opt_ioctl"));
 
@@ -1767,10 +1768,10 @@ static int opt_ioctl(struct inode *ip, struct file *fp,
        switch (cmd) {
        case CDROMPAUSE:        retval = cdrompause(); break;
        case CDROMRESUME:       retval = cdromresume(); break;
-       case CDROMPLAYMSF:      retval = cdromplaymsf(arg); break;
-       case CDROMPLAYTRKIND:   retval = cdromplaytrkind(arg); break;
-       case CDROMREADTOCHDR:   retval = cdromreadtochdr(arg); break;
-       case CDROMREADTOCENTRY: retval = cdromreadtocentry(arg); break;
+       case CDROMPLAYMSF:      retval = cdromplaymsf(argp); break;
+       case CDROMPLAYTRKIND:   retval = cdromplaytrkind(argp); break;
+       case CDROMREADTOCHDR:   retval = cdromreadtochdr(argp); break;
+       case CDROMREADTOCENTRY: retval = cdromreadtocentry(argp); break;
 
        case CDROMSTOP:         err = exec_cmd(COMSTOP);
                                if (err < 0) {
@@ -1799,8 +1800,8 @@ static int opt_ioctl(struct inode *ip, struct file *fp,
                                }
                                break;
 
-       case CDROMVOLCTRL:      retval = cdromvolctrl(arg); break;
-       case CDROMSUBCHNL:      retval = cdromsubchnl(arg); break;
+       case CDROMVOLCTRL:      retval = cdromvolctrl(argp); break;
+       case CDROMSUBCHNL:      retval = cdromsubchnl(argp); break;
 
        /* The drive detects the mode and automatically delivers the
           correct 2048 bytes, so we don't need these IOCTLs */
@@ -1814,7 +1815,7 @@ static int opt_ioctl(struct inode *ip, struct file *fp,
                                break;
 
 #ifdef MULTISESSION
-       case CDROMMULTISESSION: retval = cdrommultisession(arg); break;
+       case CDROMMULTISESSION: retval = cdrommultisession(argp); break;
 #endif
 
        case CDROM_GET_MCN:     retval = -EINVAL; break; /* not implemented */
@@ -1822,16 +1823,16 @@ static int opt_ioctl(struct inode *ip, struct file *fp,
 
        case CDROMREADRAW:
                        /* this drive delivers 2340 bytes in raw mode */
-                       retval = cdromread(arg, CD_FRAMESIZE_RAW1, COMREADRAW);
+                       retval = cdromread(argp, CD_FRAMESIZE_RAW1, COMREADRAW);
                        break;
        case CDROMREADCOOKED:
-                       retval = cdromread(arg, CD_FRAMESIZE, COMREAD);
+                       retval = cdromread(argp, CD_FRAMESIZE, COMREAD);
                        break;
        case CDROMREADALL:
-                       retval = cdromread(arg, CD_FRAMESIZE_RAWER, COMREADALL);
+                       retval = cdromread(argp, CD_FRAMESIZE_RAWER, COMREADALL);
                        break;
 
-       case CDROMSEEK:         retval = cdromseek(arg); break;
+       case CDROMSEEK:         retval = cdromseek(argp); break;
        case CDROMPLAYBLK:      retval = -EINVAL; break; /* not implemented */
        case CDROMCLOSETRAY:    break;  /* The action was taken earlier */
        default:                retval = -EINVAL;
index 8108878..0e60b5c 100644 (file)
@@ -716,13 +716,11 @@ static int sjcd_tray_open(void)
 static int sjcd_ioctl(struct inode *ip, struct file *fp,
                      unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
 #if defined( SJCD_TRACE )
        printk("SJCD:ioctl\n");
 #endif
 
-       if (ip == NULL)
-               return (-EINVAL);
-
        sjcd_get_status();
        if (!sjcd_status_valid)
                return (-EIO);
@@ -795,7 +793,7 @@ static int sjcd_ioctl(struct inode *ip, struct file *fp,
 #if defined( SJCD_TRACE )
                        printk("SJCD: ioctl: playtrkind\n");
 #endif
-                       if (!copy_from_user(&ti, (void *) arg, sizeof(ti))) {
+                       if (!copy_from_user(&ti, argp, sizeof(ti))) {
                                s = 0;
                                if (ti.cdti_trk0 < sjcd_first_track_no)
                                        return (-EINVAL);
@@ -833,7 +831,7 @@ static int sjcd_ioctl(struct inode *ip, struct file *fp,
                        printk("SJCD: ioctl: playmsf\n");
 #endif
                        if ((s =
-                            verify_area(VERIFY_READ, (void *) arg,
+                            verify_area(VERIFY_READ, argp,
                                         sizeof(sjcd_msf))) == 0) {
                                if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
                                        sjcd_send_cmd(SCMD_PAUSE);
@@ -842,7 +840,7 @@ static int sjcd_ioctl(struct inode *ip, struct file *fp,
                                            CDROM_AUDIO_NO_STATUS;
                                }
 
-                               if (copy_from_user(&sjcd_msf, (void *) arg,
+                               if (copy_from_user(&sjcd_msf, argp,
                                               sizeof(sjcd_msf)))
                                        return (-EFAULT);
 
@@ -877,7 +875,7 @@ static int sjcd_ioctl(struct inode *ip, struct file *fp,
 #endif
                        toc_header.cdth_trk0 = sjcd_first_track_no;
                        toc_header.cdth_trk1 = sjcd_last_track_no;
-                       if (copy_to_user((void *)arg, &toc_header,
+                       if (copy_to_user(argp, &toc_header,
                                         sizeof(toc_header)))
                                return -EFAULT;
                        return 0;
@@ -890,11 +888,11 @@ static int sjcd_ioctl(struct inode *ip, struct file *fp,
                        printk("SJCD: ioctl: readtocentry\n");
 #endif
                        if ((s =
-                            verify_area(VERIFY_WRITE, (void *) arg,
+                            verify_area(VERIFY_WRITE, argp,
                                         sizeof(toc_entry))) == 0) {
                                struct sjcd_hw_disk_info *tp;
 
-                               if (copy_from_user(&toc_entry, (void *) arg,
+                               if (copy_from_user(&toc_entry, argp,
                                               sizeof(toc_entry)))
                                        return (-EFAULT);
                                if (toc_entry.cdte_track == CDROM_LEADOUT)
@@ -931,7 +929,7 @@ static int sjcd_ioctl(struct inode *ip, struct file *fp,
                                default:
                                        return (-EINVAL);
                                }
-                               if (copy_to_user((void *) arg, &toc_entry,
+                               if (copy_to_user(argp, &toc_entry,
                                                 sizeof(toc_entry)))
                                        s = -EFAULT;
                        }
@@ -945,11 +943,11 @@ static int sjcd_ioctl(struct inode *ip, struct file *fp,
                        printk("SJCD: ioctl: subchnl\n");
 #endif
                        if ((s =
-                            verify_area(VERIFY_WRITE, (void *) arg,
+                            verify_area(VERIFY_WRITE, argp,
                                         sizeof(subchnl))) == 0) {
                                struct sjcd_hw_qinfo q_info;
 
-                               if (copy_from_user(&subchnl, (void *) arg,
+                               if (copy_from_user(&subchnl, argp,
                                               sizeof(subchnl)))
                                        return (-EFAULT);
 
@@ -990,7 +988,7 @@ static int sjcd_ioctl(struct inode *ip, struct file *fp,
                                default:
                                        return (-EINVAL);
                                }
-                               if (copy_to_user((void *) arg, &subchnl,
+                               if (copy_to_user(argp, &subchnl,
                                                 sizeof(subchnl)))
                                        s = -EFAULT;
                        }
@@ -1004,11 +1002,11 @@ static int sjcd_ioctl(struct inode *ip, struct file *fp,
                        printk("SJCD: ioctl: volctrl\n");
 #endif
                        if ((s =
-                            verify_area(VERIFY_READ, (void *) arg,
+                            verify_area(VERIFY_READ, argp,
                                         sizeof(vol_ctrl))) == 0) {
                                unsigned char dummy[4];
 
-                               if (copy_from_user(&vol_ctrl, (void *) arg,
+                               if (copy_from_user(&vol_ctrl, argp,
                                               sizeof(vol_ctrl)))
                                        return (-EFAULT);
                                sjcd_send_4_cmd(SCMD_SET_VOLUME,
@@ -1038,8 +1036,7 @@ static int sjcd_ioctl(struct inode *ip, struct file *fp,
 #if defined( SJCD_TRACE )
                        printk("SJCD: ioctl: statistic\n");
 #endif
-                       if (copy_to_user((void *)arg, &statistic,
-                                        sizeof(statistic)))
+                       if (copy_to_user(argp, &statistic, sizeof(statistic)))
                                return -EFAULT;
                        return 0;
                }
index 1d55bf8..a0c9c8d 100644 (file)
@@ -997,7 +997,7 @@ read_subcode(void)
  * (not BCD), so all the conversions are done.
  */
 static int
-sony_get_subchnl_info(long arg)
+sony_get_subchnl_info(void __user *arg)
 {
        struct cdrom_subchnl schi;
 
@@ -1009,7 +1009,7 @@ sony_get_subchnl_info(long arg)
        if (!sony_toc_read) {
                return -EIO;
        }
-       if (copy_from_user(&schi, (char *)arg, sizeof schi))
+       if (copy_from_user(&schi, arg, sizeof schi))
                return -EFAULT;
 
        switch (sony_audio_status) {
@@ -1025,7 +1025,7 @@ sony_get_subchnl_info(long arg)
 
        case CDROM_AUDIO_NO_STATUS:
                schi.cdsc_audiostatus = sony_audio_status;
-               if (copy_to_user((char *)arg, &schi, sizeof schi))
+               if (copy_to_user(arg, &schi, sizeof schi))
                        return -EFAULT;
                return 0;
                break;
@@ -1053,7 +1053,7 @@ sony_get_subchnl_info(long arg)
                schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode->abs_msf);
                schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode->rel_msf);
        }
-       return copy_to_user((char *)arg, &schi, sizeof schi) ? -EFAULT : 0;
+       return copy_to_user(arg, &schi, sizeof schi) ? -EFAULT : 0;
 }
 
 
@@ -1070,6 +1070,7 @@ cdu_ioctl(struct inode *inode,
        Byte cmd_buff[10], params[10];
        int  i;
        int  dsc_status;
+       void __user *argp = (void __user *)arg;
 
        if (check_drive_status() != 0)
                return -EIO;
@@ -1152,7 +1153,7 @@ cdu_ioctl(struct inode *inode,
                break;
 
        case CDROMPLAYMSF:                      /* Play starting at the given MSF address. */
-               if (copy_from_user(params, (void *)arg, 6))
+               if (copy_from_user(params, argp, 6))
                        return -EFAULT;
                spin_up_drive(status);
                set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
@@ -1184,13 +1185,12 @@ cdu_ioctl(struct inode *inode,
 
        case CDROMREADTOCHDR:           /* Read the table of contents header */
                {
-                       struct cdrom_tochdr *hdr;
+                       struct cdrom_tochdr __user *hdr = argp;
                        struct cdrom_tochdr loc_hdr;
 
                        sony_get_toc();
                        if (!sony_toc_read)
                                return -EIO;
-                       hdr = (struct cdrom_tochdr *)arg;
                        loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
                        loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
                        if (copy_to_user(hdr, &loc_hdr, sizeof *hdr))
@@ -1201,7 +1201,7 @@ cdu_ioctl(struct inode *inode,
 
        case CDROMREADTOCENTRY: /* Read a given table of contents entry */
                {
-                       struct cdrom_tocentry *entry;
+                       struct cdrom_tocentry __user *entry = argp;
                        struct cdrom_tocentry loc_entry;
                        int  track_idx;
                        Byte *msf_val = NULL;
@@ -1210,7 +1210,6 @@ cdu_ioctl(struct inode *inode,
                        if (!sony_toc_read) {
                                return -EIO;
                        }
-                       entry = (struct cdrom_tocentry *)arg;
 
                        if (copy_from_user(&loc_entry, entry, sizeof loc_entry))
                                return -EFAULT;
@@ -1252,7 +1251,7 @@ cdu_ioctl(struct inode *inode,
                        if (!sony_toc_read)
                                return -EIO;
 
-                       if (copy_from_user(&ti, (char *)arg, sizeof ti))
+                       if (copy_from_user(&ti, argp, sizeof ti))
                                return -EFAULT;
                        if ((ti.cdti_trk0 < sony_toc->first_track_num)
                                || (sony_toc->last_track_num < ti.cdti_trk0)
@@ -1314,14 +1313,13 @@ cdu_ioctl(struct inode *inode,
                }
 
        case CDROMSUBCHNL:                      /* Get subchannel info */
-               return sony_get_subchnl_info(arg);
+               return sony_get_subchnl_info(argp);
 
        case CDROMVOLCTRL:                      /* Volume control.  What volume does this change, anyway? */
                {
                        struct cdrom_volctrl volctrl;
 
-                       if (copy_from_user(&volctrl, (char *)arg,
-                                          sizeof volctrl))
+                       if (copy_from_user(&volctrl, argp, sizeof volctrl))
                                return -EFAULT;
                        cmd_buff[0] = SONY535_SET_VOLUME;
                        cmd_buff[1] = volctrl.channel0;
index 341348f..ee88dfc 100644 (file)
@@ -588,17 +588,6 @@ config HVC_CONSOLE
          console. This driver allows each pSeries partition to have a console
          which is accessed via the HMC.
 
-config PC9800_OLDLP
-       tristate "NEC PC-9800 old-style printer port support"
-       depends on X86_PC9800 && !PARPORT
-       ---help---
-         If you intend to attach a printer to the parallel port of NEC PC-9801
-         /PC-9821 with OLD compatibility mode, Say Y.
-
-config PC9800_OLDLP_CONSOLE
-       bool "Support for console on line printer"
-       depends on PC9800_OLDLP
-
 config QIC02_TAPE
        tristate "QIC-02 tape support"
        help
@@ -742,7 +731,7 @@ config NVRAM
 
 config RTC
        tristate "Enhanced Real Time Clock Support"
-       depends on !PPC32 && !PARISC && !IA64 && !X86_PC9800 && !M68K
+       depends on !PPC32 && !PARISC && !IA64 && !M68K
        ---help---
          If you say Y here and create a character special file /dev/rtc with
          major number 10 and minor number 135 using mknod ("man mknod"), you
@@ -795,15 +784,6 @@ config EFI_RTC
        bool "EFI Real Time Clock Services"
        depends on IA64
 
-config RTC98
-       tristate "NEC PC-9800 Real Time Clock Support"
-       depends on X86_PC9800
-       default y
-       ---help---
-         If you say Y here and create a character special file /dev/rtc with
-         major number 10 and minor number 135 using mknod ("man mknod"), you
-         will get access to the real time clock (or hardware clock) built
-
 config H8
        bool "Tadpole ANA H8 Support (OBSOLETE)"
        depends on OBSOLETE && ALPHA_BOOK1
@@ -959,6 +939,33 @@ config RAW_DRIVER
           kernels.  Applications should simply open the device (eg /dev/hda1)
           with the O_DIRECT flag.
 
+config HPET
+       bool "HPET - High Precision Event Timer" if (X86 || IA64)
+       default n
+       depends on ACPI
+       help
+         If you say Y here, you will have a device named "/dev/hpet/XX" for
+         each timer supported by the HPET.  The timers are
+         non-periodioc and/or periodic.
+
+config HPET_RTC_IRQ
+       bool "HPET Control RTC IRQ" if !HPET_EMULATE_RTC
+       default n
+       depends on HPET
+       help
+         If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It
+         is assumed the platform called hpet_alloc with the RTC IRQ values for
+         the HPET timers.
+
+config HPET_NOMMAP
+       bool "HPET - Control mmap capability."
+       default n
+       depends on HPET
+       help
+         If you say Y here, then the mmap interface for the HPET driver returns ENOSYS.
+         Some hardware implementations might not want all the memory in the page the
+         HPET control registers reside to be exposed.
+
 config MAX_RAW_DEVS
        int "Maximum number of RAW devices to support (1-8192)"
        depends on RAW_DRIVER
index 53439fc..8d46de3 100644 (file)
@@ -47,13 +47,13 @@ obj-$(CONFIG_VIOTAPE)               += viotape.o
 
 obj-$(CONFIG_PRINTER) += lp.o
 obj-$(CONFIG_TIPAR) += tipar.o
-obj-$(CONFIG_PC9800_OLDLP) += lp_old98.o
 
 obj-$(CONFIG_DTLK) += dtlk.o
 obj-$(CONFIG_R3964) += n_r3964.o
 obj-$(CONFIG_APPLICOM) += applicom.o
 obj-$(CONFIG_SONYPI) += sonypi.o
 obj-$(CONFIG_RTC) += rtc.o
+obj-$(CONFIG_HPET) += hpet.o
 obj-$(CONFIG_GEN_RTC) += genrtc.o
 obj-$(CONFIG_EFI_RTC) += efirtc.o
 ifeq ($(CONFIG_GENERIC_NVRAM),y)
index 4d4eaf2..0b2c40e 100644 (file)
@@ -105,8 +105,8 @@ static unsigned int WriteErrorCount;        /* number of write error      */
 static unsigned int ReadErrorCount;    /* number of read error       */
 static unsigned int DeviceErrorCount;  /* number of device error     */
 
-static ssize_t ac_read (struct file *, char *, size_t, loff_t *);
-static ssize_t ac_write (struct file *, const char *, size_t, loff_t *);
+static ssize_t ac_read (struct file *, char __user *, size_t, loff_t *);
+static ssize_t ac_write (struct file *, const char __user *, size_t, loff_t *);
 static int ac_ioctl(struct inode *, struct file *, unsigned int,
                    unsigned long);
 static irqreturn_t ac_interrupt(int, void *, struct pt_regs *);
@@ -343,7 +343,7 @@ int __init applicom_init(void)
 __initcall(applicom_init);
 #endif
 
-static ssize_t ac_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ac_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
 {
        unsigned int NumCard;   /* Board number 1 -> 8           */
        unsigned int IndexCard; /* Index board number 0 -> 7     */
@@ -467,7 +467,7 @@ static ssize_t ac_write(struct file *file, const char *buf, size_t count, loff_t
        return 0;
 }
 
-static int do_ac_read(int IndexCard, char *buf,
+static int do_ac_read(int IndexCard, char __user *buf,
                struct st_ram_io *st_loc, struct mailbox *mailbox)
 {
        unsigned long from = (unsigned long)apbs[IndexCard].RamIO + RAM_TO_PC;
@@ -521,7 +521,7 @@ static int do_ac_read(int IndexCard, char *buf,
        return (sizeof(struct st_ram_io) + sizeof(struct mailbox));
 }
 
-static ssize_t ac_read (struct file *filp, char *buf, size_t count, loff_t *ptr)
+static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_t *ptr)
 {
        unsigned long flags;
        unsigned int i;
@@ -689,6 +689,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
        int ret = 0;
        volatile unsigned char byte_reset_it;
        struct st_ram_io *adgl;
+       void __user *argp = (void __user *)arg;
 
        /* In general, the device is only openable by root anyway, so we're not
           particularly concerned that bogus ioctls can flood the console. */
@@ -697,7 +698,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
        if (!adgl)
                return -ENOMEM;
 
-       if (copy_from_user(adgl, (void *)arg,sizeof(struct st_ram_io))) {
+       if (copy_from_user(adgl, argp, sizeof(struct st_ram_io))) {
                kfree(adgl);
                return -EFAULT;
        }
@@ -721,7 +722,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                pmem = apbs[IndexCard].RamIO;
                for (i = 0; i < sizeof(struct st_ram_io); i++)
                        ((unsigned char *)adgl)[i]=readb(pmem++);
-               if (copy_to_user((void *)arg, adgl, sizeof(struct st_ram_io)))
+               if (copy_to_user(argp, adgl, sizeof(struct st_ram_io)))
                        ret = -EFAULT;
                break;
        case 1:
@@ -742,7 +743,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        (readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 1) << 8) + 
                        (readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 2) );
 
-               if (copy_to_user((void *)arg, adgl, sizeof(struct st_ram_io)))
+               if (copy_to_user(argp, adgl, sizeof(struct st_ram_io)))
                        ret = -EFAULT;
                break;
        case 2:
@@ -768,7 +769,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                pmem = apbs[IndexCard].RamIO + TIC_OWNER_TO_PC;
                adgl->tic_owner_to_pc     = readb(pmem++);
                adgl->numcard_owner_to_pc = readb(pmem);
-               if (copy_to_user((void *)arg, adgl,sizeof(struct st_ram_io)))
+               if (copy_to_user(argp, adgl,sizeof(struct st_ram_io)))
                        ret = -EFAULT;
                break;
        case 5:
index 48ae91c..85f5964 100644 (file)
@@ -676,8 +676,6 @@ static char rcsid[] =
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
 
-#define cy_put_user    put_user
-
 static void cy_throttle (struct tty_struct *tty);
 static void cy_send_xchar (struct tty_struct *tty, char ch);
 
@@ -3536,7 +3534,7 @@ set_line_char(struct cyclades_port * info)
 
 static int
 get_serial_info(struct cyclades_port * info,
-                           struct serial_struct * retinfo)
+                           struct serial_struct __user * retinfo)
 {
   struct serial_struct tmp;
   struct cyclades_card *cinfo = &cy_card[info->card];
@@ -3559,7 +3557,7 @@ get_serial_info(struct cyclades_port * info,
 
 static int
 set_serial_info(struct cyclades_port * info,
-                           struct serial_struct * new_info)
+                           struct serial_struct __user * new_info)
 {
   struct serial_struct new_serial;
   struct cyclades_port old_info;
@@ -3613,7 +3611,7 @@ check_and_exit:
  *         transmit holding register is empty.  This functionality
  *         allows an RS485 driver to be written in user space.
  */
-static int get_lsr_info(struct cyclades_port *info, unsigned int *value)
+static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value)
 {
     int card, chip, channel, index;
     unsigned char status;
@@ -3638,7 +3636,7 @@ static int get_lsr_info(struct cyclades_port *info, unsigned int *value)
        /* Not supported yet */
        return -EINVAL;
     }
-    return cy_put_user(result, (unsigned long *) value);
+    return put_user(result, (unsigned long __user *) value);
 }
 
 static int
@@ -3916,7 +3914,7 @@ cy_break(struct tty_struct *tty, int break_state)
 } /* cy_break */
 
 static int
-get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon)
+get_mon_info(struct cyclades_port * info, struct cyclades_monitor __user * mon)
 {
 
     if(copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
@@ -3961,7 +3959,7 @@ set_threshold(struct cyclades_port * info, unsigned long value)
 
 
 static int
-get_threshold(struct cyclades_port * info, unsigned long *value)
+get_threshold(struct cyclades_port * info, unsigned long __user *value)
 {
   unsigned char *base_addr;
   int card,channel,chip,index;
@@ -3978,7 +3976,7 @@ get_threshold(struct cyclades_port * info, unsigned long *value)
                       + (cy_chip_offset[chip]<<index));
 
        tmp = cy_readb(base_addr+(CyCOR3<<index)) & CyREC_FIFO;
-       return cy_put_user(tmp,value);
+       return put_user(tmp,value);
     } else {
        // Nothing to do!
        return 0;
@@ -3995,9 +3993,9 @@ set_default_threshold(struct cyclades_port * info, unsigned long value)
 
 
 static int
-get_default_threshold(struct cyclades_port * info, unsigned long *value)
+get_default_threshold(struct cyclades_port * info, unsigned long __user *value)
 {
-    return cy_put_user(info->default_threshold,value);
+    return put_user(info->default_threshold,value);
 }/* get_default_threshold */
 
 
@@ -4029,7 +4027,7 @@ set_timeout(struct cyclades_port * info, unsigned long value)
 
 
 static int
-get_timeout(struct cyclades_port * info, unsigned long *value)
+get_timeout(struct cyclades_port * info, unsigned long __user *value)
 {
   unsigned char *base_addr;
   int card,channel,chip,index;
@@ -4046,7 +4044,7 @@ get_timeout(struct cyclades_port * info, unsigned long *value)
                       + (cy_chip_offset[chip]<<index));
 
        tmp = cy_readb(base_addr+(CyRTPR<<index));
-       return cy_put_user(tmp,value);
+       return put_user(tmp,value);
     } else {
        // Nothing to do!
        return 0;
@@ -4063,9 +4061,9 @@ set_default_timeout(struct cyclades_port * info, unsigned long value)
 
 
 static int
-get_default_timeout(struct cyclades_port * info, unsigned long *value)
+get_default_timeout(struct cyclades_port * info, unsigned long __user *value)
 {
-    return cy_put_user(info->default_timeout,value);
+    return put_user(info->default_timeout,value);
 }/* get_default_timeout */
 
 /*
@@ -4079,9 +4077,10 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
 {
   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
   struct cyclades_icount cprev, cnow;          /* kernel counter temps */
-  struct serial_icounter_struct *p_cuser;      /* user space */
+  struct serial_icounter_struct __user *p_cuser;       /* user space */
   int ret_val = 0;
   unsigned long flags;
+  void __user *argp = (void __user *)arg;
 
     if (serial_paranoia_check(info, tty->name, "cy_ioctl"))
        return -ENODEV;
@@ -4093,31 +4092,31 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
 
     switch (cmd) {
         case CYGETMON:
-            ret_val = get_mon_info(info, (struct cyclades_monitor *)arg);
+            ret_val = get_mon_info(info, argp);
             break;
         case CYGETTHRESH:
-            ret_val = get_threshold(info, (unsigned long *)arg);
+            ret_val = get_threshold(info, argp);
             break;
         case CYSETTHRESH:
-            ret_val = set_threshold(info, (unsigned long)arg);
+            ret_val = set_threshold(info, arg);
             break;
         case CYGETDEFTHRESH:
-            ret_val = get_default_threshold(info, (unsigned long *)arg);
+            ret_val = get_default_threshold(info, argp);
             break;
         case CYSETDEFTHRESH:
-            ret_val = set_default_threshold(info, (unsigned long)arg);
+            ret_val = set_default_threshold(info, arg);
             break;
         case CYGETTIMEOUT:
-            ret_val = get_timeout(info, (unsigned long *)arg);
+            ret_val = get_timeout(info, argp);
             break;
         case CYSETTIMEOUT:
-            ret_val = set_timeout(info, (unsigned long)arg);
+            ret_val = set_timeout(info, arg);
             break;
         case CYGETDEFTIMEOUT:
-            ret_val = get_default_timeout(info, (unsigned long *)arg);
+            ret_val = get_default_timeout(info, argp);
             break;
         case CYSETDEFTIMEOUT:
-            ret_val = set_default_timeout(info, (unsigned long)arg);
+            ret_val = set_default_timeout(info, arg);
             break;
        case CYSETRFLOW:
            info->rflow = (int)arg;
@@ -4134,7 +4133,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
            ret_val = info->rtsdtr_inv;
            break;
        case CYGETCARDINFO:
-            if (copy_to_user((void *)arg, (void *)&cy_card[info->card], 
+            if (copy_to_user(argp, &cy_card[info->card], 
                        sizeof (struct cyclades_card))) {
                ret_val = -EFAULT;
                break;
@@ -4161,13 +4160,13 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
            ret_val = info->closing_wait / (HZ/100);
            break;
         case TIOCGSERIAL:
-            ret_val = get_serial_info(info, (struct serial_struct *) arg);
+            ret_val = get_serial_info(info, argp);
             break;
         case TIOCSSERIAL:
-            ret_val = set_serial_info(info, (struct serial_struct *) arg);
+            ret_val = set_serial_info(info, argp);
             break;
        case TIOCSERGETLSR: /* Get line status register */
-           ret_val = get_lsr_info(info, (unsigned int *) arg);
+           ret_val = get_lsr_info(info, argp);
            break;
        /*
         * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change 
@@ -4215,7 +4214,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
            CY_LOCK(info, flags);
            cnow = info->icount;
            CY_UNLOCK(info, flags);
-           p_cuser = (struct serial_icounter_struct *) arg;
+           p_cuser = argp;
            ret_val = put_user(cnow.cts, &p_cuser->cts);
            if (ret_val) return ret_val;
            ret_val = put_user(cnow.dsr, &p_cuser->dsr);
index 2abb7fa..aa7fd54 100644 (file)
@@ -109,8 +109,6 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
                return -EBUSY;
        if (!drm_agp->acquire)
                return -EINVAL;
-       if ( dev->agp->cant_use_aperture )
-               return -EINVAL;
        if ((retcode = drm_agp->acquire()))
                return retcode;
        dev->agp->acquired = 1;
index f89aa9e..cbf2dbf 100644 (file)
@@ -142,6 +142,13 @@ DRM(set_busid)(drm_device_t *dev)
        snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
                dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
 
+       dev->devname = DRM(alloc)(strlen(dev->name) + dev->unique_len + 2,
+                               DRM_MEM_DRIVER);
+       if (dev->devname == NULL)
+               return ENOMEM;
+
+       sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
+
        return 0;
 }
 
index d45f519..ed6a835 100644 (file)
@@ -346,6 +346,9 @@ static int gamma_dma_priority(struct file *filp,
        drm_buf_t         *buf;
        drm_buf_t         *last_buf = NULL;
        drm_device_dma_t  *dma      = dev->dma;
+       int               *send_indices = NULL;
+       int               *send_sizes = NULL;
+
        DECLARE_WAITQUEUE(entry, current);
 
                                /* Turn off interrupt handling */
@@ -365,11 +368,31 @@ static int gamma_dma_priority(struct file *filp,
                ++must_free;
        }
 
+       send_indices = DRM(alloc)(d->send_count * sizeof(*send_indices),
+                                 DRM_MEM_DRIVER);
+       if (send_indices == NULL)
+               return -ENOMEM;
+       if (copy_from_user(send_indices, d->send_indices, 
+                          d->send_count * sizeof(*send_indices))) {
+               retcode = -EFAULT;
+                goto cleanup;
+       }
+       
+       send_sizes = DRM(alloc)(d->send_count * sizeof(*send_sizes),
+                               DRM_MEM_DRIVER);
+       if (send_sizes == NULL)
+               return -ENOMEM;
+       if (copy_from_user(send_sizes, d->send_sizes, 
+                          d->send_count * sizeof(*send_sizes))) {
+               retcode = -EFAULT;
+                goto cleanup;
+       }
+
        for (i = 0; i < d->send_count; i++) {
-               idx = d->send_indices[i];
+               idx = send_indices[i];
                if (idx < 0 || idx >= dma->buf_count) {
                        DRM_ERROR("Index %d (of %d max)\n",
-                                 d->send_indices[i], dma->buf_count - 1);
+                                 send_indices[i], dma->buf_count - 1);
                        continue;
                }
                buf = dma->buflist[ idx ];
@@ -391,7 +414,7 @@ static int gamma_dma_priority(struct file *filp,
                                   process closes the /dev/drm? handle, so
                                   it can't also be doing DMA. */
                buf->list         = DRM_LIST_PRIO;
-               buf->used         = d->send_sizes[i];
+               buf->used         = send_sizes[i];
                buf->context      = d->context;
                buf->while_locked = d->flags & _DRM_DMA_WHILE_LOCKED;
                address           = (unsigned long)buf->address;
@@ -402,14 +425,14 @@ static int gamma_dma_priority(struct file *filp,
                if (buf->pending) {
                        DRM_ERROR("Sending pending buffer:"
                                  " buffer %d, offset %d\n",
-                                 d->send_indices[i], i);
+                                 send_indices[i], i);
                        retcode = -EINVAL;
                        goto cleanup;
                }
                if (buf->waiting) {
                        DRM_ERROR("Sending waiting buffer:"
                                  " buffer %d, offset %d\n",
-                                 d->send_indices[i], i);
+                                 send_indices[i], i);
                        retcode = -EINVAL;
                        goto cleanup;
                }
@@ -458,6 +481,12 @@ cleanup:
                gamma_dma_ready(dev);
                gamma_free_buffer(dev, last_buf);
        }
+       if (send_indices)
+               DRM(free)(send_indices, d->send_count * sizeof(*send_indices), 
+                         DRM_MEM_DRIVER);
+       if (send_sizes)
+               DRM(free)(send_sizes, d->send_count * sizeof(*send_sizes), 
+                         DRM_MEM_DRIVER);
 
        if (must_free && !dev->context_flag) {
                if (gamma_lock_free(dev, &dev->lock.hw_lock->lock,
@@ -476,9 +505,13 @@ static int gamma_dma_send_buffers(struct file *filp,
        drm_buf_t         *last_buf = NULL;
        int               retcode   = 0;
        drm_device_dma_t  *dma      = dev->dma;
+       int               send_index;
+
+       if (get_user(send_index, &d->send_indices[d->send_count-1]))
+               return -EFAULT;
 
        if (d->flags & _DRM_DMA_BLOCK) {
-               last_buf = dma->buflist[d->send_indices[d->send_count-1]];
+               last_buf = dma->buflist[send_index];
                add_wait_queue(&last_buf->dma_wait, &entry);
        }
 
index 81d2209..6ec11b0 100644 (file)
@@ -916,7 +916,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
 
        count = depth->n;
        if (count > 4096 || count <= 0)
-               return -EMSGSIZE;
+               return DRM_ERR(EMSGSIZE);
 
        if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
                return DRM_ERR(EFAULT);
@@ -1012,7 +1012,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
 
        count = depth->n;
        if (count > 4096 || count <= 0)
-               return -EMSGSIZE;
+               return DRM_ERR(EMSGSIZE);
 
        xbuf_size = count * sizeof(*x);
        ybuf_size = count * sizeof(*y);
@@ -1131,7 +1131,7 @@ static int r128_cce_dispatch_read_span( drm_device_t *dev,
 
        count = depth->n;
        if (count > 4096 || count <= 0)
-               return -EMSGSIZE;
+               return DRM_ERR(EMSGSIZE);
 
        if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
                return DRM_ERR(EFAULT);
@@ -1176,7 +1176,7 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
 
        count = depth->n;
        if (count > 4096 || count <= 0)
-               return -EMSGSIZE;
+               return DRM_ERR(EMSGSIZE);
 
        if ( count > dev_priv->depth_pitch ) {
                count = dev_priv->depth_pitch;
index 9a22c06..54fac79 100644 (file)
@@ -51,7 +51,7 @@
 #define DRIVER_DATE            "20020828"
 
 #define DRIVER_MAJOR           1
-#define DRIVER_MINOR           10
+#define DRIVER_MINOR           11
 #define DRIVER_PATCHLEVEL      0
 
 /* Interface history:
@@ -84,6 +84,8 @@
  * 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
  *       clients use to tell the DRM where they think the framebuffer is 
  *       located in the card's address space
+ * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
+ *       and GL_EXT_blend_[func|equation]_separate on r200
  */
 #define DRIVER_IOCTLS                                                       \
  [DRM_IOCTL_NR(DRM_IOCTL_DMA)]               = { radeon_cp_buffers,  1, 0 }, \
index c60c09f..735e04e 100644 (file)
 #define RADEON_EMIT_PP_TEX_SIZE_0                   73
 #define RADEON_EMIT_PP_TEX_SIZE_1                   74
 #define RADEON_EMIT_PP_TEX_SIZE_2                   75
-#define RADEON_MAX_STATE_PACKETS                    76
+#define R200_EMIT_RB3D_BLENDCOLOR                   76
+#define RADEON_MAX_STATE_PACKETS                    77
 
 
 /* Commands understood by cmd_buffer ioctl.  More can be added but
index afa516e..45eafd0 100644 (file)
@@ -690,6 +690,7 @@ extern void radeon_do_release(drm_device_t *dev);
 #define R200_SE_VTX_FMT_1                 0x208c
 #define R200_RE_CNTL                      0x1c50 
 
+#define R200_RB3D_BLENDCOLOR              0x3218
 
 /* Constants */
 #define RADEON_MAX_USEC_TIMEOUT                100000  /* 100 ms */
index 3a3bf01..83e2f6c 100644 (file)
@@ -137,12 +137,12 @@ static int init_heap(struct mem_block **heap, int start, int size)
        struct mem_block *blocks = DRM_MALLOC(sizeof(*blocks));
 
        if (!blocks) 
-               return -ENOMEM;
+               return DRM_ERR(ENOMEM);
        
        *heap = DRM_MALLOC(sizeof(**heap));
        if (!*heap) {
                DRM_FREE( blocks, sizeof(*blocks) );
-               return -ENOMEM;
+               return DRM_ERR(ENOMEM);
        }
 
        blocks->start = start;
index a8780bc..64143d1 100644 (file)
@@ -201,6 +201,7 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_
        case RADEON_EMIT_PP_TEX_SIZE_0:
        case RADEON_EMIT_PP_TEX_SIZE_1:
        case RADEON_EMIT_PP_TEX_SIZE_2:
+       case R200_EMIT_RB3D_BLENDCOLOR:
                /* These packets don't contain memory offsets */
                break;
 
@@ -563,6 +564,7 @@ static struct {
        { RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0" },
        { RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" },
        { RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_1" },
+       { R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR" },
 };
 
 
index 80935d6..9a10785 100644 (file)
@@ -113,7 +113,7 @@ int sis_fb_alloc( DRM_IOCTL_ARGS )
 
        DRM_COPY_TO_USER_IOCTL((drm_sis_mem_t *)data, fb, sizeof(fb));
 
-       DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset);
+       DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, req.offset);
 
        return retval;
 }
@@ -130,7 +130,7 @@ int sis_fb_free( DRM_IOCTL_ARGS )
 
        if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
                retval = DRM_ERR(EINVAL);
-       sis_free(fb.free);
+       sis_free((u32)fb.free);
 
        DRM_DEBUG("free fb, offset = %lu\n", fb.free);
 
index 5779505..ad4a967 100644 (file)
@@ -79,7 +79,7 @@ MODULE_PARM_DESC(force, "Force loading without checking for supported models");
 MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
 MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
 
-static ssize_t i8k_read(struct file *, char *, size_t, loff_t *);
+static ssize_t i8k_read(struct file *, char __user *, size_t, loff_t *);
 static int i8k_ioctl(struct inode *, struct file *, unsigned int,
                     unsigned long);
 
@@ -330,10 +330,10 @@ static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
     int val;
     int speed;
     unsigned char buff[16];
+    int __user *argp = (int __user *)arg;
 
-    if (!arg) {
+    if (!argp)
        return -EINVAL;
-    }
 
     switch (cmd) {
     case I8K_BIOS_VERSION:
@@ -358,14 +358,14 @@ static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
        break;
 
     case I8K_GET_SPEED:
-       if (copy_from_user(&val, (int *)arg, sizeof(int))) {
+       if (copy_from_user(&val, argp, sizeof(int))) {
            return -EFAULT;
        }
        val = i8k_get_fan_speed(val);
        break;
 
     case I8K_GET_FAN:
-       if (copy_from_user(&val, (int *)arg, sizeof(int))) {
+       if (copy_from_user(&val, argp, sizeof(int))) {
            return -EFAULT;
        }
        val = i8k_get_fan_status(val);
@@ -375,10 +375,10 @@ static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
        if (restricted && !capable(CAP_SYS_ADMIN)) {
            return -EPERM;
        }
-       if (copy_from_user(&val, (int *)arg, sizeof(int))) {
+       if (copy_from_user(&val, argp, sizeof(int))) {
            return -EFAULT;
        }
-       if (copy_from_user(&speed, (int *)arg+1, sizeof(int))) {
+       if (copy_from_user(&speed, argp+1, sizeof(int))) {
            return -EFAULT;
        }
        val = i8k_set_fan(val, speed);
@@ -394,17 +394,17 @@ static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
 
     switch (cmd) {
     case I8K_BIOS_VERSION:
-       if (copy_to_user((int *)arg, &val, 4)) {
+       if (copy_to_user(argp, &val, 4)) {
            return -EFAULT;
        }
        break;
     case I8K_MACHINE_ID:
-       if (copy_to_user((int *)arg, buff, 16)) {
+       if (copy_to_user(argp, buff, 16)) {
            return -EFAULT;
        }
        break;
     default:
-       if (copy_to_user((int *)arg, &val, sizeof(int))) {
+       if (copy_to_user(argp, &val, sizeof(int))) {
            return -EFAULT;
        }
        break;
@@ -462,7 +462,7 @@ static int i8k_get_info(char *buffer, char **start, off_t fpos, int length)
     return n;
 }
 
-static ssize_t i8k_read(struct file *f, char *buffer, size_t len, loff_t *fpos)
+static ssize_t i8k_read(struct file *f, char __user *buffer, size_t len, loff_t *fpos)
 {
     int n;
     char info[128];
index 6fc7077..7295bc5 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/ipmi_msgdefs.h>                /* for completion codes */
 #include "ipmi_si_sm.h"
 
-#define IPMI_BT_VERSION "v31"
+#define IPMI_BT_VERSION "v32"
 
 static int bt_debug = 0x00;    /* Production value 0, see following flags */
 
index afd1de3..0a2eeba 100644 (file)
@@ -45,7 +45,7 @@
 #include <asm/semaphore.h>
 #include <linux/init.h>
 
-#define IPMI_DEVINTF_VERSION "v31"
+#define IPMI_DEVINTF_VERSION "v32"
 
 struct ipmi_file_private
 {
@@ -199,7 +199,7 @@ static int handle_send_req(ipmi_user_t     user,
                        goto out;
                }
 
-               if (copy_from_user(&msgdata,
+               if (copy_from_user(msgdata,
                                   req->msg.data,
                                   req->msg.data_len))
                {
@@ -231,6 +231,7 @@ static int ipmi_ioctl(struct inode  *inode,
 {
        int                      rv = -EINVAL;
        struct ipmi_file_private *priv = file->private_data;
+       void __user *arg = (void __user *)data;
 
        switch (cmd) 
        {
@@ -238,7 +239,7 @@ static int ipmi_ioctl(struct inode  *inode,
        {
                struct ipmi_req req;
 
-               if (copy_from_user(&req, (void *) data, sizeof(req))) {
+               if (copy_from_user(&req, arg, sizeof(req))) {
                        rv = -EFAULT;
                        break;
                }
@@ -254,7 +255,7 @@ static int ipmi_ioctl(struct inode  *inode,
        {
                struct ipmi_req_settime req;
 
-               if (copy_from_user(&req, (void *) data, sizeof(req))) {
+               if (copy_from_user(&req, arg, sizeof(req))) {
                        rv = -EFAULT;
                        break;
                }
@@ -277,7 +278,7 @@ static int ipmi_ioctl(struct inode  *inode,
                
 
                rv = 0;
-               if (copy_from_user(&rsp, (void *) data, sizeof(rsp))) {
+               if (copy_from_user(&rsp, arg, sizeof(rsp))) {
                        rv = -EFAULT;
                        break;
                }
@@ -344,7 +345,7 @@ static int ipmi_ioctl(struct inode  *inode,
                        rsp.msg.data_len = 0;
                }
 
-               if (copy_to_user((void *) data, &rsp, sizeof(rsp))) {
+               if (copy_to_user(arg, &rsp, sizeof(rsp))) {
                        rv = -EFAULT;
                        goto recv_putback_on_err;
                }
@@ -371,7 +372,7 @@ static int ipmi_ioctl(struct inode  *inode,
        {
                struct ipmi_cmdspec val;
 
-               if (copy_from_user(&val, (void *) data, sizeof(val))) {
+               if (copy_from_user(&val, arg, sizeof(val))) {
                        rv = -EFAULT;
                        break;
                }
@@ -384,7 +385,7 @@ static int ipmi_ioctl(struct inode  *inode,
        {
                struct ipmi_cmdspec   val;
 
-               if (copy_from_user(&val, (void *) data, sizeof(val))) {
+               if (copy_from_user(&val, arg, sizeof(val))) {
                        rv = -EFAULT;
                        break;
                }
@@ -397,7 +398,7 @@ static int ipmi_ioctl(struct inode  *inode,
        {
                int val;
 
-               if (copy_from_user(&val, (void *) data, sizeof(val))) {
+               if (copy_from_user(&val, arg, sizeof(val))) {
                        rv = -EFAULT;
                        break;
                }
@@ -410,7 +411,7 @@ static int ipmi_ioctl(struct inode  *inode,
        {
                unsigned int val;
 
-               if (copy_from_user(&val, (void *) data, sizeof(val))) {
+               if (copy_from_user(&val, arg, sizeof(val))) {
                        rv = -EFAULT;
                        break;
                }
@@ -426,7 +427,7 @@ static int ipmi_ioctl(struct inode  *inode,
 
                val = ipmi_get_my_address(priv->user);
 
-               if (copy_to_user((void *) data, &val, sizeof(val))) {
+               if (copy_to_user(arg, &val, sizeof(val))) {
                        rv = -EFAULT;
                        break;
                }
@@ -438,7 +439,7 @@ static int ipmi_ioctl(struct inode  *inode,
        {
                unsigned int val;
 
-               if (copy_from_user(&val, (void *) data, sizeof(val))) {
+               if (copy_from_user(&val, arg, sizeof(val))) {
                        rv = -EFAULT;
                        break;
                }
@@ -454,7 +455,7 @@ static int ipmi_ioctl(struct inode  *inode,
 
                val = ipmi_get_my_LUN(priv->user);
 
-               if (copy_to_user((void *) data, &val, sizeof(val))) {
+               if (copy_to_user(arg, &val, sizeof(val))) {
                        rv = -EFAULT;
                        break;
                }
@@ -465,7 +466,7 @@ static int ipmi_ioctl(struct inode  *inode,
        {
                struct ipmi_timing_parms parms;
 
-               if (copy_from_user(&parms, (void *) data, sizeof(parms))) {
+               if (copy_from_user(&parms, arg, sizeof(parms))) {
                        rv = -EFAULT;
                        break;
                }
@@ -483,7 +484,7 @@ static int ipmi_ioctl(struct inode  *inode,
                parms.retries = priv->default_retries;
                parms.retry_time_ms = priv->default_retry_time_ms;
 
-               if (copy_to_user((void *) data, &parms, sizeof(parms))) {
+               if (copy_to_user(arg, &parms, sizeof(parms))) {
                        rv = -EFAULT;
                        break;
                }
index f4dd321..d155f9a 100644 (file)
@@ -42,7 +42,7 @@
 #include <linux/ipmi_msgdefs.h>                /* for completion codes */
 #include "ipmi_si_sm.h"
 
-#define IPMI_KCS_VERSION "v31"
+#define IPMI_KCS_VERSION "v32"
 
 /* Set this if you want a printout of why the state machine was hosed
    when it gets hosed. */
index c1e4abf..58c279a 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 
-#define IPMI_MSGHANDLER_VERSION "v31"
+#define IPMI_MSGHANDLER_VERSION "v32"
 
 struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
 static int ipmi_init_msghandler(void);
@@ -123,6 +123,12 @@ struct ipmi_channel
        unsigned char protocol;
 };
 
+struct ipmi_proc_entry
+{
+       char                   *name;
+       struct ipmi_proc_entry *next;
+};
+
 #define IPMI_IPMB_NUM_SEQ      64
 #define IPMI_MAX_CHANNELS       8
 struct ipmi_smi
@@ -149,6 +155,11 @@ struct ipmi_smi
        struct ipmi_smi_handlers *handlers;
        void                     *send_info;
 
+       /* A list of proc entries for this interface.  This does not
+          need a lock, only one thread creates it and only one thread
+          destroys it. */
+       struct ipmi_proc_entry *proc_entries;
+
        /* A table of sequence numbers for this interface.  We use the
            sequence numbers for IPMB messages that go out of the
            interface to match them up with their responses.  A routine
@@ -1515,18 +1526,36 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
                            read_proc_t *read_proc, write_proc_t *write_proc,
                            void *data, struct module *owner)
 {
-       struct proc_dir_entry *file;
-       int                   rv = 0;
+       struct proc_dir_entry  *file;
+       int                    rv = 0;
+       struct ipmi_proc_entry *entry;
+
+       /* Create a list element. */
+       entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+       if (!entry)
+               return -ENOMEM;
+       entry->name = kmalloc(strlen(name)+1, GFP_KERNEL);
+       if (!entry->name) {
+               kfree(entry);
+               return -ENOMEM;
+       }
+       strcpy(entry->name, name);
 
        file = create_proc_entry(name, 0, smi->proc_dir);
-       if (!file)
+       if (!file) {
+               kfree(entry->name);
+               kfree(entry);
                rv = -ENOMEM;
-       else {
+       else {
                file->nlink = 1;
                file->data = data;
                file->read_proc = read_proc;
                file->write_proc = write_proc;
                file->owner = owner;
+
+               /* Stick it on the list. */
+               entry->next = smi->proc_entries;
+               smi->proc_entries = entry;
        }
 
        return rv;
@@ -1562,6 +1591,21 @@ static int add_proc_entries(ipmi_smi_t smi, int num)
        return rv;
 }
 
+static void remove_proc_entries(ipmi_smi_t smi)
+{
+       struct ipmi_proc_entry *entry;
+
+       while (smi->proc_entries) {
+               entry = smi->proc_entries;
+               smi->proc_entries = entry->next;
+
+               remove_proc_entry(entry->name, smi->proc_dir);
+               kfree(entry->name);
+               kfree(entry);
+       }
+       remove_proc_entry(smi->proc_dir_name, proc_ipmi_root);
+}
+
 static int
 send_channel_info_cmd(ipmi_smi_t intf, int chan)
 {
@@ -1604,6 +1648,22 @@ channel_handler(ipmi_smi_t intf, struct ipmi_smi_msg *msg)
                /* It's the one we want */
                if (msg->rsp[2] != 0) {
                        /* Got an error from the channel, just go on. */
+
+                       if (msg->rsp[2] == IPMI_INVALID_COMMAND_ERR) {
+                               /* If the MC does not support this
+                                  command, that is legal.  We just
+                                  assume it has one IPMB at channel
+                                  zero. */
+                               intf->channels[0].medium
+                                       = IPMI_CHANNEL_MEDIUM_IPMB;
+                               intf->channels[0].protocol
+                                       = IPMI_CHANNEL_PROTOCOL_IPMB;
+                               rv = -ENOSYS;
+
+                               intf->curr_channel = IPMI_MAX_CHANNELS;
+                               wake_up(&intf->waitq);
+                               goto out;
+                       }
                        goto next_channel;
                }
                if (msg->rsp_size < 6) {
@@ -1627,10 +1687,20 @@ channel_handler(ipmi_smi_t intf, struct ipmi_smi_msg *msg)
                        wake_up(&intf->waitq);
 
                        printk(KERN_WARNING "ipmi_msghandler: Error sending"
-                              "channel information: 0x%x\n",
+                              "channel information: %d\n",
                               rv);
                }
        }
+ out:
+       return;
+}
+
+void ipmi_poll_interface(ipmi_user_t user)
+{
+       ipmi_smi_t intf = user->intf;
+
+       if (intf->handlers->poll)
+               intf->handlers->poll(intf->send_info);
 }
 
 int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
@@ -1749,8 +1819,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
 
        if (rv) {
                if (new_intf->proc_dir)
-                       remove_proc_entry(new_intf->proc_dir_name,
-                                         proc_ipmi_root);
+                       remove_proc_entries(new_intf);
                kfree(new_intf);
        }
 
@@ -1806,8 +1875,7 @@ int ipmi_unregister_smi(ipmi_smi_t intf)
        {
                for (i=0; i<MAX_IPMI_INTERFACES; i++) {
                        if (ipmi_interfaces[i] == intf) {
-                               remove_proc_entry(intf->proc_dir_name,
-                                                 proc_ipmi_root);
+                               remove_proc_entries(intf);
                                spin_lock_irqsave(&interfaces_lock, flags);
                                ipmi_interfaces[i] = NULL;
                                clean_up_interface_data(intf);
@@ -3112,6 +3180,7 @@ EXPORT_SYMBOL(ipmi_request);
 EXPORT_SYMBOL(ipmi_request_settime);
 EXPORT_SYMBOL(ipmi_request_supply_msgs);
 EXPORT_SYMBOL(ipmi_request_with_source);
+EXPORT_SYMBOL(ipmi_poll_interface);
 EXPORT_SYMBOL(ipmi_register_smi);
 EXPORT_SYMBOL(ipmi_unregister_smi);
 EXPORT_SYMBOL(ipmi_register_for_cmd);
index 34ceaee..85c9fec 100644 (file)
@@ -76,7 +76,7 @@ static inline void add_usec_to_timer(struct timer_list *t, long v)
 #include "ipmi_si_sm.h"
 #include <linux/init.h>
 
-#define IPMI_SI_VERSION "v31"
+#define IPMI_SI_VERSION "v32"
 
 /* Measure times between events in the driver. */
 #undef DEBUG_TIMING
@@ -712,6 +712,13 @@ static void set_run_to_completion(void *send_info, int i_run_to_completion)
        spin_unlock_irqrestore(&(smi_info->si_lock), flags);
 }
 
+static void poll(void *send_info)
+{
+       struct smi_info *smi_info = send_info;
+
+       smi_event_handler(smi_info, 0);
+}
+
 static void request_events(void *send_info)
 {
        struct smi_info *smi_info = send_info;
@@ -851,7 +858,8 @@ static struct ipmi_smi_handlers handlers =
        .owner                  = THIS_MODULE,
        .sender                 = sender,
        .request_events         = request_events,
-       .set_run_to_completion  = set_run_to_completion
+       .set_run_to_completion  = set_run_to_completion,
+       .poll                   = poll,
 };
 
 /* There can be 4 IO ports passed in (with or without IRQs), 4 addresses,
@@ -905,10 +913,10 @@ MODULE_PARM_DESC(irqs, "Sets the interrupt of each interface, the"
                 " has an interrupt.  Otherwise, set it to zero or leave"
                 " it blank.");
 
-
-#if defined(CONFIG_ACPI_INTERPETER) || defined(CONFIG_X86) || defined(CONFIG_PCI)
 #define IPMI_MEM_ADDR_SPACE 1
 #define IPMI_IO_ADDR_SPACE  2
+
+#if defined(CONFIG_ACPI_INTERPETER) || defined(CONFIG_X86) || defined(CONFIG_PCI)
 static int is_new_interface(int intf, u8 addr_space, unsigned long base_addr)
 {
        int i;
@@ -1848,6 +1856,21 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
        atomic_set(&new_smi->req_events, 0);
        new_smi->run_to_completion = 0;
 
+       new_smi->interrupt_disabled = 0;
+       new_smi->timer_stopped = 0;
+       new_smi->stop_operation = 0;
+
+       /* The ipmi_register_smi() code does some operations to
+          determine the channel information, so we must be ready to
+          handle operations before it is called.  This means we have
+          to stop the timer if we get an error after this point. */
+       init_timer(&(new_smi->si_timer));
+       new_smi->si_timer.data = (long) new_smi;
+       new_smi->si_timer.function = smi_timeout;
+       new_smi->last_timeout_jiffies = jiffies;
+       new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
+       add_timer(&(new_smi->si_timer));
+
        rv = ipmi_register_smi(&handlers,
                               new_smi,
                               new_smi->ipmi_version_major,
@@ -1857,7 +1880,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
                printk(KERN_ERR
                       "ipmi_si: Unable to register device: error %d\n",
                       rv);
-               goto out_err;
+               goto out_err_stop_timer;
        }
 
        rv = ipmi_smi_add_proc_entry(new_smi->intf, "type",
@@ -1867,7 +1890,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
                printk(KERN_ERR
                       "ipmi_si: Unable to create proc entry: %d\n",
                       rv);
-               goto out_err;
+               goto out_err_stop_timer;
        }
 
        rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats",
@@ -1877,7 +1900,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
                printk(KERN_ERR
                       "ipmi_si: Unable to create proc entry: %d\n",
                       rv);
-               goto out_err;
+               goto out_err_stop_timer;
        }
 
        start_clear_flags(new_smi);
@@ -1886,34 +1909,40 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
        if (new_smi->irq)
                new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ;
 
-       new_smi->interrupt_disabled = 0;
-       new_smi->timer_stopped = 0;
-       new_smi->stop_operation = 0;
-
-       init_timer(&(new_smi->si_timer));
-       new_smi->si_timer.data = (long) new_smi;
-       new_smi->si_timer.function = smi_timeout;
-       new_smi->last_timeout_jiffies = jiffies;
-       new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
-       add_timer(&(new_smi->si_timer));
-
        *smi = new_smi;
 
        printk(" IPMI %s interface initialized\n", si_type[intf_num]);
 
        return 0;
 
+ out_err_stop_timer:
+       new_smi->stop_operation = 1;
+
+       /* Wait for the timer to stop.  This avoids problems with race
+          conditions removing the timer here. */
+       while (!new_smi->timer_stopped) {
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout(1);
+       }
+
  out_err:
        if (new_smi->intf)
                ipmi_unregister_smi(new_smi->intf);
 
        new_smi->irq_cleanup(new_smi);
+
+       /* Wait until we know that we are out of any interrupt
+          handlers might have been running before we freed the
+          interrupt. */
+       synchronize_kernel();
+
        if (new_smi->si_sm) {
                if (new_smi->handlers)
                        new_smi->handlers->cleanup(new_smi->si_sm);
                kfree(new_smi->si_sm);
        }
        new_smi->io_cleanup(new_smi);
+
        return rv;
 }
 
index 7bd7041..b5c08d6 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/ipmi_msgdefs.h>                /* for completion codes */
 #include "ipmi_si_sm.h"
 
-#define IPMI_SMIC_VERSION "v31"
+#define IPMI_SMIC_VERSION "v32"
 
 /* smic_debug is a bit-field
  *     SMIC_DEBUG_ENABLE -     turned on for now
index 50aa959..2d201d0 100644 (file)
@@ -51,7 +51,7 @@
 #include <asm/apic.h>
 #endif
 
-#define IPMI_WATCHDOG_VERSION "v31"
+#define IPMI_WATCHDOG_VERSION "v32"
 
 /*
  * The IPMI command/response information for the watchdog timer.
@@ -515,40 +515,37 @@ static struct watchdog_info ident=
 static int ipmi_ioctl(struct inode *inode, struct file *file,
                      unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
        int i;
        int val;
 
        switch(cmd) {
        case WDIOC_GETSUPPORT:
-               i = copy_to_user((void*)arg, &ident, sizeof(ident));
+               i = copy_to_user(argp, &ident, sizeof(ident));
                return i ? -EFAULT : 0;
 
        case WDIOC_SETTIMEOUT:
-               i = copy_from_user(&val, (void *) arg, sizeof(int));
+               i = copy_from_user(&val, argp, sizeof(int));
                if (i)
                        return -EFAULT;
                timeout = val;
                return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
 
        case WDIOC_GETTIMEOUT:
-               i = copy_to_user((void *) arg,
-                                &timeout,
-                                sizeof(timeout));
+               i = copy_to_user(argp, &timeout, sizeof(timeout));
                if (i)
                        return -EFAULT;
                return 0;
 
        case WDIOC_SET_PRETIMEOUT:
-               i = copy_from_user(&val, (void *) arg, sizeof(int));
+               i = copy_from_user(&val, argp, sizeof(int));
                if (i)
                        return -EFAULT;
                pretimeout = val;
                return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
 
        case WDIOC_GET_PRETIMEOUT:
-               i = copy_to_user((void *) arg,
-                                &pretimeout,
-                                sizeof(pretimeout));
+               i = copy_to_user(argp, &pretimeout, sizeof(pretimeout));
                if (i)
                        return -EFAULT;
                return 0;
@@ -557,7 +554,7 @@ static int ipmi_ioctl(struct inode *inode, struct file *file,
                return ipmi_heartbeat();
 
        case WDIOC_SETOPTIONS:
-               i = copy_from_user(&val, (void *) arg, sizeof(int));
+               i = copy_from_user(&val, argp, sizeof(int));
                if (i)
                        return -EFAULT;
                if (val & WDIOS_DISABLECARD)
@@ -576,7 +573,7 @@ static int ipmi_ioctl(struct inode *inode, struct file *file,
 
        case WDIOC_GETSTATUS:
                val = 0;
-               i = copy_to_user((void *) arg, &val, sizeof(val));
+               i = copy_to_user(argp, &val, sizeof(val));
                if (i)
                        return -EFAULT;
                return 0;
@@ -587,7 +584,7 @@ static int ipmi_ioctl(struct inode *inode, struct file *file,
 }
 
 static ssize_t ipmi_write(struct file *file,
-                         const char  *buf,
+                         const char  __user *buf,
                          size_t      len,
                          loff_t      *ppos)
 {
@@ -607,7 +604,7 @@ static ssize_t ipmi_write(struct file *file,
 }
 
 static ssize_t ipmi_read(struct file *file,
-                        char        *buf,
+                        char        __user *buf,
                         size_t      count,
                         loff_t      *ppos)
 {
@@ -883,14 +880,12 @@ static int wdog_panic_handler(struct notifier_block *this,
 
        /* On a panic, if we have a panic timeout, make sure that the thing
           reboots, even if it hangs during that panic. */
-       if (watchdog_user && !panic_event_handled && (panic_timeout > 0)) {
+       if (watchdog_user && !panic_event_handled) {
                /* Make sure the panic doesn't hang, and make sure we
                   do this only once. */
                panic_event_handled = 1;
            
-               timeout = panic_timeout + 120;
-               if (timeout > 255)
-                       timeout = 255;
+               timeout = 255;
                pretimeout = 0;
                ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
                panic_halt_ipmi_set_timeout();
index 1a5a2df..ca512ad 100644 (file)
@@ -851,7 +851,7 @@ static void __exit istallion_module_exit(void)
        i = tty_unregister_driver(stli_serial);
        if (i) {
                printk("STALLION: failed to un-register tty driver, "
-                       "errno=%d,%d\n", -i);
+                       "errno=%d\n", -i);
                restore_flags(flags);
                return;
        }
index 010bff6..b703f5f 100644 (file)
@@ -52,13 +52,12 @@ extern void ctrl_alt_del(void);
 
 /*
  * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
- * This seems a good reason to start with NumLock off. On PC9800 and HIL keyboards 
+ * This seems a good reason to start with NumLock off. On HIL keyboards
  * of PARISC machines however there is no NumLock key and everyone expects the keypad 
  * to be used for numbers.
  */
 
-#if defined(CONFIG_X86_PC9800) || \
-    defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
+#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
 #define KBD_DEFLEDS (1 << VC_NUMLOCK)
 #else
 #define KBD_DEFLEDS 0
index a1c9cd0..945a258 100644 (file)
@@ -291,7 +291,7 @@ static int lp_wait_ready(int minor, int nonblock)
        return error;
 }
 
-static ssize_t lp_write(struct file * file, const char * buf,
+static ssize_t lp_write(struct file * file, const char __user * buf,
                        size_t count, loff_t *ppos)
 {
        unsigned int minor = iminor(file->f_dentry->d_inode);
@@ -407,7 +407,7 @@ static ssize_t lp_write(struct file * file, const char * buf,
 #ifdef CONFIG_PARPORT_1284
 
 /* Status readback conforming to ieee1284 */
-static ssize_t lp_read(struct file * file, char * buf,
+static ssize_t lp_read(struct file * file, char __user * buf,
                       size_t count, loff_t *ppos)
 {
        unsigned int minor=iminor(file->f_dentry->d_inode);
@@ -560,6 +560,7 @@ static int lp_ioctl(struct inode *inode, struct file *file,
        unsigned int minor = iminor(inode);
        int status;
        int retval = 0;
+       void __user *argp = (void __user *)arg;
 
 #ifdef LP_DEBUG
        printk(KERN_DEBUG "lp%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
@@ -603,7 +604,7 @@ static int lp_ioctl(struct inode *inode, struct file *file,
                        return -EINVAL;
                        break;
                case LPGETIRQ:
-                       if (copy_to_user((int *) arg, &LP_IRQ(minor),
+                       if (copy_to_user(argp, &LP_IRQ(minor),
                                        sizeof(int)))
                                return -EFAULT;
                        break;
@@ -612,7 +613,7 @@ static int lp_ioctl(struct inode *inode, struct file *file,
                        status = r_str(minor);
                        lp_release_parport (&lp_table[minor]);
 
-                       if (copy_to_user((int *) arg, &status, sizeof(int)))
+                       if (copy_to_user(argp, &status, sizeof(int)))
                                return -EFAULT;
                        break;
                case LPRESET:
@@ -620,7 +621,7 @@ static int lp_ioctl(struct inode *inode, struct file *file,
                        break;
 #ifdef LP_STATS
                case LPGETSTATS:
-                       if (copy_to_user((int *) arg, &LP_STAT(minor),
+                       if (copy_to_user(argp, &LP_STAT(minor),
                                        sizeof(struct lp_stats)))
                                return -EFAULT;
                        if (capable(CAP_SYS_ADMIN))
@@ -630,13 +631,12 @@ static int lp_ioctl(struct inode *inode, struct file *file,
 #endif
                case LPGETFLAGS:
                        status = LP_F(minor);
-                       if (copy_to_user((int *) arg, &status, sizeof(int)))
+                       if (copy_to_user(argp, &status, sizeof(int)))
                                return -EFAULT;
                        break;
 
                case LPSETTIMEOUT:
-                       if (copy_from_user (&par_timeout,
-                                           (struct timeval *) arg,
+                       if (copy_from_user (&par_timeout, argp,
                                            sizeof (struct timeval))) {
                                return -EFAULT;
                        }
index d0b4d4d..82ab436 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
-#include <asm/pgalloc.h>
 
 #ifdef CONFIG_IA64
 # include <linux/efi.h>
index 0fb356e..8832ed2 100644 (file)
@@ -467,10 +467,10 @@ int dsp3780I_Run(DSP_3780I_CONFIG_SETTINGS * pSettings)
 }
 
 
-int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
                         unsigned uCount, unsigned long ulDSPAddr)
 {
-       unsigned short *pusBuffer = pvBuffer;
+       unsigned short __user *pusBuffer = pvBuffer;
        unsigned short val;
 
 
@@ -508,10 +508,10 @@ int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void *pvBuffer,
 }
 
 int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO,
-                                void *pvBuffer, unsigned uCount,
+                                void __user *pvBuffer, unsigned uCount,
                                 unsigned long ulDSPAddr)
 {
-       unsigned short *pusBuffer = pvBuffer;
+       unsigned short __user *pusBuffer = pvBuffer;
        unsigned short val;
 
 
@@ -549,10 +549,10 @@ int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO,
 }
 
 
-int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
                          unsigned uCount, unsigned long ulDSPAddr)
 {
-       unsigned short *pusBuffer = pvBuffer;
+       unsigned short __user *pusBuffer = pvBuffer;
 
 
        PRINTK_5(TRACE_3780I,
@@ -590,10 +590,10 @@ int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void *pvBuffer,
 }
 
 
-int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
                         unsigned uCount, unsigned long ulDSPAddr)
 {
-       unsigned short *pusBuffer = pvBuffer;
+       unsigned short __user *pusBuffer = pvBuffer;
 
        PRINTK_5(TRACE_3780I,
                "3780i::dsp3780I_ReadIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
@@ -637,10 +637,10 @@ int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void *pvBuffer,
 }
 
 
-int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
                          unsigned uCount, unsigned long ulDSPAddr)
 {
-       unsigned short *pusBuffer = pvBuffer;
+       unsigned short __user *pusBuffer = pvBuffer;
 
        PRINTK_5(TRACE_3780I,
                "3780i::dsp3780I_WriteIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
index 8632890..3e7d020 100644 (file)
@@ -323,16 +323,16 @@ int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings,
 int dsp3780I_DisableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings);
 int dsp3780I_Reset(DSP_3780I_CONFIG_SETTINGS * pSettings);
 int dsp3780I_Run(DSP_3780I_CONFIG_SETTINGS * pSettings);
-int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
                         unsigned uCount, unsigned long ulDSPAddr);
 int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO,
-                                void *pvBuffer, unsigned uCount,
+                                void __user *pvBuffer, unsigned uCount,
                                 unsigned long ulDSPAddr);
-int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
                          unsigned uCount, unsigned long ulDSPAddr);
-int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
                         unsigned uCount, unsigned long ulDSPAddr);
-int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
                          unsigned uCount, unsigned long ulDSPAddr);
 unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO,
                                    unsigned long ulMsaAddr);
index f236538..7f54c84 100644 (file)
@@ -121,6 +121,7 @@ static int mwave_ioctl(struct inode *inode, struct file *file,
 {
        unsigned int retval = 0;
        pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
+       void __user *arg = (void __user *)ioarg;
 
        PRINTK_5(TRACE_MWAVE,
                "mwavedd::mwave_ioctl, entry inode %x file %x cmd %x arg %x\n",
@@ -164,8 +165,7 @@ static int mwave_ioctl(struct inode *inode, struct file *file,
                                " retval %x from tp3780I_QueryAbilities\n",
                                retval);
                        if (retval == 0) {
-                               if( copy_to_user((char *) ioarg,
-                                                       (char *) &rAbilities,
+                               if( copy_to_user(arg, &rAbilities,
                                                        sizeof(MW_ABILITIES)) )
                                        return -EFAULT;
                        }
@@ -179,13 +179,12 @@ static int mwave_ioctl(struct inode *inode, struct file *file,
                case IOCTL_MW_READ_DATA:
                case IOCTL_MW_READCLEAR_DATA: {
                        MW_READWRITE rReadData;
-                       unsigned short *pusBuffer = 0;
+                       unsigned short __user *pusBuffer = 0;
        
-                       if( copy_from_user((char *) &rReadData,
-                                               (char *) ioarg,
+                       if( copy_from_user(&rReadData, arg,
                                                sizeof(MW_READWRITE)) )
                                return -EFAULT;
-                       pusBuffer = (unsigned short *) (rReadData.pBuf);
+                       pusBuffer = (unsigned short __user *) (rReadData.pBuf);
        
                        PRINTK_4(TRACE_MWAVE,
                                "mwavedd::mwave_ioctl IOCTL_MW_READ_DATA,"
@@ -193,7 +192,7 @@ static int mwave_ioctl(struct inode *inode, struct file *file,
                                rReadData.ulDataLength, ioarg, pusBuffer);
                        retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
                                        iocmd,
-                                       (void *) pusBuffer,
+                                       pusBuffer,
                                        rReadData.ulDataLength,
                                        rReadData.usDspAddress);
                }
@@ -201,12 +200,12 @@ static int mwave_ioctl(struct inode *inode, struct file *file,
        
                case IOCTL_MW_READ_INST: {
                        MW_READWRITE rReadData;
-                       unsigned short *pusBuffer = 0;
+                       unsigned short __user *pusBuffer = 0;
        
-                       if( copy_from_user((char *) &rReadData, (char *) ioarg,
+                       if( copy_from_user(&rReadData, arg,
                                                sizeof(MW_READWRITE)) )
                                return -EFAULT;
-                       pusBuffer = (unsigned short *) (rReadData.pBuf);
+                       pusBuffer = (unsigned short __user *) (rReadData.pBuf);
        
                        PRINTK_4(TRACE_MWAVE,
                                "mwavedd::mwave_ioctl IOCTL_MW_READ_INST,"
@@ -222,13 +221,12 @@ static int mwave_ioctl(struct inode *inode, struct file *file,
        
                case IOCTL_MW_WRITE_DATA: {
                        MW_READWRITE rWriteData;
-                       unsigned short *pusBuffer = 0;
+                       unsigned short __user *pusBuffer = 0;
        
-                       if( copy_from_user((char *) &rWriteData,
-                                               (char *) ioarg,
+                       if( copy_from_user(&rWriteData, arg,
                                                sizeof(MW_READWRITE)) )
                                return -EFAULT;
-                       pusBuffer = (unsigned short *) (rWriteData.pBuf);
+                       pusBuffer = (unsigned short __user *) (rWriteData.pBuf);
        
                        PRINTK_4(TRACE_MWAVE,
                                "mwavedd::mwave_ioctl IOCTL_MW_WRITE_DATA,"
@@ -244,13 +242,12 @@ static int mwave_ioctl(struct inode *inode, struct file *file,
        
                case IOCTL_MW_WRITE_INST: {
                        MW_READWRITE rWriteData;
-                       unsigned short *pusBuffer = 0;
+                       unsigned short __user *pusBuffer = 0;
        
-                       if( copy_from_user((char *) &rWriteData,
-                                               (char *) ioarg,
+                       if( copy_from_user(&rWriteData, arg,
                                                sizeof(MW_READWRITE)) )
                                return -EFAULT;
-                       pusBuffer = (unsigned short *) (rWriteData.pBuf);
+                       pusBuffer = (unsigned short __user *)(rWriteData.pBuf);
        
                        PRINTK_4(TRACE_MWAVE,
                                "mwavedd::mwave_ioctl IOCTL_MW_WRITE_INST,"
@@ -388,7 +385,7 @@ static int mwave_ioctl(struct inode *inode, struct file *file,
 }
 
 
-static ssize_t mwave_read(struct file *file, char *buf, size_t count,
+static ssize_t mwave_read(struct file *file, char __user *buf, size_t count,
                           loff_t * ppos)
 {
        PRINTK_5(TRACE_MWAVE,
@@ -399,7 +396,7 @@ static ssize_t mwave_read(struct file *file, char *buf, size_t count,
 }
 
 
-static ssize_t mwave_write(struct file *file, const char *buf,
+static ssize_t mwave_write(struct file *file, const char __user *buf,
                            size_t count, loff_t * ppos)
 {
        PRINTK_5(TRACE_MWAVE,
index 373173d..c830fc6 100644 (file)
@@ -522,7 +522,7 @@ int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities
 }
 
 int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
-                               void *pvBuffer, unsigned int uCount,
+                               void __user *pvBuffer, unsigned int uCount,
                                unsigned long ulDSPAddr)
 {
        int retval = 0;
@@ -558,7 +558,7 @@ int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
 
 
 int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
-                               void *pvBuffer, unsigned int uCount,
+                               void __user *pvBuffer, unsigned int uCount,
                                unsigned long ulDSPAddr)
 {
        int retval = 0;
index fc049ac..07685b6 100644 (file)
@@ -93,10 +93,10 @@ int tp3780I_StartDSP(THINKPAD_BD_DATA * pBDData);
 int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities);
 int tp3780I_Cleanup(THINKPAD_BD_DATA * pBDData);
 int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
-                               void *pvBuffer, unsigned int uCount,
+                               void __user *pvBuffer, unsigned int uCount,
                                unsigned long ulDSPAddr);
 int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
-                               void *pvBuffer, unsigned int uCount,
+                               void __user *pvBuffer, unsigned int uCount,
                                unsigned long ulDSPAddr);
 
 
index 7b6ee59..b5f32d6 100644 (file)
@@ -250,7 +250,7 @@ static loff_t nvram_llseek(struct file *file,loff_t offset, int origin )
 }
 
 static ssize_t
-nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+nvram_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
        unsigned char contents[NVRAM_BYTES];
        unsigned i = *ppos;
@@ -279,7 +279,7 @@ nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 }
 
 static ssize_t
-nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+nvram_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
        unsigned char contents[NVRAM_BYTES];
        unsigned i = *ppos;
index fb87f87..970e233 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/char/pcmcia/synclink_cs.c
  *
- * $Id: synclink_cs.c,v 4.21 2004/03/08 15:29:23 paulkf Exp $
+ * $Id: synclink_cs.c,v 4.22 2004/06/01 20:27:46 paulkf Exp $
  *
  * Device driver for Microgate SyncLink PC Card
  * multiprotocol serial adapter.
@@ -438,15 +438,15 @@ static void bh_status(MGSLPC_INFO *info);
 static int tiocmget(struct tty_struct *tty, struct file *file);
 static int tiocmset(struct tty_struct *tty, struct file *file,
                    unsigned int set, unsigned int clear);
-static int get_stats(MGSLPC_INFO *info, struct mgsl_icount *user_icount);
-static int get_params(MGSLPC_INFO *info, MGSL_PARAMS *user_params);
-static int set_params(MGSLPC_INFO *info, MGSL_PARAMS *new_params);
-static int get_txidle(MGSLPC_INFO *info, int*idle_mode);
+static int get_stats(MGSLPC_INFO *info, struct mgsl_icount __user *user_icount);
+static int get_params(MGSLPC_INFO *info, MGSL_PARAMS __user *user_params);
+static int set_params(MGSLPC_INFO *info, MGSL_PARAMS __user *new_params);
+static int get_txidle(MGSLPC_INFO *info, int __user *idle_mode);
 static int set_txidle(MGSLPC_INFO *info, int idle_mode);
 static int set_txenable(MGSLPC_INFO *info, int enable);
 static int tx_abort(MGSLPC_INFO *info);
 static int set_rxenable(MGSLPC_INFO *info, int enable);
-static int wait_events(MGSLPC_INFO *info, int *mask);
+static int wait_events(MGSLPC_INFO *info, int __user *mask);
 
 #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
 
@@ -489,7 +489,7 @@ MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICE_COUNT) "i");
 MODULE_LICENSE("GPL");
 
 static char *driver_name = "SyncLink PC Card driver";
-static char *driver_version = "$Revision: 4.21 $";
+static char *driver_version = "$Revision: 4.22 $";
 
 static struct tty_driver *serial_driver;
 
@@ -521,8 +521,10 @@ static dev_link_t *dev_list = NULL;
  * (gdb) to get the .text address for the add-symbol-file command.
  * This allows remote debugging of dynamically loadable modules.
  */
-static void* mgslpc_get_text_ptr(void);
-static void* mgslpc_get_text_ptr() {return mgslpc_get_text_ptr;}
+static void* mgslpc_get_text_ptr(void)
+{
+       return mgslpc_get_text_ptr;
+}
 
 static dev_link_t *mgslpc_attach(void)
 {
@@ -1955,7 +1957,7 @@ static void mgslpc_unthrottle(struct tty_struct * tty)
 
 /* get the current serial statistics
  */
-static int get_stats(MGSLPC_INFO * info, struct mgsl_icount *user_icount)
+static int get_stats(MGSLPC_INFO * info, struct mgsl_icount __user *user_icount)
 {
        int err;
        if (debug_level >= DEBUG_LEVEL_INFO)
@@ -1968,7 +1970,7 @@ static int get_stats(MGSLPC_INFO * info, struct mgsl_icount *user_icount)
 
 /* get the current serial parameters
  */
-static int get_params(MGSLPC_INFO * info, MGSL_PARAMS *user_params)
+static int get_params(MGSLPC_INFO * info, MGSL_PARAMS __user *user_params)
 {
        int err;
        if (debug_level >= DEBUG_LEVEL_INFO)
@@ -1988,7 +1990,7 @@ static int get_params(MGSLPC_INFO * info, MGSL_PARAMS *user_params)
  *
  * Returns:    0 if success, otherwise error code
  */
-static int set_params(MGSLPC_INFO * info, MGSL_PARAMS *new_params)
+static int set_params(MGSLPC_INFO * info, MGSL_PARAMS __user *new_params)
 {
        unsigned long flags;
        MGSL_PARAMS tmp_params;
@@ -2014,7 +2016,7 @@ static int set_params(MGSLPC_INFO * info, MGSL_PARAMS *new_params)
        return 0;
 }
 
-static int get_txidle(MGSLPC_INFO * info, int*idle_mode)
+static int get_txidle(MGSLPC_INFO * info, int __user *idle_mode)
 {
        int err;
        if (debug_level >= DEBUG_LEVEL_INFO)
@@ -2037,7 +2039,7 @@ static int set_txidle(MGSLPC_INFO * info, int idle_mode)
        return 0;
 }
 
-static int get_interface(MGSLPC_INFO * info, int*if_mode)
+static int get_interface(MGSLPC_INFO * info, int __user *if_mode)
 {
        int err;
        if (debug_level >= DEBUG_LEVEL_INFO)
@@ -2136,7 +2138,7 @@ static int set_rxenable(MGSLPC_INFO * info, int enable)
  *                             of events triggerred,
  *                     otherwise error code
  */
-static int wait_events(MGSLPC_INFO * info, int mask_ptr)
+static int wait_events(MGSLPC_INFO * info, int __user *mask_ptr)
 {
        unsigned long flags;
        int s;
@@ -2409,20 +2411,21 @@ int ioctl_common(MGSLPC_INFO *info, unsigned int cmd, unsigned long arg)
 {
        int error;
        struct mgsl_icount cnow;        /* kernel counter temps */
-       struct serial_icounter_struct *p_cuser; /* user space */
+       struct serial_icounter_struct __user *p_cuser;  /* user space */
+       void __user *argp = (void __user *)arg;
        unsigned long flags;
        
        switch (cmd) {
        case MGSL_IOCGPARAMS:
-               return get_params(info,(MGSL_PARAMS *)arg);
+               return get_params(info, argp);
        case MGSL_IOCSPARAMS:
-               return set_params(info,(MGSL_PARAMS *)arg);
+               return set_params(info, argp);
        case MGSL_IOCGTXIDLE:
-               return get_txidle(info,(int*)arg);
+               return get_txidle(info, argp);
        case MGSL_IOCSTXIDLE:
-               return set_txidle(info,(int)arg);
+               return set_txidle(info, (int)arg);
        case MGSL_IOCGIF:
-               return get_interface(info,(int*)arg);
+               return get_interface(info, argp);
        case MGSL_IOCSIF:
                return set_interface(info,(int)arg);
        case MGSL_IOCTXENABLE:
@@ -2432,16 +2435,16 @@ int ioctl_common(MGSLPC_INFO *info, unsigned int cmd, unsigned long arg)
        case MGSL_IOCTXABORT:
                return tx_abort(info);
        case MGSL_IOCGSTATS:
-               return get_stats(info,(struct mgsl_icount*)arg);
+               return get_stats(info, argp);
        case MGSL_IOCWAITEVENT:
-               return wait_events(info,(int*)arg);
+               return wait_events(info, argp);
        case TIOCMIWAIT:
                return modem_input_wait(info,(int)arg);
        case TIOCGICOUNT:
                spin_lock_irqsave(&info->lock,flags);
                cnow = info->icount;
                spin_unlock_irqrestore(&info->lock,flags);
-               p_cuser = (struct serial_icounter_struct *) arg;
+               p_cuser = argp;
                PUT_USER(error,cnow.cts, &p_cuser->cts);
                if (error) return error;
                PUT_USER(error,cnow.dsr, &p_cuser->dsr);
@@ -3130,9 +3133,35 @@ static struct tty_operations mgslpc_ops = {
        .tiocmset = tiocmset,
 };
 
+static void synclink_cs_cleanup(void)
+{
+       int rc;
+
+       printk("Unloading %s: version %s\n", driver_name, driver_version);
+
+       while(mgslpc_device_list)
+               mgslpc_remove_device(mgslpc_device_list);
+
+       if (serial_driver) {
+               if ((rc = tty_unregister_driver(serial_driver)))
+                       printk("%s(%d) failed to unregister tty driver err=%d\n",
+                              __FILE__,__LINE__,rc);
+               put_tty_driver(serial_driver);
+       }
+
+       pcmcia_unregister_driver(&mgslpc_driver);
+
+       /* XXX: this really needs to move into generic code.. */
+       while (dev_list != NULL) {
+               if (dev_list->state & DEV_CONFIG)
+                       mgslpc_release((u_long)dev_list);
+               mgslpc_detach(dev_list);
+       }
+}
+
 static int __init synclink_cs_init(void)
 {
-    int error;
+    int rc;
 
     if (break_on_load) {
            mgslpc_get_text_ptr();
@@ -3141,14 +3170,13 @@ static int __init synclink_cs_init(void)
 
     printk("%s %s\n", driver_name, driver_version);
 
-    serial_driver = alloc_tty_driver(MAX_DEVICE_COUNT);
-    if (!serial_driver)
-           return -ENOMEM;
+    if ((rc = pcmcia_register_driver(&mgslpc_driver)) < 0)
+           return rc;
 
-    error = pcmcia_register_driver(&mgslpc_driver);
-    if (error) {
-           put_tty_driver(serial_driver);
-           return error;
+    serial_driver = alloc_tty_driver(MAX_DEVICE_COUNT);
+    if (!serial_driver) {
+           rc = -ENOMEM;
+           goto error;
     }
 
     /* Initialize the tty_driver structure */
@@ -3166,39 +3194,28 @@ static int __init synclink_cs_init(void)
     serial_driver->flags = TTY_DRIVER_REAL_RAW;
     tty_set_operations(serial_driver, &mgslpc_ops);
 
-    if (tty_register_driver(serial_driver) < 0)
+    if ((rc = tty_register_driver(serial_driver)) < 0) {
            printk("%s(%d):Couldn't register serial driver\n",
                   __FILE__,__LINE__);
+           put_tty_driver(serial_driver);
+           serial_driver = NULL;
+           goto error;
+    }
                        
     printk("%s %s, tty major#%d\n",
           driver_name, driver_version,
           serial_driver->major);
        
     return 0;
+
+error:
+    synclink_cs_cleanup();
+    return rc;
 }
 
 static void __exit synclink_cs_exit(void) 
 {
-       int rc;
-
-       printk("Unloading %s: version %s\n", driver_name, driver_version);
-
-       while(mgslpc_device_list)
-               mgslpc_remove_device(mgslpc_device_list);
-
-       if ((rc = tty_unregister_driver(serial_driver)))
-               printk("%s(%d) failed to unregister tty driver err=%d\n",
-                      __FILE__,__LINE__,rc);
-       put_tty_driver(serial_driver);
-
-       pcmcia_unregister_driver(&mgslpc_driver);
-
-       /* XXX: this really needs to move into generic code.. */
-       while (dev_list != NULL) {
-               if (dev_list->state & DEV_CONFIG)
-                       mgslpc_release((u_long)dev_list);
-               mgslpc_detach(dev_list);
-       }
+       synclink_cs_cleanup();
 }
 
 module_init(synclink_cs_init);
index 56ae1f0..5eda075 100644 (file)
@@ -103,7 +103,7 @@ static inline void pp_enable_irq (struct pp_struct *pp)
        port->ops->enable_irq (port);
 }
 
-static ssize_t pp_read (struct file * file, char * buf, size_t count,
+static ssize_t pp_read (struct file * file, char __user * buf, size_t count,
                        loff_t * ppos)
 {
        unsigned int minor = iminor(file->f_dentry->d_inode);
@@ -186,8 +186,8 @@ static ssize_t pp_read (struct file * file, char * buf, size_t count,
        return bytes_read;
 }
 
-static ssize_t pp_write (struct file * file, const char * buf, size_t count,
-                        loff_t * ppos)
+static ssize_t pp_write (struct file * file, const char __user * buf,
+                        size_t count, loff_t * ppos)
 {
        unsigned int minor = iminor(file->f_dentry->d_inode);
        struct pp_struct *pp = file->private_data;
@@ -335,6 +335,7 @@ static int pp_ioctl(struct inode *inode, struct file *file,
        unsigned int minor = iminor(inode);
        struct pp_struct *pp = file->private_data;
        struct parport * port;
+       void __user *argp = (void __user *)arg;
 
        /* First handle the cases that don't take arguments. */
        switch (cmd) {
@@ -396,7 +397,7 @@ static int pp_ioctl(struct inode *inode, struct file *file,
        case PPSETMODE:
            {
                int mode;
-               if (copy_from_user (&mode, (int *) arg, sizeof (mode)))
+               if (copy_from_user (&mode, argp, sizeof (mode)))
                        return -EFAULT;
                /* FIXME: validate mode */
                pp->state.mode = mode;
@@ -418,7 +419,7 @@ static int pp_ioctl(struct inode *inode, struct file *file,
                } else {
                        mode = pp->state.mode;
                }
-               if (copy_to_user ((int *)arg, &mode, sizeof (mode))) {
+               if (copy_to_user (argp, &mode, sizeof (mode))) {
                        return -EFAULT;
                }
                return 0;
@@ -426,7 +427,7 @@ static int pp_ioctl(struct inode *inode, struct file *file,
        case PPSETPHASE:
            {
                int phase;
-               if (copy_from_user (&phase, (int *) arg, sizeof (phase))) {
+               if (copy_from_user (&phase, argp, sizeof (phase))) {
                        return -EFAULT;
                }
                /* FIXME: validate phase */
@@ -447,7 +448,7 @@ static int pp_ioctl(struct inode *inode, struct file *file,
                } else {
                        phase = pp->state.phase;
                }
-               if (copy_to_user ((int *)arg, &phase, sizeof (phase))) {
+               if (copy_to_user (argp, &phase, sizeof (phase))) {
                        return -EFAULT;
                }
                return 0;
@@ -461,7 +462,7 @@ static int pp_ioctl(struct inode *inode, struct file *file,
                        return -ENODEV;
 
                modes = port->modes;
-               if (copy_to_user ((unsigned int *)arg, &modes, sizeof (modes))) {
+               if (copy_to_user (argp, &modes, sizeof (modes))) {
                        return -EFAULT;
                }
                return 0;
@@ -470,7 +471,7 @@ static int pp_ioctl(struct inode *inode, struct file *file,
            {
                int uflags;
 
-               if (copy_from_user (&uflags, (int *)arg, sizeof (uflags))) {
+               if (copy_from_user (&uflags, argp, sizeof (uflags))) {
                        return -EFAULT;
                }
                pp->flags &= ~PP_FLAGMASK;
@@ -482,7 +483,7 @@ static int pp_ioctl(struct inode *inode, struct file *file,
                int uflags;
 
                uflags = pp->flags & PP_FLAGMASK;
-               if (copy_to_user ((int *)arg, &uflags, sizeof (uflags))) {
+               if (copy_to_user (argp, &uflags, sizeof (uflags))) {
                        return -EFAULT;
                }
                return 0;
@@ -509,17 +510,17 @@ static int pp_ioctl(struct inode *inode, struct file *file,
 
        case PPRSTATUS:
                reg = parport_read_status (port);
-               if (copy_to_user ((unsigned char *) arg, &reg, sizeof (reg)))
+               if (copy_to_user (argp, &reg, sizeof (reg)))
                        return -EFAULT;
                return 0;
        case PPRDATA:
                reg = parport_read_data (port);
-               if (copy_to_user ((unsigned char *) arg, &reg, sizeof (reg)))
+               if (copy_to_user (argp, &reg, sizeof (reg)))
                        return -EFAULT;
                return 0;
        case PPRCONTROL:
                reg = parport_read_control (port);
-               if (copy_to_user ((unsigned char *) arg, &reg, sizeof (reg)))
+               if (copy_to_user (argp, &reg, sizeof (reg)))
                        return -EFAULT;
                return 0;
        case PPYIELD:
@@ -538,29 +539,29 @@ static int pp_ioctl(struct inode *inode, struct file *file,
                return 0;
 
        case PPWCONTROL:
-               if (copy_from_user (&reg, (unsigned char *) arg, sizeof (reg)))
+               if (copy_from_user (&reg, argp, sizeof (reg)))
                        return -EFAULT;
                parport_write_control (port, reg);
                return 0;
 
        case PPWDATA:
-               if (copy_from_user (&reg, (unsigned char *) arg, sizeof (reg)))
+               if (copy_from_user (&reg, argp, sizeof (reg)))
                        return -EFAULT;
                parport_write_data (port, reg);
                return 0;
 
        case PPFCONTROL:
-               if (copy_from_user (&mask, (unsigned char *) arg,
+               if (copy_from_user (&mask, argp,
                                    sizeof (mask)))
                        return -EFAULT;
-               if (copy_from_user (&reg, 1 + (unsigned char *) arg,
+               if (copy_from_user (&reg, 1 + (unsigned char __user *) arg,
                                    sizeof (reg)))
                        return -EFAULT;
                parport_frob_control (port, mask, reg);
                return 0;
 
        case PPDATADIR:
-               if (copy_from_user (&mode, (int *) arg, sizeof (mode)))
+               if (copy_from_user (&mode, argp, sizeof (mode)))
                        return -EFAULT;
                if (mode)
                        port->ops->data_reverse (port);
@@ -569,7 +570,7 @@ static int pp_ioctl(struct inode *inode, struct file *file,
                return 0;
 
        case PPNEGOT:
-               if (copy_from_user (&mode, (int *) arg, sizeof (mode)))
+               if (copy_from_user (&mode, argp, sizeof (mode)))
                        return -EFAULT;
                switch ((ret = parport_negotiate (port, mode))) {
                case 0: break;
@@ -584,8 +585,7 @@ static int pp_ioctl(struct inode *inode, struct file *file,
                return ret;
 
        case PPWCTLONIRQ:
-               if (copy_from_user (&reg, (unsigned char *) arg,
-                                   sizeof (reg)))
+               if (copy_from_user (&reg, argp, sizeof (reg)))
                        return -EFAULT;
 
                /* Remember what to set the control lines to, for next
@@ -596,14 +596,13 @@ static int pp_ioctl(struct inode *inode, struct file *file,
 
        case PPCLRIRQ:
                ret = atomic_read (&pp->irqc);
-               if (copy_to_user ((int *) arg, &ret, sizeof (ret)))
+               if (copy_to_user (argp, &ret, sizeof (ret)))
                        return -EFAULT;
                atomic_sub (ret, &pp->irqc);
                return 0;
 
        case PPSETTIME:
-               if (copy_from_user (&par_timeout, (struct timeval *)arg,
-                                   sizeof(struct timeval))) {
+               if (copy_from_user (&par_timeout, argp, sizeof(struct timeval))) {
                        return -EFAULT;
                }
                /* Convert to jiffies, place in pp->pdev->timeout */
@@ -622,10 +621,8 @@ static int pp_ioctl(struct inode *inode, struct file *file,
                to_jiffies = pp->pdev->timeout;
                par_timeout.tv_sec = to_jiffies / HZ;
                par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ);
-               if (copy_to_user ((struct timeval *)arg, &par_timeout,
-                                 sizeof(struct timeval))) {
+               if (copy_to_user (argp, &par_timeout, sizeof(struct timeval)))
                        return -EFAULT;
-               }
                return 0;
 
        default:
index 03b4f20..641fe5e 100644 (file)
@@ -97,6 +97,11 @@ static unsigned long rtc_port;
 static int rtc_irq = PCI_IRQ_NONE;
 #endif
 
+#ifdef CONFIG_HPET_RTC_IRQ
+#undef RTC_IRQ
+#define        RTC_IRQ 0
+#endif
+
 #ifdef RTC_IRQ
 static int rtc_has_irq = 1;
 #endif
index 3758fb1..e937346 100644 (file)
@@ -26,7 +26,7 @@ static int major = 0;         /* default to dynamic major */
 MODULE_PARM(major, "i");
 MODULE_PARM_DESC(major, "Major device number");
 
-static ssize_t scx200_gpio_write(struct file *file, const char *data, 
+static ssize_t scx200_gpio_write(struct file *file, const char __user *data, 
                                 size_t len, loff_t *ppos)
 {
        unsigned m = iminor(file->f_dentry->d_inode);
@@ -77,7 +77,7 @@ static ssize_t scx200_gpio_write(struct file *file, const char *data,
        return len;
 }
 
-static ssize_t scx200_gpio_read(struct file *file, char *buf,
+static ssize_t scx200_gpio_read(struct file *file, char __user *buf,
                                size_t len, loff_t *ppos)
 {
        unsigned m = iminor(file->f_dentry->d_inode);
index a3780cd..a906dfa 100644 (file)
@@ -461,8 +461,9 @@ static int sonypi_misc_open(struct inode * inode, struct file * file) {
        return 0;
 }
 
-static ssize_t sonypi_misc_read(struct file * file, char * buf, 
-                               size_t count, loff_t *pos) {
+static ssize_t sonypi_misc_read(struct file * file, char __user * buf,
+                       size_t count, loff_t *pos)
+{
        DECLARE_WAITQUEUE(wait, current);
        ssize_t i = count;
        unsigned char c;
@@ -504,6 +505,7 @@ static unsigned int sonypi_misc_poll(struct file *file, poll_table * wait) {
 static int sonypi_misc_ioctl(struct inode *ip, struct file *fp, 
                             unsigned int cmd, unsigned long arg) {
        int ret = 0;
+       void __user *argp = (void __user *)arg;
        u8 val8;
        u16 val16;
 
@@ -514,11 +516,11 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
                        ret = -EIO;
                        break;
                }
-               if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
+               if (copy_to_user(argp, &val8, sizeof(val8)))
                        ret = -EFAULT;
                break;
        case SONYPI_IOCSBRT:
-               if (copy_from_user(&val8, (u8 *)arg, sizeof(val8))) {
+               if (copy_from_user(&val8, argp, sizeof(val8))) {
                        ret = -EFAULT;
                        break;
                }
@@ -530,7 +532,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
                        ret = -EIO;
                        break;
                }
-               if (copy_to_user((u16 *)arg, &val16, sizeof(val16)))
+               if (copy_to_user(argp, &val16, sizeof(val16)))
                        ret = -EFAULT;
                break;
        case SONYPI_IOCGBAT1REM:
@@ -538,7 +540,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
                        ret = -EIO;
                        break;
                }
-               if (copy_to_user((u16 *)arg, &val16, sizeof(val16)))
+               if (copy_to_user(argp, &val16, sizeof(val16)))
                        ret = -EFAULT;
                break;
        case SONYPI_IOCGBAT2CAP:
@@ -546,7 +548,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
                        ret = -EIO;
                        break;
                }
-               if (copy_to_user((u16 *)arg, &val16, sizeof(val16)))
+               if (copy_to_user(argp, &val16, sizeof(val16)))
                        ret = -EFAULT;
                break;
        case SONYPI_IOCGBAT2REM:
@@ -554,7 +556,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
                        ret = -EIO;
                        break;
                }
-               if (copy_to_user((u16 *)arg, &val16, sizeof(val16)))
+               if (copy_to_user(argp, &val16, sizeof(val16)))
                        ret = -EFAULT;
                break;
        case SONYPI_IOCGBATFLAGS:
@@ -563,16 +565,16 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
                        break;
                }
                val8 &= 0x07;
-               if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
+               if (copy_to_user(argp, &val8, sizeof(val8)))
                        ret = -EFAULT;
                break;
        case SONYPI_IOCGBLUE:
                val8 = sonypi_device.bluetooth_power;
-               if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
+               if (copy_to_user(argp, &val8, sizeof(val8)))
                        ret = -EFAULT;
                break;
        case SONYPI_IOCSBLUE:
-               if (copy_from_user(&val8, (u8 *)arg, sizeof(val8))) {
+               if (copy_from_user(&val8, argp, sizeof(val8))) {
                        ret = -EFAULT;
                        break;
                }
index deefd71..89f04b7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/char/synclink.c
  *
- * $Id: synclink.c,v 4.21 2004/03/08 15:29:22 paulkf Exp $
+ * $Id: synclink.c,v 4.24 2004/06/03 14:50:09 paulkf Exp $
  *
  * Device driver for Microgate SyncLink ISA and PCI
  * high speed multiprotocol serial adapters.
@@ -782,7 +782,6 @@ int mgsl_claim_resources(struct mgsl_struct *info);
 void mgsl_release_resources(struct mgsl_struct *info);
 void mgsl_add_device(struct mgsl_struct *info);
 struct mgsl_struct* mgsl_allocate_device(void);
-int mgsl_enum_isa_devices(void);
 
 /*
  * DMA buffer manupulation functions.
@@ -853,19 +852,22 @@ static int tiocmget(struct tty_struct *tty, struct file *file);
 static int tiocmset(struct tty_struct *tty, struct file *file,
                    unsigned int set, unsigned int clear);
 static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount
-       *user_icount);
-static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS *user_params);
-static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS *new_params);
-static int mgsl_get_txidle(struct mgsl_struct * info, int*idle_mode);
+       __user *user_icount);
+static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS  __user *user_params);
+static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS  __user *new_params);
+static int mgsl_get_txidle(struct mgsl_struct * info, int __user *idle_mode);
 static int mgsl_set_txidle(struct mgsl_struct * info, int idle_mode);
 static int mgsl_txenable(struct mgsl_struct * info, int enable);
 static int mgsl_txabort(struct mgsl_struct * info);
 static int mgsl_rxenable(struct mgsl_struct * info, int enable);
-static int mgsl_wait_event(struct mgsl_struct * info, int mask);
+static int mgsl_wait_event(struct mgsl_struct * info, int __user *mask);
 static int mgsl_loopmode_send_done( struct mgsl_struct * info );
 
 #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
 
+/* set non-zero on successful registration with PCI subsystem */
+static int pci_registered;
+
 /*
  * Global linked list of SyncLink devices
  */
@@ -909,7 +911,7 @@ MODULE_PARM(txdmabufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
 MODULE_PARM(txholdbufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
 
 static char *driver_name = "SyncLink serial driver";
-static char *driver_version = "$Revision: 4.21 $";
+static char *driver_version = "$Revision: 4.24 $";
 
 static int synclink_init_one (struct pci_dev *dev,
                                     const struct pci_device_id *ent);
@@ -950,8 +952,10 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout);
  * (gdb) to get the .text address for the add-symbol-file command.
  * This allows remote debugging of dynamically loadable modules.
  */
-void* mgsl_get_text_ptr(void);
-void* mgsl_get_text_ptr() {return mgsl_get_text_ptr;}
+void* mgsl_get_text_ptr(void)
+{
+       return mgsl_get_text_ptr;
+}
 
 /*
  * tmp_buf is used as a temporary buffer by mgsl_write.  We need to
@@ -2521,7 +2525,7 @@ static void mgsl_unthrottle(struct tty_struct * tty)
  *     
  * Return Value:       0 if success, otherwise error code
  */
-static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount *user_icount)
+static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount __user *user_icount)
 {
        int err;
        
@@ -2550,7 +2554,7 @@ static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount *user_ic
  *     
  * Return Value:       0 if success, otherwise error code
  */
-static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS *user_params)
+static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS __user *user_params)
 {
        int err;
        if (debug_level >= DEBUG_LEVEL_INFO)
@@ -2580,7 +2584,7 @@ static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS *user_params)
  *
  * Return Value:       0 if success, otherwise error code
  */
-static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS *new_params)
+static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS __user *new_params)
 {
        unsigned long flags;
        MGSL_PARAMS tmp_params;
@@ -2616,7 +2620,7 @@ static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS *new_params)
  *     
  * Return Value:       0 if success, otherwise error code
  */
-static int mgsl_get_txidle(struct mgsl_struct * info, int*idle_mode)
+static int mgsl_get_txidle(struct mgsl_struct * info, int __user *idle_mode)
 {
        int err;
        
@@ -2763,7 +2767,7 @@ static int mgsl_rxenable(struct mgsl_struct * info, int enable)
  *                             of events triggerred,
  *                     otherwise error code
  */
-static int mgsl_wait_event(struct mgsl_struct * info, int * mask_ptr)
+static int mgsl_wait_event(struct mgsl_struct * info, int __user * mask_ptr)
 {
        unsigned long flags;
        int s;
@@ -3051,16 +3055,17 @@ int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long
 {
        int error;
        struct mgsl_icount cnow;        /* kernel counter temps */
-       struct serial_icounter_struct *p_cuser; /* user space */
+       void __user *argp = (void __user *)arg;
+       struct serial_icounter_struct __user *p_cuser;  /* user space */
        unsigned long flags;
        
        switch (cmd) {
                case MGSL_IOCGPARAMS:
-                       return mgsl_get_params(info,(MGSL_PARAMS *)arg);
+                       return mgsl_get_params(info, argp);
                case MGSL_IOCSPARAMS:
-                       return mgsl_set_params(info,(MGSL_PARAMS *)arg);
+                       return mgsl_set_params(info, argp);
                case MGSL_IOCGTXIDLE:
-                       return mgsl_get_txidle(info,(int*)arg);
+                       return mgsl_get_txidle(info, argp);
                case MGSL_IOCSTXIDLE:
                        return mgsl_set_txidle(info,(int)arg);
                case MGSL_IOCTXENABLE:
@@ -3070,9 +3075,9 @@ int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long
                case MGSL_IOCTXABORT:
                        return mgsl_txabort(info);
                case MGSL_IOCGSTATS:
-                       return mgsl_get_stats(info,(struct mgsl_icount*)arg);
+                       return mgsl_get_stats(info, argp);
                case MGSL_IOCWAITEVENT:
-                       return mgsl_wait_event(info,(int*)arg);
+                       return mgsl_wait_event(info, argp);
                case MGSL_IOCLOOPTXDONE:
                        return mgsl_loopmode_send_done(info);
                /* Wait for modem input (DCD,RI,DSR,CTS) change
@@ -3091,7 +3096,7 @@ int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long
                        spin_lock_irqsave(&info->irq_spinlock,flags);
                        cnow = info->icount;
                        spin_unlock_irqrestore(&info->irq_spinlock,flags);
-                       p_cuser = (struct serial_icounter_struct *) arg;
+                       p_cuser = argp;
                        PUT_USER(error,cnow.cts, &p_cuser->cts);
                        if (error) return error;
                        PUT_USER(error,cnow.dsr, &p_cuser->dsr);
@@ -4425,7 +4430,7 @@ void mgsl_add_device( struct mgsl_struct *info )
  * Arguments:          none
  * Return Value:       pointer to mgsl_struct if success, otherwise NULL
  */
-struct mgsl_struct* mgsl_allocate_device()
+struct mgsl_struct* mgsl_allocate_device(void)
 {
        struct mgsl_struct *info;
        
@@ -4484,10 +4489,11 @@ static struct tty_operations mgsl_ops = {
 /*
  * perform tty device initialization
  */
-int mgsl_init_tty(void);
-int mgsl_init_tty()
+static int mgsl_init_tty(void)
 {
-       serial_driver = alloc_tty_driver(mgsl_device_count);
+       int rc;
+
+       serial_driver = alloc_tty_driver(128);
        if (!serial_driver)
                return -ENOMEM;
        
@@ -4503,9 +4509,13 @@ int mgsl_init_tty()
                B9600 | CS8 | CREAD | HUPCL | CLOCAL;
        serial_driver->flags = TTY_DRIVER_REAL_RAW;
        tty_set_operations(serial_driver, &mgsl_ops);
-       if (tty_register_driver(serial_driver) < 0)
+       if ((rc = tty_register_driver(serial_driver)) < 0) {
                printk("%s(%d):Couldn't register serial driver\n",
                        __FILE__,__LINE__);
+               put_tty_driver(serial_driver);
+               serial_driver = NULL;
+               return rc;
+       }
                        
        printk("%s %s, tty major#%d\n",
                driver_name, driver_version,
@@ -4515,7 +4525,7 @@ int mgsl_init_tty()
 
 /* enumerate user specified ISA adapters
  */
-int mgsl_enum_isa_devices()
+static void mgsl_enum_isa_devices(void)
 {
        struct mgsl_struct *info;
        int i;
@@ -4546,51 +4556,9 @@ int mgsl_enum_isa_devices()
                
                mgsl_add_device( info );
        }
-       
-       return 0;
 }
 
-/* mgsl_init()
- * 
- *     Driver initialization entry point.
- *     
- * Arguments:  None
- * Return Value:       0 if success, otherwise error code
- */
-int __init mgsl_init(void)
-{
-       int rc;
-
-       printk("%s %s\n", driver_name, driver_version);
-       
-       mgsl_enum_isa_devices();
-       pci_register_driver(&synclink_pci_driver);
-
-       if ( !mgsl_device_list ) {
-               printk("%s(%d):No SyncLink devices found.\n",__FILE__,__LINE__);
-               return -ENODEV;
-       }
-       if ((rc = mgsl_init_tty()))
-               return rc;
-       
-       return 0;
-}
-
-static int __init synclink_init(void)
-{
-/* Uncomment this to kernel debug module.
- * mgsl_get_text_ptr() leaves the .text address in eax
- * which can be used with add-symbol-file with gdb.
- */
-       if (break_on_load) {
-               mgsl_get_text_ptr();
-               BREAKPOINT();
-       }
-       
-       return mgsl_init();
-}
-
-static void __exit synclink_exit(void) 
+static void synclink_cleanup(void)
 {
        int rc;
        struct mgsl_struct *info;
@@ -4598,11 +4566,13 @@ static void __exit synclink_exit(void)
 
        printk("Unloading %s: %s\n", driver_name, driver_version);
 
-       if ((rc = tty_unregister_driver(serial_driver)))
-               printk("%s(%d) failed to unregister tty driver err=%d\n",
-                      __FILE__,__LINE__,rc);
+       if (serial_driver) {
+               if ((rc = tty_unregister_driver(serial_driver)))
+                       printk("%s(%d) failed to unregister tty driver err=%d\n",
+                              __FILE__,__LINE__,rc);
+               put_tty_driver(serial_driver);
+       }
 
-       put_tty_driver(serial_driver);
        info = mgsl_device_list;
        while(info) {
 #ifdef CONFIG_SYNCLINK_SYNCPPP
@@ -4620,7 +4590,40 @@ static void __exit synclink_exit(void)
                tmp_buf = NULL;
        }
        
-       pci_unregister_driver(&synclink_pci_driver);
+       if (pci_registered)
+               pci_unregister_driver(&synclink_pci_driver);
+}
+
+static int __init synclink_init(void)
+{
+       int rc;
+
+       if (break_on_load) {
+               mgsl_get_text_ptr();
+               BREAKPOINT();
+       }
+
+       printk("%s %s\n", driver_name, driver_version);
+
+       mgsl_enum_isa_devices();
+       if ((rc = pci_register_driver(&synclink_pci_driver)) < 0)
+               printk("%s:failed to register PCI driver, error=%d\n",__FILE__,rc);
+       else
+               pci_registered = 1;
+
+       if ((rc = mgsl_init_tty()) < 0)
+               goto error;
+
+       return 0;
+
+error:
+       synclink_cleanup();
+       return rc;
+}
+
+static void __exit synclink_exit(void)
+{
+       synclink_cleanup();
 }
 
 module_init(synclink_init);
index d82335e..eec8815 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: synclinkmp.c,v 4.19 2004/03/08 15:29:23 paulkf Exp $
+ * $Id: synclinkmp.c,v 4.22 2004/06/03 14:50:10 paulkf Exp $
  *
  * Device driver for Microgate SyncLink Multiport
  * high speed multiprotocol serial adapter.
@@ -494,7 +494,7 @@ MODULE_PARM(maxframe,"1-" __MODULE_STRING(MAX_DEVICES) "i");
 MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICES) "i");
 
 static char *driver_name = "SyncLink MultiPort driver";
-static char *driver_version = "$Revision: 4.19 $";
+static char *driver_version = "$Revision: 4.22 $";
 
 static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent);
 static void synclinkmp_remove_one(struct pci_dev *dev);
@@ -567,17 +567,17 @@ static struct net_device_stats *sppp_cb_net_stats(struct net_device *dev);
 
 /* ioctl handlers */
 
-static int  get_stats(SLMP_INFO *info, struct mgsl_icount *user_icount);
-static int  get_params(SLMP_INFO *info, MGSL_PARAMS *params);
-static int  set_params(SLMP_INFO *info, MGSL_PARAMS *params);
-static int  get_txidle(SLMP_INFO *info, int*idle_mode);
+static int  get_stats(SLMP_INFO *info, struct mgsl_icount __user *user_icount);
+static int  get_params(SLMP_INFO *info, MGSL_PARAMS __user *params);
+static int  set_params(SLMP_INFO *info, MGSL_PARAMS __user *params);
+static int  get_txidle(SLMP_INFO *info, int __user *idle_mode);
 static int  set_txidle(SLMP_INFO *info, int idle_mode);
 static int  tx_enable(SLMP_INFO *info, int enable);
 static int  tx_abort(SLMP_INFO *info);
 static int  rx_enable(SLMP_INFO *info, int enable);
 static int  map_status(int signals);
 static int  modem_input_wait(SLMP_INFO *info,int arg);
-static int  wait_mgsl_event(SLMP_INFO *info, int *mask_ptr);
+static int  wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr);
 static int  tiocmget(struct tty_struct *tty, struct file *file);
 static int  tiocmset(struct tty_struct *tty, struct file *file,
                     unsigned int set, unsigned int clear);
@@ -692,7 +692,7 @@ static u32 sca_pci_load_interval = 64;
  * This allows remote debugging of dynamically loadable modules.
  */
 static void* synclinkmp_get_text_ptr(void);
-static void* synclinkmp_get_text_ptr() {return synclinkmp_get_text_ptr;}
+static void* synclinkmp_get_text_ptr(void) {return synclinkmp_get_text_ptr;}
 
 static inline int sanity_check(SLMP_INFO *info,
                               char *name, const char *routine)
@@ -1333,8 +1333,9 @@ static int ioctl(struct tty_struct *tty, struct file *file,
        SLMP_INFO *info = (SLMP_INFO *)tty->driver_data;
        int error;
        struct mgsl_icount cnow;        /* kernel counter temps */
-       struct serial_icounter_struct *p_cuser; /* user space */
+       struct serial_icounter_struct __user *p_cuser;  /* user space */
        unsigned long flags;
+       void __user *argp = (void __user *)arg;
 
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("%s(%d):%s ioctl() cmd=%08X\n", __FILE__,__LINE__,
@@ -1351,23 +1352,23 @@ static int ioctl(struct tty_struct *tty, struct file *file,
 
        switch (cmd) {
        case MGSL_IOCGPARAMS:
-               return get_params(info,(MGSL_PARAMS *)arg);
+               return get_params(info, argp);
        case MGSL_IOCSPARAMS:
-               return set_params(info,(MGSL_PARAMS *)arg);
+               return set_params(info, argp);
        case MGSL_IOCGTXIDLE:
-               return get_txidle(info,(int*)arg);
+               return get_txidle(info, argp);
        case MGSL_IOCSTXIDLE:
-               return set_txidle(info,(int)arg);
+               return set_txidle(info, (int)arg);
        case MGSL_IOCTXENABLE:
-               return tx_enable(info,(int)arg);
+               return tx_enable(info, (int)arg);
        case MGSL_IOCRXENABLE:
-               return rx_enable(info,(int)arg);
+               return rx_enable(info, (int)arg);
        case MGSL_IOCTXABORT:
                return tx_abort(info);
        case MGSL_IOCGSTATS:
-               return get_stats(info,(struct mgsl_icount*)arg);
+               return get_stats(info, argp);
        case MGSL_IOCWAITEVENT:
-               return wait_mgsl_event(info,(int*)arg);
+               return wait_mgsl_event(info, argp);
        case MGSL_IOCLOOPTXDONE:
                return 0; // TODO: Not supported, need to document
                /* Wait for modem input (DCD,RI,DSR,CTS) change
@@ -1386,7 +1387,7 @@ static int ioctl(struct tty_struct *tty, struct file *file,
                spin_lock_irqsave(&info->lock,flags);
                cnow = info->icount;
                spin_unlock_irqrestore(&info->lock,flags);
-               p_cuser = (struct serial_icounter_struct *) arg;
+               p_cuser = argp;
                PUT_USER(error,cnow.cts, &p_cuser->cts);
                if (error) return error;
                PUT_USER(error,cnow.dsr, &p_cuser->dsr);
@@ -2762,7 +2763,7 @@ static void change_params(SLMP_INFO *info)
        program_hw(info);
 }
 
-static int get_stats(SLMP_INFO * info, struct mgsl_icount *user_icount)
+static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount)
 {
        int err;
 
@@ -2781,7 +2782,7 @@ static int get_stats(SLMP_INFO * info, struct mgsl_icount *user_icount)
        return 0;
 }
 
-static int get_params(SLMP_INFO * info, MGSL_PARAMS *user_params)
+static int get_params(SLMP_INFO * info, MGSL_PARAMS __user *user_params)
 {
        int err;
        if (debug_level >= DEBUG_LEVEL_INFO)
@@ -2799,7 +2800,7 @@ static int get_params(SLMP_INFO * info, MGSL_PARAMS *user_params)
        return 0;
 }
 
-static int set_params(SLMP_INFO * info, MGSL_PARAMS *new_params)
+static int set_params(SLMP_INFO * info, MGSL_PARAMS __user *new_params)
 {
        unsigned long flags;
        MGSL_PARAMS tmp_params;
@@ -2825,7 +2826,7 @@ static int set_params(SLMP_INFO * info, MGSL_PARAMS *new_params)
        return 0;
 }
 
-static int get_txidle(SLMP_INFO * info, int*idle_mode)
+static int get_txidle(SLMP_INFO * info, int __user *idle_mode)
 {
        int err;
 
@@ -2938,7 +2939,7 @@ static int map_status(int signals)
 
 /* wait for specified event to occur
  */
-static int wait_mgsl_event(SLMP_INFO * info, int mask_ptr)
+static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr)
 {
        unsigned long flags;
        int s;
@@ -3781,56 +3782,7 @@ static struct tty_operations ops = {
        .tiocmset = tiocmset,
 };
 
-/* Driver initialization entry point.
- */
-
-static int __init synclinkmp_init(void)
-{
-       if (break_on_load) {
-               synclinkmp_get_text_ptr();
-               BREAKPOINT();
-       }
-
-       printk("%s %s\n", driver_name, driver_version);
-
-       synclinkmp_adapter_count = -1;
-       pci_register_driver(&synclinkmp_pci_driver);
-
-       if ( !synclinkmp_device_list ) {
-               printk("%s(%d):No SyncLink devices found.\n",__FILE__,__LINE__);
-               return -ENODEV;
-       }
-
-       serial_driver = alloc_tty_driver(synclinkmp_device_count);
-       if (!serial_driver)
-               return -ENOMEM;
-
-       /* Initialize the tty_driver structure */
-
-       serial_driver->owner = THIS_MODULE;
-       serial_driver->driver_name = "synclinkmp";
-       serial_driver->name = "ttySLM";
-       serial_driver->major = ttymajor;
-       serial_driver->minor_start = 64;
-       serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
-       serial_driver->subtype = SERIAL_TYPE_NORMAL;
-       serial_driver->init_termios = tty_std_termios;
-       serial_driver->init_termios.c_cflag =
-               B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-       serial_driver->flags = TTY_DRIVER_REAL_RAW;
-       tty_set_operations(serial_driver, &ops);
-       if (tty_register_driver(serial_driver) < 0)
-               printk("%s(%d):Couldn't register serial driver\n",
-                       __FILE__,__LINE__);
-
-       printk("%s %s, tty major#%d\n",
-               driver_name, driver_version,
-               serial_driver->major);
-
-       return 0;
-}
-
-static void __exit synclinkmp_exit(void)
+static void synclinkmp_cleanup(void)
 {
        unsigned long flags;
        int rc;
@@ -3839,10 +3791,12 @@ static void __exit synclinkmp_exit(void)
 
        printk("Unloading %s %s\n", driver_name, driver_version);
 
-       if ((rc = tty_unregister_driver(serial_driver)))
-               printk("%s(%d) failed to unregister tty driver err=%d\n",
-                      __FILE__,__LINE__,rc);
-       put_tty_driver(serial_driver);
+       if (serial_driver) {
+               if ((rc = tty_unregister_driver(serial_driver)))
+                       printk("%s(%d) failed to unregister tty driver err=%d\n",
+                              __FILE__,__LINE__,rc);
+               put_tty_driver(serial_driver);
+       }
 
        info = synclinkmp_device_list;
        while(info) {
@@ -3882,6 +3836,69 @@ static void __exit synclinkmp_exit(void)
        pci_unregister_driver(&synclinkmp_pci_driver);
 }
 
+/* Driver initialization entry point.
+ */
+
+static int __init synclinkmp_init(void)
+{
+       int rc;
+
+       if (break_on_load) {
+               synclinkmp_get_text_ptr();
+               BREAKPOINT();
+       }
+
+       printk("%s %s\n", driver_name, driver_version);
+
+       if ((rc = pci_register_driver(&synclinkmp_pci_driver)) < 0) {
+               printk("%s:failed to register PCI driver, error=%d\n",__FILE__,rc);
+               return rc;
+       }
+
+       serial_driver = alloc_tty_driver(128);
+       if (!serial_driver) {
+               rc = -ENOMEM;
+               goto error;
+       }
+
+       /* Initialize the tty_driver structure */
+
+       serial_driver->owner = THIS_MODULE;
+       serial_driver->driver_name = "synclinkmp";
+       serial_driver->name = "ttySLM";
+       serial_driver->major = ttymajor;
+       serial_driver->minor_start = 64;
+       serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
+       serial_driver->subtype = SERIAL_TYPE_NORMAL;
+       serial_driver->init_termios = tty_std_termios;
+       serial_driver->init_termios.c_cflag =
+               B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+       serial_driver->flags = TTY_DRIVER_REAL_RAW;
+       tty_set_operations(serial_driver, &ops);
+       if ((rc = tty_register_driver(serial_driver)) < 0) {
+               printk("%s(%d):Couldn't register serial driver\n",
+                       __FILE__,__LINE__);
+               put_tty_driver(serial_driver);
+               serial_driver = NULL;
+               goto error;
+       }
+
+       printk("%s %s, tty major#%d\n",
+               driver_name, driver_version,
+               serial_driver->major);
+
+       return 0;
+
+error:
+       synclinkmp_cleanup();
+       return rc;
+}
+
+static void __exit synclinkmp_exit(void)
+{
+       synclinkmp_cleanup();
+}
+
 module_init(synclinkmp_init);
 module_exit(synclinkmp_exit);
 
index 15e2c72..5b84af0 100644 (file)
@@ -251,13 +251,14 @@ static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
        unsigned long arg)
 {
        SMMRegisters regs;
+       SMMRegisters __user *argp = (SMMRegisters __user *)arg;
        unsigned short ax,bx;
        int err;
 
-       if (!arg)
+       if (!argp)
                return -EINVAL;
 
-       if (copy_from_user(&regs, (SMMRegisters *) arg, sizeof(SMMRegisters)))
+       if (copy_from_user(&regs, argp, sizeof(SMMRegisters)))
                return -EFAULT;
 
        switch (cmd) {
@@ -281,7 +282,7 @@ static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                        return -EINVAL;
        }
 
-        if (copy_to_user((SMMRegisters *) arg, &regs, sizeof(SMMRegisters)))
+        if (copy_to_user(argp, &regs, sizeof(SMMRegisters)))
                return -EFAULT;
 
        return (err==0) ? 0:-EINVAL;
index 698c2c4..6ee95af 100644 (file)
@@ -1727,7 +1727,7 @@ static irqreturn_t qic02_tape_interrupt(int irq, void *dev_id,
  * request would return the EOF flag for the previous file.
  */
 
-static ssize_t qic02_tape_read(struct file *filp, char *buf, size_t count, loff_t * ppos)
+static ssize_t qic02_tape_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
 {
        int type = iminor(filp->f_dentry->d_inode);
        unsigned short flags = filp->f_flags;
@@ -1905,7 +1905,7 @@ static ssize_t qic02_tape_read(struct file *filp, char *buf, size_t count, loff_
  * tape device again. The driver will detect an exception status in (No Cartridge)
  * and force a rewind. After that tar may continue writing.
  */
-static ssize_t qic02_tape_write(struct file *filp, const char *buf, size_t count, loff_t * ppos)
+static ssize_t qic02_tape_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
 {
        int type = iminor(filp->f_dentry->d_inode);
        unsigned short flags = filp->f_flags;
@@ -2400,6 +2400,7 @@ static int qic02_tape_ioctl(struct inode *inode, struct file *filp, unsigned int
        struct mtop operation;
        unsigned char blk_addr[6];
        struct mtpos ioctl_tell;
+       void __user *argp = (void __user *)ioarg;
 
 
        if (TP_DIAGS(current_type))
@@ -2416,7 +2417,7 @@ static int qic02_tape_ioctl(struct inode *inode, struct file *filp, unsigned int
        if (c == _IOC_NR(MTIOCGETCONFIG)) {
                CHECK_IOC_SIZE(mtconfiginfo);
 
-               if (copy_to_user((char *) ioarg, (char *) &qic02_tape_dynconf, sizeof(qic02_tape_dynconf)))
+               if (copy_to_user(argp, &qic02_tape_dynconf, sizeof(qic02_tape_dynconf)))
                        return -EFAULT;
                return 0;
        } else if (c == _IOC_NR(MTIOCSETCONFIG)) {
@@ -2438,7 +2439,7 @@ static int qic02_tape_ioctl(struct inode *inode, struct file *filp, unsigned int
                        qic02_release_resources();      /* and go zombie */
 
                /* copy struct from user space to kernel space */
-               if (copy_from_user((char *) &qic02_tape_dynconf, (char *) ioarg, sizeof(qic02_tape_dynconf)))
+               if (copy_from_user(&qic02_tape_dynconf, argp, sizeof(qic02_tape_dynconf)))
                        return -EFAULT;
                
                return update_ifc_masks(qic02_tape_dynconf.ifc_type);
@@ -2452,7 +2453,7 @@ static int qic02_tape_ioctl(struct inode *inode, struct file *filp, unsigned int
                CHECK_IOC_SIZE(mtop);
 
                /* copy mtop struct from user space to kernel space */
-               if (copy_from_user((char *) &operation, (char *) ioarg, sizeof(operation)))
+               if (copy_from_user(&operation, argp, sizeof(operation)))
                        return -EFAULT;
 
                /* ---note: mt_count is signed, negative seeks must be
@@ -2507,7 +2508,7 @@ static int qic02_tape_ioctl(struct inode *inode, struct file *filp, unsigned int
                 */
 
                /* copy results to user space */
-               if (copy_to_user((char *) ioarg, (char *) &ioctl_status, sizeof(ioctl_status)))
+               if (copy_to_user(argp, &ioctl_status, sizeof(ioctl_status)))
                        return -EFAULT;
                return 0;
        } else if (TP_HAVE_TELL && (c == _IOC_NR(MTIOCPOS))) {
@@ -2527,7 +2528,7 @@ static int qic02_tape_ioctl(struct inode *inode, struct file *filp, unsigned int
                ioctl_tell.mt_blkno = (blk_addr[3] << 16) | (blk_addr[4] << 8) | blk_addr[5];
 
                /* copy results to user space */
-               if (copy_to_user((char *) ioarg, (char *) &ioctl_tell, sizeof(ioctl_tell)))
+               if (copy_to_user(argp, &ioctl_tell, sizeof(ioctl_tell)))
                        return -EFAULT;
                return 0;
 
@@ -2536,7 +2537,7 @@ static int qic02_tape_ioctl(struct inode *inode, struct file *filp, unsigned int
 }                              /* qic02_tape_ioctl */
 
 
-static ssize_t qic02_do_tape_read(struct file *filp, char *buf, size_t count, loff_t * ppos)
+static ssize_t qic02_do_tape_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
 {
        int err;
        
@@ -2547,7 +2548,7 @@ static ssize_t qic02_do_tape_read(struct file *filp, char *buf, size_t count, lo
        return err;
 }
 
-static ssize_t qic02_do_tape_write(struct file *filp, const char *buf, size_t count, loff_t * ppos)
+static ssize_t qic02_do_tape_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
 {
        int err;
 
index 0c76237..280be2c 100644 (file)
@@ -91,6 +91,7 @@
 #include <linux/module.h>
 #include <linux/smp_lock.h>
 #include <linux/device.h>
+#include <linux/idr.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -128,6 +129,8 @@ DECLARE_MUTEX(tty_sem);
 #ifdef CONFIG_UNIX98_PTYS
 extern struct tty_driver *ptm_driver;  /* Unix98 pty masters; for /dev/ptmx */
 extern int pty_limit;          /* Config limit on Unix98 ptys */
+static DEFINE_IDR(allocated_ptys);
+static DECLARE_MUTEX(allocated_ptys_lock);
 #endif
 
 extern void disable_early_printk(void);
@@ -1065,6 +1068,7 @@ static void release_dev(struct file * filp)
 {
        struct tty_struct *tty, *o_tty;
        int     pty_master, tty_closing, o_tty_closing, do_sleep;
+       int     devpts_master;
        int     idx;
        char    buf[64];
        
@@ -1079,6 +1083,7 @@ static void release_dev(struct file * filp)
        idx = tty->index;
        pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
                      tty->driver->subtype == PTY_TYPE_MASTER);
+       devpts_master = pty_master && (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM);
        o_tty = tty->link;
 
 #ifdef TTY_PARANOIA_CHECK
@@ -1295,11 +1300,21 @@ static void release_dev(struct file * filp)
                o_tty->ldisc = ldiscs[N_TTY];
        }
 
-       /* 
+       /*
         * The release_mem function takes care of the details of clearing
         * the slots and preserving the termios structure.
         */
        release_mem(tty, idx);
+
+#ifdef CONFIG_UNIX98_PTYS
+       /* Make this pty number available for reallocation */
+       if (devpts_master) {
+               down(&allocated_ptys_lock);
+               idr_remove(&allocated_ptys, idx);
+               up(&allocated_ptys_lock);
+       }
+#endif
+
 }
 
 /*
@@ -1322,8 +1337,12 @@ static int tty_open(struct inode * inode, struct file * filp)
        int index;
        dev_t device = inode->i_rdev;
        unsigned short saved_flags = filp->f_flags;
+
 retry_open:
        noctty = filp->f_flags & O_NOCTTY;
+       index  = -1;
+       retval = 0;
+
        if (device == MKDEV(TTYAUX_MAJOR,0)) {
                if (!current->signal->tty)
                        return -ENXIO;
@@ -1361,24 +1380,40 @@ retry_open:
 
 #ifdef CONFIG_UNIX98_PTYS
        if (device == MKDEV(TTYAUX_MAJOR,2)) {
+               int idr_ret;
+
                /* find a device that is not in use. */
-               static int next_ptmx_dev = 0;
-               retval = -1;
+               down(&allocated_ptys_lock);
+               if (!idr_pre_get(&allocated_ptys, GFP_KERNEL)) {
+                       up(&allocated_ptys_lock);
+                       return -ENOMEM;
+               }
+               idr_ret = idr_get_new(&allocated_ptys, NULL, &index);
+               if (idr_ret < 0) {
+                       up(&allocated_ptys_lock);
+                       if (idr_ret == -EAGAIN)
+                               return -ENOMEM;
+                       return -EIO;
+               }
+               if (index >= pty_limit) {
+                       idr_remove(&allocated_ptys, index);
+                       up(&allocated_ptys_lock);
+                       return -EIO;
+               }
+               up(&allocated_ptys_lock);
+
                driver = ptm_driver;
-               while (driver->refcount < pty_limit) {
-                       index = next_ptmx_dev;
-                       next_ptmx_dev = (next_ptmx_dev+1) % driver->num;
-                       if (!init_dev(driver, index, &tty))
-                               goto ptmx_found; /* ok! */
+               retval = init_dev(driver, index, &tty);
+               if (retval) {
+                       down(&allocated_ptys_lock);
+                       idr_remove(&allocated_ptys, index);
+                       up(&allocated_ptys_lock);
+                       return retval;
                }
-               return -EIO; /* no free ptys */
-       ptmx_found:
+
                set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
-               if (devpts_pty_new(tty->link)) {
-                       /* BADNESS - need to destroy both ptm and pts! */
-                       return -ENOMEM;
-               }
-               noctty = 1;
+               if (devpts_pty_new(tty->link))
+                       retval = -ENOMEM;
        } else
 #endif
        {
@@ -1400,10 +1435,12 @@ got_driver:
 #ifdef TTY_DEBUG_HANGUP
        printk(KERN_DEBUG "opening %s...", tty->name);
 #endif
-       if (tty->driver->open)
-               retval = tty->driver->open(tty, filp);
-       else
-               retval = -ENODEV;
+       if (!retval) {
+               if (tty->driver->open)
+                       retval = tty->driver->open(tty, filp);
+               else
+                       retval = -ENODEV;
+       }
        filp->f_flags = saved_flags;
 
        if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN))
@@ -1415,6 +1452,14 @@ got_driver:
                       tty->name);
 #endif
 
+#ifdef CONFIG_UNIX98_PTYS
+               if (index != -1) {
+                       down(&allocated_ptys_lock);
+                       idr_remove(&allocated_ptys, index);
+                       up(&allocated_ptys_lock);
+               }
+#endif
+
                release_dev(filp);
                if (retval != -ERESTARTSYS)
                        return retval;
index acb25de..2febb25 100644 (file)
@@ -111,7 +111,7 @@ static void acq_stop(void)
  *     /dev/watchdog handling.
  */
 
-static ssize_t acq_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
        /*  Can't seek (pwrite) on this device  */
        if (ppos != &file->f_pos)
@@ -146,6 +146,8 @@ static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        unsigned long arg)
 {
        int options, retval = -EINVAL;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident =
        {
                .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
@@ -156,22 +158,22 @@ static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        switch(cmd)
        {
        case WDIOC_GETSUPPORT:
-         return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)) ? -EFAULT : 0;
+         return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
 
        case WDIOC_GETSTATUS:
        case WDIOC_GETBOOTSTATUS:
-         return put_user(0, (int *)arg);
+         return put_user(0, p);
 
        case WDIOC_KEEPALIVE:
          acq_keepalive();
          return 0;
 
        case WDIOC_GETTIMEOUT:
-         return put_user(WATCHDOG_HEARTBEAT, (int *)arg);
+         return put_user(WATCHDOG_HEARTBEAT, p);
 
        case WDIOC_SETOPTIONS:
        {
-           if (get_user(options, (int *)arg))
+           if (get_user(options, p))
              return -EFAULT;
 
            if (options & WDIOS_DISABLECARD)
index a92b3ae..4090794 100644 (file)
@@ -100,7 +100,7 @@ advwdt_disable(void)
 }
 
 static ssize_t
-advwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
        /*  Can't seek (pwrite) on this device  */
        if (ppos != &file->f_pos)
@@ -130,6 +130,8 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
          unsigned long arg)
 {
        int new_timeout;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident = {
                .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
                .firmware_version = 1,
@@ -138,20 +140,20 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
        switch (cmd) {
        case WDIOC_GETSUPPORT:
-         if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
+         if (copy_to_user(argp, &ident, sizeof(ident)))
            return -EFAULT;
          break;
 
        case WDIOC_GETSTATUS:
        case WDIOC_GETBOOTSTATUS:
-         return put_user(0, (int *)arg);
+         return put_user(0, p);
 
        case WDIOC_KEEPALIVE:
          advwdt_ping();
          break;
 
        case WDIOC_SETTIMEOUT:
-         if (get_user(new_timeout, (int *)arg))
+         if (get_user(new_timeout, p))
                  return -EFAULT;
          if ((new_timeout < 1) || (new_timeout > 63))
                  return -EINVAL;
@@ -160,13 +162,13 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
          /* Fall */
 
        case WDIOC_GETTIMEOUT:
-         return put_user(timeout, (int *)arg);
+         return put_user(timeout, p);
 
        case WDIOC_SETOPTIONS:
        {
          int options, retval = -EINVAL;
 
-         if (get_user(options, (int *)arg))
+         if (get_user(options, p))
            return -EFAULT;
 
          if (options & WDIOS_DISABLECARD) {
index 9a3207d..f093a69 100644 (file)
@@ -138,7 +138,7 @@ static int ali_settimer(int t)
  *     the next close to turn off the watchdog.
  */
 
-static ssize_t ali_write(struct file *file, const char *data,
+static ssize_t ali_write(struct file *file, const char __user *data,
                              size_t len, loff_t * ppos)
 {
        /*  Can't seek (pwrite) on this device  */
@@ -184,6 +184,8 @@ static ssize_t ali_write(struct file *file, const char *data,
 static int ali_ioctl(struct inode *inode, struct file *file,
                          unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident = {
                .options =              WDIOF_KEEPALIVEPING |
                                        WDIOF_SETTIMEOUT |
@@ -194,12 +196,12 @@ static int ali_ioctl(struct inode *inode, struct file *file,
 
        switch (cmd) {
                case WDIOC_GETSUPPORT:
-                       return copy_to_user((struct watchdog_info *) arg, &ident,
+                       return copy_to_user(argp, &ident,
                                sizeof (ident)) ? -EFAULT : 0;
 
                case WDIOC_GETSTATUS:
                case WDIOC_GETBOOTSTATUS:
-                       return put_user(0, (int *) arg);
+                       return put_user(0, p);
 
                case WDIOC_KEEPALIVE:
                        ali_keepalive();
@@ -209,7 +211,7 @@ static int ali_ioctl(struct inode *inode, struct file *file,
                {
                        int new_options, retval = -EINVAL;
 
-                       if (get_user (new_options, (int *) arg))
+                       if (get_user (new_options, p))
                                return -EFAULT;
 
                        if (new_options & WDIOS_DISABLECARD) {
@@ -229,7 +231,7 @@ static int ali_ioctl(struct inode *inode, struct file *file,
                {
                        int new_timeout;
 
-                       if (get_user(new_timeout, (int *) arg))
+                       if (get_user(new_timeout, p))
                                return -EFAULT;
 
                        if (ali_settimer(new_timeout))
@@ -240,7 +242,7 @@ static int ali_ioctl(struct inode *inode, struct file *file,
                }
 
                case WDIOC_GETTIMEOUT:
-                       return put_user(timeout, (int *)arg);
+                       return put_user(timeout, p);
 
                default:
                        return -ENOIOCTLCMD;
index 00baec9..c137cd3 100644 (file)
@@ -148,7 +148,7 @@ static void wdt_keepalive(void)
  * /dev/watchdog handling
  */
 
-static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos)
+static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos)
 {
        /* We can't seek */
        if(ppos != &file->f_pos)
@@ -203,6 +203,8 @@ static int fop_close(struct inode * inode, struct file * file)
 
 static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident =
        {
                .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
@@ -213,10 +215,10 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
        switch(cmd)
        {
                case WDIOC_GETSUPPORT:
-                       return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+                       return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
                case WDIOC_GETSTATUS:
                case WDIOC_GETBOOTSTATUS:
-                       return put_user(0, (int *)arg);
+                       return put_user(0, p);
                case WDIOC_KEEPALIVE:
                        wdt_keepalive();
                        return 0;
@@ -224,7 +226,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                {
                        int new_options, retval = -EINVAL;
 
-                       if(get_user(new_options, (int *)arg))
+                       if(get_user(new_options, p))
                                return -EFAULT;
 
                        if(new_options & WDIOS_DISABLECARD) {
@@ -243,7 +245,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                {
                        int new_timeout;
 
-                       if(get_user(new_timeout, (int *)arg))
+                       if(get_user(new_timeout, p))
                                return -EFAULT;
 
                        if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
@@ -254,7 +256,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                        /* Fall through */
                }
                case WDIOC_GETTIMEOUT:
-                       return put_user(timeout, (int *)arg);
+                       return put_user(timeout, p);
                default:
                        return -ENOIOCTLCMD;
        }
index dad804f..7e7b653 100644 (file)
@@ -145,6 +145,7 @@ static int cpu5wdt_release(struct inode *inode, struct file *file)
 
 static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
        unsigned int value;
        static struct watchdog_info ident =
        {
@@ -159,15 +160,15 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm
                case WDIOC_GETSTATUS:
                        value = inb(port + CPU5WDT_STATUS_REG);
                        value = (value >> 2) & 1;
-                       if ( copy_to_user((int *)arg, (int *)&value, sizeof(int)) )
+                       if ( copy_to_user(argp, &value, sizeof(int)) )
                                return -EFAULT;
                        break;
                case WDIOC_GETSUPPORT:
-                       if ( copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)) )
+                       if ( copy_to_user(argp, &ident, sizeof(ident)) )
                                return -EFAULT;
                        break;
                case WDIOC_SETOPTIONS:
-                       if ( copy_from_user(&value, (int *)arg, sizeof(int)) )
+                       if ( copy_from_user(&value, argp, sizeof(int)) )
                                return -EFAULT;
                        switch(value) {
                                case WDIOS_ENABLECARD:
@@ -185,7 +186,7 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm
        return 0;
 }
 
-static ssize_t cpu5wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
        if ( !count )
                return -EIO;
index ab28ca2..01df656 100644 (file)
@@ -196,8 +196,8 @@ static void eurwdt_ping(void)
  * write of data will do, as we we don't define content meaning.
  */
 
-static ssize_t eurwdt_write(struct file *file, const char *buf, size_t count,
-loff_t *ppos)
+static ssize_t eurwdt_write(struct file *file, const char __user *buf,
+size_t count, loff_t *ppos)
 {
        /*  Can't seek (pwrite) on this device  */
        if (ppos != &file->f_pos)
@@ -237,6 +237,8 @@ loff_t *ppos)
 static int eurwdt_ioctl(struct inode *inode, struct file *file,
        unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident = {
                .options          = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
                .firmware_version = 1,
@@ -251,19 +253,18 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
                return -ENOIOCTLCMD;
 
        case WDIOC_GETSUPPORT:
-               return copy_to_user((struct watchdog_info *)arg, &ident,
-                       sizeof(ident)) ? -EFAULT : 0;
+               return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
 
        case WDIOC_GETSTATUS:
        case WDIOC_GETBOOTSTATUS:
-               return put_user(0, (int *) arg);
+               return put_user(0, p);
 
        case WDIOC_KEEPALIVE:
                eurwdt_ping();
                return 0;
 
        case WDIOC_SETTIMEOUT:
-               if (copy_from_user(&time, (int *) arg, sizeof(int)))
+               if (copy_from_user(&time, p, sizeof(int)))
                        return -EFAULT;
 
                /* Sanity check */
@@ -275,10 +276,10 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
                /* Fall */
 
        case WDIOC_GETTIMEOUT:
-               return put_user(eurwdt_timeout, (int *)arg);
+               return put_user(eurwdt_timeout, p);
 
        case WDIOC_SETOPTIONS:
-               if (get_user(options, (int *)arg))
+               if (get_user(options, p))
                        return -EFAULT;
                if (options & WDIOS_DISABLECARD) {
                        eurwdt_disable_timer();
index efe3c1d..8a63f7f 100644 (file)
@@ -212,7 +212,7 @@ static int i8xx_tco_release (struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t i8xx_tco_write (struct file *file, const char *data,
+static ssize_t i8xx_tco_write (struct file *file, const char __user *data,
                              size_t len, loff_t * ppos)
 {
        /*  Can't seek (pwrite) on this device  */
@@ -249,6 +249,8 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file,
 {
        int new_options, retval = -EINVAL;
        int new_heartbeat;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident = {
                .options =              WDIOF_SETTIMEOUT |
                                        WDIOF_KEEPALIVEPING |
@@ -259,12 +261,12 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file,
 
        switch (cmd) {
                case WDIOC_GETSUPPORT:
-                       return copy_to_user((struct watchdog_info *) arg, &ident,
+                       return copy_to_user(argp, &ident,
                                sizeof (ident)) ? -EFAULT : 0;
 
                case WDIOC_GETSTATUS:
                case WDIOC_GETBOOTSTATUS:
-                       return put_user (0, (int *) arg);
+                       return put_user (0, p);
 
                case WDIOC_KEEPALIVE:
                        tco_timer_keepalive ();
@@ -272,7 +274,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file,
 
                case WDIOC_SETOPTIONS:
                {
-                       if (get_user (new_options, (int *) arg))
+                       if (get_user (new_options, p))
                                return -EFAULT;
 
                        if (new_options & WDIOS_DISABLECARD) {
@@ -291,7 +293,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file,
 
                case WDIOC_SETTIMEOUT:
                {
-                       if (get_user(new_heartbeat, (int *) arg))
+                       if (get_user(new_heartbeat, p))
                                return -EFAULT;
 
                        if (tco_timer_set_heartbeat(new_heartbeat))
@@ -302,7 +304,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file,
                }
 
                case WDIOC_GETTIMEOUT:
-                       return put_user(heartbeat, (int *)arg);
+                       return put_user(heartbeat, p);
 
                default:
                        return -ENOIOCTLCMD;
index 2e259a1..0d48439 100644 (file)
@@ -139,7 +139,7 @@ ibwdt_ping(void)
 }
 
 static ssize_t
-ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
        /*  Can't seek (pwrite) on this device  */
        if (ppos != &file->f_pos)
@@ -170,6 +170,8 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
          unsigned long arg)
 {
        int i, new_margin;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
 
        static struct watchdog_info ident = {
                .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
@@ -179,19 +181,19 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
        switch (cmd) {
        case WDIOC_GETSUPPORT:
-         if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
+         if (copy_to_user(argp, &ident, sizeof(ident)))
            return -EFAULT;
          break;
 
        case WDIOC_GETSTATUS:
-         return put_user(0, (int *) arg);
+         return put_user(0, p);
 
        case WDIOC_KEEPALIVE:
          ibwdt_ping();
          break;
 
        case WDIOC_SETTIMEOUT:
-         if (get_user(new_margin, (int *)arg))
+         if (get_user(new_margin, p))
                  return -EFAULT;
          if ((new_margin < 0) || (new_margin > 30))
                  return -EINVAL;
@@ -203,7 +205,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
          /* Fall */
 
        case WDIOC_GETTIMEOUT:
-         return put_user(wd_times[wd_margin], (int *)arg);
+         return put_user(wd_times[wd_margin], p);
          break;
 
        default:
index 99c6b21..e8dc517 100644 (file)
@@ -302,7 +302,7 @@ static void zf_ping(unsigned long data)
        }
 }
 
-static ssize_t zf_write(struct file *file, const char *buf, size_t count,
+static ssize_t zf_write(struct file *file, const char __user *buf, size_t count,
                                                                loff_t *ppos)
 {
        /*  Can't seek (pwrite) on this device  */
@@ -352,15 +352,16 @@ static ssize_t zf_write(struct file *file, const char *buf, size_t count,
 static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        switch(cmd){
                case WDIOC_GETSUPPORT:
-                       if (copy_to_user((struct watchdog_info *)arg,
-                                        &zf_info, sizeof(zf_info)))
+                       if (copy_to_user(argp, &zf_info, sizeof(zf_info)))
                                return -EFAULT;
                        break;
 
                case WDIOC_GETSTATUS:
-                       return put_user(0, (int *) arg);
+                       return put_user(0, p);
 
                case WDIOC_KEEPALIVE:
                        zf_ping(0);
index 6d3e7d5..2790f9c 100644 (file)
@@ -134,7 +134,7 @@ static int mixcomwd_release(struct inode *inode, struct file *file)
 }
 
 
-static ssize_t mixcomwd_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+static ssize_t mixcomwd_write(struct file *file, const char __user *data, size_t len, loff_t *ppos)
 {
        if (ppos != &file->f_pos) {
                return -ESPIPE;
@@ -164,6 +164,8 @@ static ssize_t mixcomwd_write(struct file *file, const char *data, size_t len, l
 static int mixcomwd_ioctl(struct inode *inode, struct file *file,
        unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        int status;
        static struct watchdog_info ident = {
                .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
@@ -178,13 +180,12 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
                        if (!nowayout) {
                                status|=mixcomwd_timer_alive;
                        }
-                       if (copy_to_user((int *)arg, &status, sizeof(int))) {
+                       if (copy_to_user(p, &status, sizeof(int))) {
                                return -EFAULT;
                        }
                        break;
                case WDIOC_GETSUPPORT:
-                       if (copy_to_user((struct watchdog_info *)arg, &ident,
-                           sizeof(ident))) {
+                       if (copy_to_user(argp, &ident, sizeof(ident))) {
                                return -EFAULT;
                        }
                        break;
index bd24b53..295e114 100644 (file)
@@ -70,7 +70,7 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-#define WD_VER                  "1.16 (03/27/2004)"
+#define WD_VER                  "1.16 (06/12/2004)"
 #define PFX                    "pcwd: "
 
 /*
@@ -299,10 +299,11 @@ static int pcwd_stop(void)
        return 0;
 }
 
-static void pcwd_keepalive(void)
+static int pcwd_keepalive(void)
 {
        /* user land ping */
        next_heartbeat = jiffies + (heartbeat * HZ);
+       return 0;
 }
 
 static int pcwd_set_heartbeat(int t)
@@ -404,6 +405,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
        int status;
        int temperature;
        int new_heartbeat;
+       int __user *argp = (int __user *)arg;
        static struct watchdog_info ident = {
                .options =              WDIOF_OVERHEAT |
                                        WDIOF_CARDRESET |
@@ -419,27 +421,27 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
                return -ENOIOCTLCMD;
 
        case WDIOC_GETSUPPORT:
-               if(copy_to_user((void*)arg, &ident, sizeof(ident)))
+               if(copy_to_user(argp, &ident, sizeof(ident)))
                        return -EFAULT;
                return 0;
 
        case WDIOC_GETSTATUS:
                pcwd_get_status(&status);
-               return put_user(status, (int *) arg);
+               return put_user(status, argp);
 
        case WDIOC_GETBOOTSTATUS:
-               return put_user(initial_status, (int *) arg);
+               return put_user(initial_status, argp);
 
        case WDIOC_GETTEMP:
                if (pcwd_get_temperature(&temperature))
                        return -EFAULT;
 
-               return put_user(temperature, (int *) arg);
+               return put_user(temperature, argp);
 
        case WDIOC_SETOPTIONS:
                if (revision == PCWD_REVISION_C)
                {
-                       if(copy_from_user(&rv, (int*) arg, sizeof(int)))
+                       if(copy_from_user(&rv, argp, sizeof(int)))
                                return -EFAULT;
 
                        if (rv & WDIOS_DISABLECARD)
@@ -464,7 +466,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
                return 0;
 
        case WDIOC_SETTIMEOUT:
-               if (get_user(new_heartbeat, (int *) arg))
+               if (get_user(new_heartbeat, argp))
                        return -EFAULT;
 
                if (pcwd_set_heartbeat(new_heartbeat))
@@ -474,13 +476,13 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
                /* Fall */
 
        case WDIOC_GETTIMEOUT:
-               return put_user(heartbeat, (int *)arg);
+               return put_user(heartbeat, argp);
        }
 
        return 0;
 }
 
-static ssize_t pcwd_write(struct file *file, const char *buf, size_t len,
+static ssize_t pcwd_write(struct file *file, const char __user *buf, size_t len,
                          loff_t *ppos)
 {
        /*  Can't seek (pwrite) on this device  */
@@ -528,12 +530,12 @@ static int pcwd_close(struct inode *inode, struct file *file)
 {
        if (expect_close == 42) {
                pcwd_stop();
-               atomic_inc( &open_allowed );
        } else {
                printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
                pcwd_keepalive();
        }
        expect_close = 0;
+       atomic_inc( &open_allowed );
        return 0;
 }
 
@@ -541,7 +543,7 @@ static int pcwd_close(struct inode *inode, struct file *file)
  *     /dev/temperature handling
  */
 
-static ssize_t pcwd_temp_read(struct file *file, char *buf, size_t count,
+static ssize_t pcwd_temp_read(struct file *file, char __user *buf, size_t count,
                         loff_t *ppos)
 {
        int temperature;
index e24694c..ddfeee8 100644 (file)
@@ -49,7 +49,7 @@
 
 /* Module and version information */
 #define WATCHDOG_VERSION "1.00"
-#define WATCHDOG_DATE "13/03/2004"
+#define WATCHDOG_DATE "12 Jun 2004"
 #define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
 #define WATCHDOG_NAME "pcwd_pci"
 #define PFX WATCHDOG_NAME ": "
@@ -73,7 +73,7 @@
 #define WD_PCI_TTRP             0x04   /* Temperature Trip status */
 
 /* according to documentation max. time to process a command for the pci
  watchdog card is 100 ms, so we give it 150 ms to do it's job */
* watchdog card is 100 ms, so we give it 150 ms to do it's job */
 #define PCI_COMMAND_TIMEOUT    150
 
 /* Watchdog's internal commands */
@@ -258,7 +258,7 @@ static int pcipcwd_get_temperature(int *temperature)
  *     /dev/watchdog handling
  */
 
-static ssize_t pcipcwd_write(struct file *file, const char *data,
+static ssize_t pcipcwd_write(struct file *file, const char __user *data,
                              size_t len, loff_t *ppos)
 {
        /* Can't seek (pwrite) on this device  */
@@ -293,6 +293,8 @@ static ssize_t pcipcwd_write(struct file *file, const char *data,
 static int pcipcwd_ioctl(struct inode *inode, struct file *file,
                          unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident = {
                .options =              WDIOF_OVERHEAT |
                                        WDIOF_CARDRESET |
@@ -305,7 +307,7 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
 
        switch (cmd) {
                case WDIOC_GETSUPPORT:
-                       return copy_to_user((struct watchdog_info *) arg, &ident,
+                       return copy_to_user(argp, &ident,
                                sizeof (ident)) ? -EFAULT : 0;
 
                case WDIOC_GETSTATUS:
@@ -314,11 +316,11 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
 
                        pcipcwd_get_status(&status);
 
-                       return put_user(status, (int *) arg);
+                       return put_user(status, p);
                }
 
                case WDIOC_GETBOOTSTATUS:
-                       return put_user(pcipcwd_private.boot_status, (int *) arg);
+                       return put_user(pcipcwd_private.boot_status, p);
 
                case WDIOC_GETTEMP:
                {
@@ -327,7 +329,7 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
                        if (pcipcwd_get_temperature(&temperature))
                                return -EFAULT;
 
-                       return put_user(temperature, (int *) arg);
+                       return put_user(temperature, p);
                }
 
                case WDIOC_KEEPALIVE:
@@ -338,7 +340,7 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
                {
                        int new_options, retval = -EINVAL;
 
-                       if (get_user (new_options, (int *) arg))
+                       if (get_user (new_options, p))
                                return -EFAULT;
 
                        if (new_options & WDIOS_DISABLECARD) {
@@ -363,7 +365,7 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
                {
                        int new_heartbeat;
 
-                       if (get_user(new_heartbeat, (int *) arg))
+                       if (get_user(new_heartbeat, p))
                                return -EFAULT;
 
                        if (pcipcwd_set_heartbeat(new_heartbeat))
@@ -374,7 +376,7 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
                }
 
                case WDIOC_GETTIMEOUT:
-                       return put_user(heartbeat, (int *)arg);
+                       return put_user(heartbeat, p);
 
                default:
                        return -ENOIOCTLCMD;
@@ -404,8 +406,8 @@ static int pcipcwd_release(struct inode *inode, struct file *file)
                printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
                pcipcwd_keepalive();
        }
-       clear_bit(0, &is_active);
        expect_release = 0;
+       clear_bit(0, &is_active);
        return 0;
 }
 
@@ -413,7 +415,7 @@ static int pcipcwd_release(struct inode *inode, struct file *file)
  *     /dev/temperature handling
  */
 
-static ssize_t pcipcwd_temp_read(struct file *file, char *data,
+static ssize_t pcipcwd_temp_read(struct file *file, char __user *data,
                                size_t len, loff_t *ppos)
 {
        int temperature;
@@ -585,15 +587,12 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
                printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n");
 
        /* Check that the heartbeat value is within it's range ; if not reset to the default */
-       if (heartbeat < 1 || heartbeat > 0xFFFF) {
-               heartbeat = WATCHDOG_HEARTBEAT;
+       if (pcipcwd_set_heartbeat(heartbeat)) {
+               pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
                printk(KERN_INFO PFX "heartbeat value must be 0<heartbeat<65536, using %d\n",
-                       heartbeat);
+                       WATCHDOG_HEARTBEAT);
        }
 
-       /* Calculate the watchdog's heartbeat */
-       pcipcwd_set_heartbeat(heartbeat);
-
        ret = register_reboot_notifier(&pcipcwd_notifier);
        if (ret != 0) {
                printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
@@ -601,29 +600,30 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
                goto err_out_release_region;
        }
 
-       ret = misc_register(&pcipcwd_miscdev);
-       if (ret != 0) {
-               printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
-                       WATCHDOG_MINOR, ret);
-               goto err_out_unregister_reboot;
-       }
-
        if (pcipcwd_private.supports_temp) {
                ret = misc_register(&pcipcwd_temp_miscdev);
                if (ret != 0) {
                        printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
                                TEMP_MINOR, ret);
-                       goto err_out_misc_deregister;
+                       goto err_out_unregister_reboot;
                }
        }
 
+       ret = misc_register(&pcipcwd_miscdev);
+       if (ret != 0) {
+               printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+                       WATCHDOG_MINOR, ret);
+               goto err_out_misc_deregister;
+       }
+
        printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
                heartbeat, nowayout);
 
        return 0;
 
 err_out_misc_deregister:
-       misc_deregister(&pcipcwd_miscdev);
+       if (pcipcwd_private.supports_temp)
+               misc_deregister(&pcipcwd_temp_miscdev);
 err_out_unregister_reboot:
        unregister_reboot_notifier(&pcipcwd_notifier);
 err_out_release_region:
@@ -640,9 +640,9 @@ static void __devexit pcipcwd_card_exit(struct pci_dev *pdev)
                pcipcwd_stop();
 
        /* Deregister */
+       misc_deregister(&pcipcwd_miscdev);
        if (pcipcwd_private.supports_temp)
                misc_deregister(&pcipcwd_temp_miscdev);
-       misc_deregister(&pcipcwd_miscdev);
        unregister_reboot_notifier(&pcipcwd_notifier);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
index d88228e..5032553 100644 (file)
@@ -56,7 +56,8 @@
 
 
 /* Module and Version Information */
-#define DRIVER_VERSION "v1.00 (28/02/2004)"
+#define DRIVER_VERSION "1.00"
+#define DRIVER_DATE "12 Jun 2004"
 #define DRIVER_AUTHOR "Wim Van Sebroeck <wim@iguana.be>"
 #define DRIVER_DESC "Berkshire USB-PC Watchdog driver"
 #define DRIVER_LICENSE "GPL"
@@ -325,7 +326,7 @@ static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd, int *temp
  *     /dev/watchdog handling
  */
 
-static ssize_t usb_pcwd_write(struct file *file, const char *data,
+static ssize_t usb_pcwd_write(struct file *file, const char __user *data,
                              size_t len, loff_t *ppos)
 {
        /* Can't seek (pwrite) on this device  */
@@ -360,6 +361,8 @@ static ssize_t usb_pcwd_write(struct file *file, const char *data,
 static int usb_pcwd_ioctl(struct inode *inode, struct file *file,
                          unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident = {
                .options =              WDIOF_KEEPALIVEPING |
                                        WDIOF_SETTIMEOUT |
@@ -370,12 +373,12 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file,
 
        switch (cmd) {
                case WDIOC_GETSUPPORT:
-                       return copy_to_user((struct watchdog_info *) arg, &ident,
+                       return copy_to_user(argp, &ident,
                                sizeof (ident)) ? -EFAULT : 0;
 
                case WDIOC_GETSTATUS:
                case WDIOC_GETBOOTSTATUS:
-                       return put_user(0, (int *) arg);
+                       return put_user(0, p);
 
                case WDIOC_GETTEMP:
                {
@@ -384,7 +387,7 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file,
                        if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature))
                                return -EFAULT;
 
-                       return put_user(temperature, (int *) arg);
+                       return put_user(temperature, p);
                }
 
                case WDIOC_KEEPALIVE:
@@ -395,7 +398,7 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file,
                {
                        int new_options, retval = -EINVAL;
 
-                       if (get_user (new_options, (int *) arg))
+                       if (get_user (new_options, p))
                                return -EFAULT;
 
                        if (new_options & WDIOS_DISABLECARD) {
@@ -415,7 +418,7 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file,
                {
                        int new_heartbeat;
 
-                       if (get_user(new_heartbeat, (int *) arg))
+                       if (get_user(new_heartbeat, p))
                                return -EFAULT;
 
                        if (usb_pcwd_set_heartbeat(usb_pcwd_device, new_heartbeat))
@@ -426,7 +429,7 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file,
                }
 
                case WDIOC_GETTIMEOUT:
-                       return put_user(heartbeat, (int *)arg);
+                       return put_user(heartbeat, p);
 
                default:
                        return -ENOIOCTLCMD;
@@ -456,8 +459,8 @@ static int usb_pcwd_release(struct inode *inode, struct file *file)
                printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
                usb_pcwd_keepalive(usb_pcwd_device);
        }
-       clear_bit(0, &is_active);
        expect_release = 0;
+       clear_bit(0, &is_active);
        return 0;
 }
 
@@ -465,7 +468,7 @@ static int usb_pcwd_release(struct inode *inode, struct file *file)
  *     /dev/temperature handling
  */
 
-static ssize_t usb_pcwd_temperature_read(struct file *file, char *data,
+static ssize_t usb_pcwd_temperature_read(struct file *file, char __user *data,
                                size_t len, loff_t *ppos)
 {
        int temperature;
@@ -477,7 +480,7 @@ static ssize_t usb_pcwd_temperature_read(struct file *file, char *data,
        if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature))
                return -EFAULT;
 
-       if (copy_to_user (data, &temperature, 1))
+       if (copy_to_user(data, &temperature, 1))
                return -EFAULT;
 
        return 1;
@@ -681,15 +684,12 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
                ((option_switches & 0x08) ? "ON" : "OFF"));
 
        /* Check that the heartbeat value is within it's range ; if not reset to the default */
-       if (heartbeat < 1 || heartbeat > 0xFFFF) {
-               heartbeat = WATCHDOG_HEARTBEAT;
+       if (usb_pcwd_set_heartbeat(usb_pcwd, heartbeat)) {
+               usb_pcwd_set_heartbeat(usb_pcwd, WATCHDOG_HEARTBEAT);
                printk(KERN_INFO PFX "heartbeat value must be 0<heartbeat<65536, using %d\n",
-                       heartbeat);
+                       WATCHDOG_HEARTBEAT);
        }
 
-       /* Calculate the watchdog's heartbeat */
-       usb_pcwd_set_heartbeat(usb_pcwd, heartbeat);
-
        retval = register_reboot_notifier(&usb_pcwd_notifier);
        if (retval != 0) {
                printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
@@ -697,17 +697,17 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
                goto error;
        }
 
-       retval = misc_register(&usb_pcwd_miscdev);
+       retval = misc_register(&usb_pcwd_temperature_miscdev);
        if (retval != 0) {
                printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
-                       WATCHDOG_MINOR, retval);
+                       TEMP_MINOR, retval);
                goto err_out_unregister_reboot;
        }
 
-       retval = misc_register(&usb_pcwd_temperature_miscdev);
+       retval = misc_register(&usb_pcwd_miscdev);
        if (retval != 0) {
                printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
-                       TEMP_MINOR, retval);
+                       WATCHDOG_MINOR, retval);
                goto err_out_misc_deregister;
        }
 
@@ -720,7 +720,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
        return 0;
 
 err_out_misc_deregister:
-       misc_deregister(&usb_pcwd_miscdev);
+       misc_deregister(&usb_pcwd_temperature_miscdev);
 err_out_unregister_reboot:
        unregister_reboot_notifier(&usb_pcwd_notifier);
 error:
@@ -758,8 +758,8 @@ static void usb_pcwd_disconnect(struct usb_interface *interface)
        usb_pcwd->exists = 0;
 
        /* Deregister */
-       misc_deregister(&usb_pcwd_temperature_miscdev);
        misc_deregister(&usb_pcwd_miscdev);
+       misc_deregister(&usb_pcwd_temperature_miscdev);
        unregister_reboot_notifier(&usb_pcwd_notifier);
 
        up (&usb_pcwd->sem);
@@ -791,7 +791,7 @@ static int __init usb_pcwd_init(void)
                return result;
        }
 
-       printk(KERN_INFO PFX DRIVER_DESC " " DRIVER_VERSION "\n");
+       printk(KERN_INFO PFX DRIVER_DESC " v" DRIVER_VERSION " (" DRIVER_DATE ")\n");
        return 0;
 }
 
index c533c46..b1c2990 100644 (file)
@@ -166,7 +166,7 @@ static void wdt_keepalive(void)
  * /dev/watchdog handling
  */
 
-static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos)
+static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos)
 {
        /* We can't seek */
        if(ppos != &file->f_pos)
@@ -230,6 +230,8 @@ static int fop_close(struct inode * inode, struct file * file)
 static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident=
        {
                .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
@@ -242,10 +244,10 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                default:
                        return -ENOIOCTLCMD;
                case WDIOC_GETSUPPORT:
-                       return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+                       return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
                case WDIOC_GETSTATUS:
                case WDIOC_GETBOOTSTATUS:
-                       return put_user(0, (int *)arg);
+                       return put_user(0, p);
                case WDIOC_KEEPALIVE:
                        wdt_keepalive();
                        return 0;
@@ -253,7 +255,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                {
                        int new_options, retval = -EINVAL;
 
-                       if(get_user(new_options, (int *)arg))
+                       if(get_user(new_options, p))
                                return -EFAULT;
 
                        if(new_options & WDIOS_DISABLECARD) {
@@ -272,7 +274,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                {
                        int new_timeout;
 
-                       if(get_user(new_timeout, (int *)arg))
+                       if(get_user(new_timeout, p))
                                return -EFAULT;
 
                        if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
@@ -283,7 +285,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                        /* Fall through */
                }
                case WDIOC_GETTIMEOUT:
-                       return put_user(timeout, (int *)arg);
+                       return put_user(timeout, p);
        }
 }
 
index b7e4885..df38161 100644 (file)
@@ -174,6 +174,8 @@ static int sc1200wdt_open(struct inode *inode, struct file *file)
 static int sc1200wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
        int new_timeout;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident = {
                .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
                .firmware_version = 0,
@@ -185,22 +187,22 @@ static int sc1200wdt_ioctl(struct inode *inode, struct file *file, unsigned int
                        return -ENOIOCTLCMD;    /* Keep Pavel Machek amused ;) */
 
                case WDIOC_GETSUPPORT:
-                       if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof ident))
+                       if (copy_to_user(argp, &ident, sizeof ident))
                                return -EFAULT;
                        return 0;
 
                case WDIOC_GETSTATUS:
-                       return put_user(sc1200wdt_status(), (int *)arg);
+                       return put_user(sc1200wdt_status(), p);
 
                case WDIOC_GETBOOTSTATUS:
-                       return put_user(0, (int *)arg);
+                       return put_user(0, p);
 
                case WDIOC_KEEPALIVE:
                        sc1200wdt_write_data(WDTO, timeout);
                        return 0;
 
                case WDIOC_SETTIMEOUT:
-                       if (get_user(new_timeout, (int *)arg))
+                       if (get_user(new_timeout, p))
                                return -EFAULT;
 
                        /* the API states this is given in secs */
@@ -213,13 +215,13 @@ static int sc1200wdt_ioctl(struct inode *inode, struct file *file, unsigned int
                        /* fall through and return the new timeout */
 
                case WDIOC_GETTIMEOUT:
-                       return put_user(timeout * 60, (int *)arg);
+                       return put_user(timeout * 60, p);
 
                case WDIOC_SETOPTIONS:
                {
                        int options, retval = -EINVAL;
 
-                       if (get_user(options, (int *)arg))
+                       if (get_user(options, p))
                                return -EFAULT;
 
                        if (options & WDIOS_DISABLECARD) {
@@ -254,7 +256,7 @@ static int sc1200wdt_release(struct inode *inode, struct file *file)
 }
 
 
-static ssize_t sc1200wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+static ssize_t sc1200wdt_write(struct file *file, const char __user *data, size_t len, loff_t *ppos)
 {
        if (ppos != &file->f_pos)
                return -ESPIPE;
index b54c47b..ebd0bb1 100644 (file)
@@ -225,7 +225,7 @@ static int wdt_set_heartbeat(int t)
  *     /dev/watchdog handling
  */
 
-static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos)
+static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos)
 {
        /* We can't seek */
        if(ppos != &file->f_pos)
@@ -285,6 +285,8 @@ static int fop_close(struct inode * inode, struct file * file)
 static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident = {
                .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
                .firmware_version = 1,
@@ -296,10 +298,10 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                default:
                        return -ENOIOCTLCMD;
                case WDIOC_GETSUPPORT:
-                       return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+                       return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
                case WDIOC_GETSTATUS:
                case WDIOC_GETBOOTSTATUS:
-                       return put_user(0, (int *)arg);
+                       return put_user(0, p);
                case WDIOC_KEEPALIVE:
                        wdt_keepalive();
                        return 0;
@@ -307,7 +309,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                {
                        int new_options, retval = -EINVAL;
 
-                       if(get_user(new_options, (int *)arg))
+                       if(get_user(new_options, p))
                                return -EFAULT;
 
                        if(new_options & WDIOS_DISABLECARD) {
@@ -326,7 +328,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                {
                        int new_timeout;
 
-                       if(get_user(new_timeout, (int *)arg))
+                       if(get_user(new_timeout, p))
                                return -EFAULT;
 
                        if(wdt_set_heartbeat(new_timeout))
@@ -336,7 +338,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                        /* Fall through */
                }
                case WDIOC_GETTIMEOUT:
-                       return put_user(timeout, (int *)arg);
+                       return put_user(timeout, p);
        }
 }
 
index 6f0657b..bc61e82 100644 (file)
@@ -132,7 +132,7 @@ static struct notifier_block scx200_wdt_notifier =
        .notifier_call = scx200_wdt_notify_sys,
 };
 
-static ssize_t scx200_wdt_write(struct file *file, const char *data,
+static ssize_t scx200_wdt_write(struct file *file, const char __user *data,
                                     size_t len, loff_t *ppos)
 {
        if (ppos != &file->f_pos)
@@ -163,6 +163,8 @@ static ssize_t scx200_wdt_write(struct file *file, const char *data,
 static int scx200_wdt_ioctl(struct inode *inode, struct file *file,
        unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident = {
                .identity = "NatSemi SCx200 Watchdog",
                .firmware_version = 1,
@@ -174,20 +176,19 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file,
        default:
                return -ENOIOCTLCMD;
        case WDIOC_GETSUPPORT:
-               if(copy_to_user((struct watchdog_info *)arg, &ident,
-                               sizeof(ident)))
+               if(copy_to_user(argp, &ident, sizeof(ident)))
                        return -EFAULT;
                return 0;
        case WDIOC_GETSTATUS:
        case WDIOC_GETBOOTSTATUS:
-               if (put_user(0, (int *)arg))
+               if (put_user(0, p))
                        return -EFAULT;
                return 0;
        case WDIOC_KEEPALIVE:
                scx200_wdt_ping();
                return 0;
        case WDIOC_SETTIMEOUT:
-               if (get_user(new_margin, (int *)arg))
+               if (get_user(new_margin, p))
                        return -EFAULT;
                if (new_margin < 1)
                        return -EINVAL;
@@ -195,7 +196,7 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file,
                scx200_wdt_update_margin();
                scx200_wdt_ping();
        case WDIOC_GETTIMEOUT:
-               if (put_user(margin, (int *)arg))
+               if (put_user(margin, p))
                        return -EFAULT;
                return 0;
        }
index e9f4f22..832590d 100644 (file)
@@ -161,7 +161,7 @@ static int softdog_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t softdog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+static ssize_t softdog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos)
 {
        /*  Can't seek (pwrite) on this device  */
        if (ppos != &file->f_pos)
@@ -194,6 +194,8 @@ static ssize_t softdog_write(struct file *file, const char *data, size_t len, lo
 static int softdog_ioctl(struct inode *inode, struct file *file,
        unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        int new_margin;
        static struct watchdog_info ident = {
                .options =              WDIOF_SETTIMEOUT |
@@ -206,23 +208,23 @@ static int softdog_ioctl(struct inode *inode, struct file *file,
                default:
                        return -ENOIOCTLCMD;
                case WDIOC_GETSUPPORT:
-                       return copy_to_user((struct watchdog_info *)arg, &ident,
+                       return copy_to_user(argp, &ident,
                                sizeof(ident)) ? -EFAULT : 0;
                case WDIOC_GETSTATUS:
                case WDIOC_GETBOOTSTATUS:
-                       return put_user(0,(int *)arg);
+                       return put_user(0, p);
                case WDIOC_KEEPALIVE:
                        softdog_keepalive();
                        return 0;
                case WDIOC_SETTIMEOUT:
-                       if (get_user(new_margin, (int *)arg))
+                       if (get_user(new_margin, p))
                                return -EFAULT;
                        if (softdog_set_heartbeat(new_margin))
                                return -EINVAL;
                        softdog_keepalive();
                        /* Fall */
                case WDIOC_GETTIMEOUT:
-                       return put_user(soft_margin, (int *)arg);
+                       return put_user(soft_margin, p);
        }
 }
 
index 7a12930..0a21962 100644 (file)
@@ -142,7 +142,7 @@ wdt_set_heartbeat(int t)
 }
 
 static ssize_t
-wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
        /*  Can't seek (pwrite) on this device  */
        if (ppos != &file->f_pos)
@@ -171,6 +171,8 @@ static int
 wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
          unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        int new_timeout;
        static struct watchdog_info ident = {
                .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
@@ -180,20 +182,20 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
        switch (cmd) {
        case WDIOC_GETSUPPORT:
-         if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
+         if (copy_to_user(argp, &ident, sizeof(ident)))
            return -EFAULT;
          break;
 
        case WDIOC_GETSTATUS:
        case WDIOC_GETBOOTSTATUS:
-         return put_user(0, (int *)arg);
+         return put_user(0, p);
 
        case WDIOC_KEEPALIVE:
          wdt_ping();
          break;
 
        case WDIOC_SETTIMEOUT:
-         if (get_user(new_timeout, (int *)arg))
+         if (get_user(new_timeout, p))
                  return -EFAULT;
          if (wdt_set_heartbeat(new_timeout))
                  return -EINVAL;
@@ -201,13 +203,13 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
          /* Fall */
 
        case WDIOC_GETTIMEOUT:
-         return put_user(timeout, (int *)arg);
+         return put_user(timeout, p);
 
        case WDIOC_SETOPTIONS:
        {
          int options, retval = -EINVAL;
 
-         if (get_user(options, (int *)arg))
+         if (get_user(options, p))
            return -EFAULT;
 
          if (options & WDIOS_DISABLECARD) {
index 2b657a5..21270da 100644 (file)
@@ -188,7 +188,7 @@ static void wdt_keepalive(void)
  * /dev/watchdog handling
  */
 
-static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos)
+static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos)
 {
        /* We can't seek */
        if(ppos != &file->f_pos)
@@ -249,6 +249,8 @@ static int fop_close(struct inode * inode, struct file * file)
 static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident=
        {
                .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
@@ -261,10 +263,10 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                default:
                        return -ENOIOCTLCMD;
                case WDIOC_GETSUPPORT:
-                       return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+                       return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
                case WDIOC_GETSTATUS:
                case WDIOC_GETBOOTSTATUS:
-                       return put_user(0, (int *)arg);
+                       return put_user(0, p);
                case WDIOC_KEEPALIVE:
                        wdt_keepalive();
                        return 0;
@@ -272,7 +274,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                {
                        int new_options, retval = -EINVAL;
 
-                       if(get_user(new_options, (int *)arg))
+                       if(get_user(new_options, p))
                                return -EFAULT;
 
                        if(new_options & WDIOS_DISABLECARD) {
@@ -291,7 +293,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                {
                        int new_timeout;
 
-                       if(get_user(new_timeout, (int *)arg))
+                       if(get_user(new_timeout, p))
                                return -EFAULT;
 
                        if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
@@ -302,7 +304,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                        /* Fall through */
                }
                case WDIOC_GETTIMEOUT:
-                       return put_user(timeout, (int *)arg);
+                       return put_user(timeout, p);
        }
 }
 
index 464a5a7..26e232b 100644 (file)
@@ -95,7 +95,7 @@ wafwdt_stop(void)
        inb_p(wdt_stop);
 }
 
-static ssize_t wafwdt_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
+static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
 {
        /*  Can't seek (pwrite) on this device  */
        if (ppos != &file->f_pos)
@@ -128,6 +128,8 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd
             unsigned long arg)
 {
        int new_timeout;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        static struct watchdog_info ident = {
                .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
                .firmware_version = 1,
@@ -136,21 +138,20 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 
        switch (cmd) {
        case WDIOC_GETSUPPORT:
-               if (copy_to_user
-                   ((struct watchdog_info *) arg, &ident, sizeof (ident)))
+               if (copy_to_user(argp, &ident, sizeof (ident)))
                        return -EFAULT;
                break;
 
        case WDIOC_GETSTATUS:
        case WDIOC_GETBOOTSTATUS:
-               return put_user(0, (int *)arg);
+               return put_user(0, p);
 
        case WDIOC_KEEPALIVE:
                wafwdt_ping();
                break;
 
        case WDIOC_SETTIMEOUT:
-               if (get_user(new_timeout, (int *)arg))
+               if (get_user(new_timeout, p))
                        return -EFAULT;
                if ((new_timeout < 1) || (new_timeout > 255))
                        return -EINVAL;
@@ -159,13 +160,13 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                wafwdt_start();
                /* Fall */
        case WDIOC_GETTIMEOUT:
-               return put_user(timeout, (int *)arg);
+               return put_user(timeout, p);
 
        case WDIOC_SETOPTIONS:
        {
                int options, retval = -EINVAL;
 
-               if (get_user(options, (int *)arg))
+               if (get_user(options, p))
                        return -EFAULT;
 
                if (options & WDIOS_DISABLECARD) {
index c606ce4..407690b 100644 (file)
@@ -286,7 +286,7 @@ static irqreturn_t wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  *     write of data will do, as we we don't define content meaning.
  */
 
-static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
        /*  Can't seek (pwrite) on this device  */
        if (ppos != &file->f_pos)
@@ -327,6 +327,8 @@ static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_
 static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        int new_heartbeat;
        int status;
 
@@ -351,18 +353,18 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                default:
                        return -ENOIOCTLCMD;
                case WDIOC_GETSUPPORT:
-                       return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+                       return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
 
                case WDIOC_GETSTATUS:
                        wdt_get_status(&status);
-                       return put_user(status,(int *)arg);
+                       return put_user(status, p);
                case WDIOC_GETBOOTSTATUS:
-                       return put_user(0, (int *)arg);
+                       return put_user(0, p);
                case WDIOC_KEEPALIVE:
                        wdt_ping();
                        return 0;
                case WDIOC_SETTIMEOUT:
-                       if (get_user(new_heartbeat, (int *)arg))
+                       if (get_user(new_heartbeat, p))
                                return -EFAULT;
 
                        if (wdt_set_heartbeat(new_heartbeat))
@@ -371,7 +373,7 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                        wdt_ping();
                        /* Fall */
                case WDIOC_GETTIMEOUT:
-                       return put_user(heartbeat, (int *)arg);
+                       return put_user(heartbeat, p);
        }
 }
 
@@ -435,7 +437,7 @@ static int wdt_release(struct inode *inode, struct file *file)
  *     farenheit. It was designed by an imperial measurement luddite.
  */
 
-static ssize_t wdt_temp_read(struct file *file, char *buf, size_t count, loff_t *ptr)
+static ssize_t wdt_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr)
 {
        int temperature;
 
index 395df48..c63d17f 100644 (file)
@@ -331,7 +331,7 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  *     write of data will do, as we we don't define content meaning.
  */
 
-static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
        /*  Can't seek (pwrite) on this device  */
        if (ppos != &file->f_pos)
@@ -374,6 +374,8 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 {
        int new_heartbeat;
        int status;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
 
        static struct watchdog_info ident = {
                .options =              WDIOF_SETTIMEOUT|
@@ -396,18 +398,18 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                default:
                        return -ENOIOCTLCMD;
                case WDIOC_GETSUPPORT:
-                       return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+                       return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
 
                case WDIOC_GETSTATUS:
                        wdtpci_get_status(&status);
-                       return put_user(status,(int *)arg);
+                       return put_user(status, p);
                case WDIOC_GETBOOTSTATUS:
-                       return put_user(0, (int *)arg);
+                       return put_user(0, p);
                case WDIOC_KEEPALIVE:
                        wdtpci_ping();
                        return 0;
                case WDIOC_SETTIMEOUT:
-                       if (get_user(new_heartbeat, (int *)arg))
+                       if (get_user(new_heartbeat, p))
                                return -EFAULT;
 
                        if (wdtpci_set_heartbeat(new_heartbeat))
@@ -416,7 +418,7 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        wdtpci_ping();
                        /* Fall */
                case WDIOC_GETTIMEOUT:
-                       return put_user(heartbeat, (int *)arg);
+                       return put_user(heartbeat, p);
        }
 }
 
@@ -484,7 +486,7 @@ static int wdtpci_release(struct inode *inode, struct file *file)
  *     fahrenheit. It was designed by an imperial measurement luddite.
  */
 
-static ssize_t wdtpci_temp_read(struct file *file, char *buf, size_t count, loff_t *ptr)
+static ssize_t wdtpci_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr)
 {
        int temperature;
 
index a6f3510..a7fa79f 100644 (file)
@@ -722,7 +722,12 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
                            unsigned int target_freq,
                            unsigned int relation)
 {
-       return cpufreq_driver->target(policy, target_freq, relation);
+       int retval = -EINVAL;
+       lock_cpu_hotplug();
+       if (cpu_online(policy->cpu))
+               retval = cpufreq_driver->target(policy, target_freq, relation);
+       unlock_cpu_hotplug();
+       return retval;
 }
 EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
 
index 666c717..5102144 100644 (file)
@@ -206,7 +206,7 @@ cpufreq_sysctl(ctl_table *table, int __user *name, int nlen,
                if (oldlen != sizeof(unsigned int))
                        return -EINVAL;
 
-               if (put_user(cpufreq_get(cpu), (unsigned int *)oldval) ||
+               if (put_user(cpufreq_get(cpu), (unsigned int __user *)oldval) ||
                    put_user(sizeof(unsigned int), oldlenp))
                        return -EFAULT;
        }
@@ -216,7 +216,7 @@ cpufreq_sysctl(ctl_table *table, int __user *name, int nlen,
                if (newlen != sizeof(unsigned int))
                        return -EINVAL;
 
-               if (get_user(freq, (unsigned int *)newval))
+               if (get_user(freq, (unsigned int __user *)newval))
                        return -EFAULT;
 
                cpufreq_set(freq, cpu);
index 81d58c7..a0eaf6f 100644 (file)
@@ -164,7 +164,7 @@ end:
  */
 static int cpufreq_proc_write (
         struct file            *file,
-        const char             *buffer,
+        const char             __user *buffer,
         unsigned long          count,
         void                   *data)
 {
index e5f41e0..1fbb219 100644 (file)
@@ -38,7 +38,7 @@
 #include <asm/irq.h>
 #include <asm/semaphore.h>
 #include "fcp_impl.h"
-#include "../scsi/hosts.h"
+#include <scsi/scsi_host.h>
 
 /* #define FCDEBUG */
 
index 3479288..40257f7 100644 (file)
@@ -320,7 +320,7 @@ edd_show_info_flags(struct edd_device *edev, char *buf)
 }
 
 static ssize_t
-edd_show_legacy_cylinders(struct edd_device *edev, char *buf)
+edd_show_legacy_max_cylinder(struct edd_device *edev, char *buf)
 {
        struct edd_info *info;
        char *p = buf;
@@ -330,12 +330,12 @@ edd_show_legacy_cylinders(struct edd_device *edev, char *buf)
        if (!info || !buf)
                return -EINVAL;
 
-       p += snprintf(p, left, "0x%x\n", info->legacy_cylinders);
+       p += snprintf(p, left, "%u\n", info->legacy_max_cylinder);
        return (p - buf);
 }
 
 static ssize_t
-edd_show_legacy_heads(struct edd_device *edev, char *buf)
+edd_show_legacy_max_head(struct edd_device *edev, char *buf)
 {
        struct edd_info *info;
        char *p = buf;
@@ -345,12 +345,12 @@ edd_show_legacy_heads(struct edd_device *edev, char *buf)
        if (!info || !buf)
                return -EINVAL;
 
-       p += snprintf(p, left, "0x%x\n", info->legacy_heads);
+       p += snprintf(p, left, "%u\n", info->legacy_max_head);
        return (p - buf);
 }
 
 static ssize_t
-edd_show_legacy_sectors(struct edd_device *edev, char *buf)
+edd_show_legacy_sectors_per_track(struct edd_device *edev, char *buf)
 {
        struct edd_info *info;
        char *p = buf;
@@ -360,7 +360,7 @@ edd_show_legacy_sectors(struct edd_device *edev, char *buf)
        if (!info || !buf)
                return -EINVAL;
 
-       p += snprintf(p, left, "0x%x\n", info->legacy_sectors);
+       p += snprintf(p, left, "%u\n", info->legacy_sectors_per_track);
        return (p - buf);
 }
 
@@ -375,7 +375,7 @@ edd_show_default_cylinders(struct edd_device *edev, char *buf)
        if (!info || !buf)
                return -EINVAL;
 
-       p += scnprintf(p, left, "0x%x\n", info->params.num_default_cylinders);
+       p += scnprintf(p, left, "%u\n", info->params.num_default_cylinders);
        return (p - buf);
 }
 
@@ -390,7 +390,7 @@ edd_show_default_heads(struct edd_device *edev, char *buf)
        if (!info || !buf)
                return -EINVAL;
 
-       p += scnprintf(p, left, "0x%x\n", info->params.num_default_heads);
+       p += scnprintf(p, left, "%u\n", info->params.num_default_heads);
        return (p - buf);
 }
 
@@ -405,7 +405,7 @@ edd_show_default_sectors_per_track(struct edd_device *edev, char *buf)
        if (!info || !buf)
                return -EINVAL;
 
-       p += scnprintf(p, left, "0x%x\n", info->params.sectors_per_track);
+       p += scnprintf(p, left, "%u\n", info->params.sectors_per_track);
        return (p - buf);
 }
 
@@ -420,7 +420,7 @@ edd_show_sectors(struct edd_device *edev, char *buf)
        if (!info || !buf)
                return -EINVAL;
 
-       p += scnprintf(p, left, "0x%llx\n", info->params.number_of_sectors);
+       p += scnprintf(p, left, "%llu\n", info->params.number_of_sectors);
        return (p - buf);
 }
 
@@ -436,7 +436,7 @@ edd_show_sectors(struct edd_device *edev, char *buf)
  */
 
 static int
-edd_has_legacy_cylinders(struct edd_device *edev)
+edd_has_legacy_max_cylinder(struct edd_device *edev)
 {
        struct edd_info *info;
        if (!edev)
@@ -444,11 +444,11 @@ edd_has_legacy_cylinders(struct edd_device *edev)
        info = edd_dev_get_info(edev);
        if (!info)
                return -EINVAL;
-       return info->legacy_cylinders > 0;
+       return info->legacy_max_cylinder > 0;
 }
 
 static int
-edd_has_legacy_heads(struct edd_device *edev)
+edd_has_legacy_max_head(struct edd_device *edev)
 {
        struct edd_info *info;
        if (!edev)
@@ -456,11 +456,11 @@ edd_has_legacy_heads(struct edd_device *edev)
        info = edd_dev_get_info(edev);
        if (!info)
                return -EINVAL;
-       return info->legacy_heads > 0;
+       return info->legacy_max_head > 0;
 }
 
 static int
-edd_has_legacy_sectors(struct edd_device *edev)
+edd_has_legacy_sectors_per_track(struct edd_device *edev)
 {
        struct edd_info *info;
        if (!edev)
@@ -468,7 +468,7 @@ edd_has_legacy_sectors(struct edd_device *edev)
        info = edd_dev_get_info(edev);
        if (!info)
                return -EINVAL;
-       return info->legacy_sectors > 0;
+       return info->legacy_sectors_per_track > 0;
 }
 
 static int
@@ -555,12 +555,14 @@ static EDD_DEVICE_ATTR(version, 0444, edd_show_version, NULL);
 static EDD_DEVICE_ATTR(extensions, 0444, edd_show_extensions, NULL);
 static EDD_DEVICE_ATTR(info_flags, 0444, edd_show_info_flags, NULL);
 static EDD_DEVICE_ATTR(sectors, 0444, edd_show_sectors, NULL);
-static EDD_DEVICE_ATTR(legacy_cylinders, 0444, edd_show_legacy_cylinders,
-                      edd_has_legacy_cylinders);
-static EDD_DEVICE_ATTR(legacy_heads, 0444, edd_show_legacy_heads,
-                      edd_has_legacy_heads);
-static EDD_DEVICE_ATTR(legacy_sectors, 0444, edd_show_legacy_sectors,
-                      edd_has_legacy_sectors);
+static EDD_DEVICE_ATTR(legacy_max_cylinder, 0444,
+                       edd_show_legacy_max_cylinder,
+                      edd_has_legacy_max_cylinder);
+static EDD_DEVICE_ATTR(legacy_max_head, 0444, edd_show_legacy_max_head,
+                      edd_has_legacy_max_head);
+static EDD_DEVICE_ATTR(legacy_sectors_per_track, 0444,
+                       edd_show_legacy_sectors_per_track,
+                      edd_has_legacy_sectors_per_track);
 static EDD_DEVICE_ATTR(default_cylinders, 0444, edd_show_default_cylinders,
                       edd_has_default_cylinders);
 static EDD_DEVICE_ATTR(default_heads, 0444, edd_show_default_heads,
@@ -587,9 +589,9 @@ static struct attribute * def_attrs[] = {
 
 /* These attributes are conditional and only added for some devices. */
 static struct edd_attribute * edd_attrs[] = {
-       &edd_attr_legacy_cylinders,
-       &edd_attr_legacy_heads,
-       &edd_attr_legacy_sectors,
+       &edd_attr_legacy_max_cylinder,
+       &edd_attr_legacy_max_head,
+       &edd_attr_legacy_sectors_per_track,
        &edd_attr_default_cylinders,
        &edd_attr_default_heads,
        &edd_attr_default_sectors_per_track,
index 56225a5..2583eca 100644 (file)
@@ -126,7 +126,13 @@ int i2c_add_adapter(struct i2c_adapter *adap)
                goto out_unlock;
        }
 
-       id = idr_get_new(&i2c_adapter_idr, NULL);
+       res = idr_get_new(&i2c_adapter_idr, NULL, &id);
+       if (res < 0) {
+               if (res == -EAGAIN)
+                       res = -ENOMEM;
+               goto out_unlock;
+       }
+
        adap->nr =  id & MAX_ID_MASK;
        init_MUTEX(&adap->bus_lock);
        init_MUTEX(&adap->clist_lock);
@@ -162,7 +168,7 @@ int i2c_add_adapter(struct i2c_adapter *adap)
 
        dev_dbg(&adap->dev, "registered as adapter #%d\n", adap->nr);
 
- out_unlock:
+out_unlock:
        up(&core_lists);
        return res;
 }
index c43ac49..ec58f19 100644 (file)
@@ -97,25 +97,7 @@ comment "Please see Documentation/ide.txt for help/info on IDE drives"
 
 config BLK_DEV_HD_IDE
        bool "Use old disk-only driver on primary interface"
-       depends on ((X86 && X86_PC9800!=y) || SH_MPC1211)
-       ---help---
-         There are two drivers for MFM/RLL/IDE disks.  Most people use just
-         the new enhanced driver by itself.  This option however installs the
-         old hard disk driver to control the primary IDE/disk interface in
-         the system, leaving the new enhanced IDE driver to take care of only
-         the 2nd/3rd/4th IDE interfaces.  Doing this will prevent you from
-         having an IDE/ATAPI CD-ROM or tape drive connected to the primary
-         IDE interface.  Choosing this option may be useful for older systems
-         which have MFM/RLL/ESDI controller+drives at the primary port
-         address (0x1f0), along with IDE drives at the secondary/3rd/4th port
-         addresses.
-
-         Normally, just say N here; you will then use the new driver for all
-         4 interfaces.
-
-config BLK_DEV_HD_IDE98
-       bool "Use old disk-only driver on primary interface"
-       depends on X86 && X86_PC9800
+       depends on (X86 || SH_MPC1211)
        ---help---
          There are two drivers for MFM/RLL/IDE disks.  Most people use just
          the new enhanced driver by itself.  This option however installs the
@@ -157,20 +139,6 @@ config IDEDISK_MULTI_MODE
 
          If in doubt, say N.
 
-config IDEDISK_STROKE
-       bool "Auto-Geometry Resizing support"
-       depends on BLK_DEV_IDEDISK
-       help
-         Should you have a system w/ an AWARD Bios and your drives are larger
-         than 32GB and it will not boot, one is required to perform a few OEM
-         operations first.  The option is called "STROKE" because it allows
-         one to "soft clip" the drive to work around a barrier limit.  For
-         Maxtor drives it is called "jumpon.exe".  Please search Maxtor's
-         web-site for "JUMPON.EXE".  IBM has a similar tool at:
-         <http://www.storage.ibm.com/hdd/support/download.htm>.
-
-         If you are unsure, say N here.
-
 config BLK_DEV_IDECS
        tristate "PCMCIA IDE support"
        depends on PCMCIA
@@ -438,48 +406,6 @@ config BLK_DEV_IDEDMA_PCI
 
 if BLK_DEV_IDEDMA_PCI
 
-# TCQ is disabled for now
-config BLK_DEV_IDE_TCQ
-       bool "ATA tagged command queueing (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && n
-       help
-         Support for tagged command queueing on ATA disk drives. This enables
-         the IDE layer to have multiple in-flight requests on hardware that
-         supports it. For now this includes the IBM Deskstar series drives,
-         such as the 22GXP, 75GXP, 40GV, 60GXP, and 120GXP (ie any Deskstar made
-         in the last couple of years), and at least some of the Western
-         Digital drives in the Expert series (by nature of really being IBM
-         drives).
-
-         If you have such a drive, say Y here.
-
-config BLK_DEV_IDE_TCQ_DEFAULT
-       bool "TCQ on by default"
-       depends on BLK_DEV_IDE_TCQ
-       ---help---
-         Enable tagged command queueing unconditionally on drives that report
-         support for it. Regardless of the chosen value here, tagging can be
-         controlled at run time:
-
-         echo "using_tcq:32" > /proc/ide/hdX/settings
-
-         where any value between 1-32 selects chosen queue depth and enables
-         TCQ, and 0 disables it. hdparm version 4.7 an above also support
-         TCQ manipulations.
-
-         Generally say Y here.
-
-config BLK_DEV_IDE_TCQ_DEPTH
-       int "Default queue depth"
-       depends on BLK_DEV_IDE_TCQ
-       default "8"
-       help
-         Maximum size of commands to enable per-drive. Any value between 1
-         and 32 is valid, with 32 being the maxium that the hardware supports.
-
-         You probably just want the default of 32 here. If you enter an invalid
-         number, the default value will be used.
-
 config BLK_DEV_IDEDMA_FORCED
        bool "Force enable legacy 2.0.X HOSTS to use DMA"
        help
index 4629760..aeac73d 100644 (file)
@@ -29,7 +29,6 @@ ide-core-$(CONFIG_BLK_DEV_IDEPNP)     += ide-pnp.o
 ide-core-$(CONFIG_IDE_ARM)             += arm/ide_arm.o
 
 # built-in only drivers from legacy/
-ide-core-$(CONFIG_BLK_DEV_IDE_PC9800)  += legacy/pc9800.o
 ide-core-$(CONFIG_BLK_DEV_BUDDHA)      += legacy/buddha.o
 ide-core-$(CONFIG_BLK_DEV_FALCON_IDE)  += legacy/falconide.o
 ide-core-$(CONFIG_BLK_DEV_GAYLE)       += legacy/gayle.o
index 1bb668b..0bb2482 100644 (file)
@@ -535,9 +535,7 @@ static void cdrom_prepare_request(struct request *rq)
        rq->flags = REQ_PC;
 }
 
-static void cdrom_queue_request_sense(ide_drive_t *drive, 
-                                     struct completion *wait,
-                                     void *sense,
+static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
                                      struct request *failed_command)
 {
        struct cdrom_info *info         = drive->driver_data;
@@ -554,7 +552,6 @@ static void cdrom_queue_request_sense(ide_drive_t *drive,
        rq->cmd[4] = rq->data_len = 18;
 
        rq->flags = REQ_SENSE;
-       rq->waiting = wait;
 
        /* NOTE! Save the failed command in "rq->buffer" */
        rq->buffer = (void *) failed_command;
@@ -574,7 +571,7 @@ ide_startstop_t ide_cdrom_error (ide_drive_t *drive, const char *msg, byte stat)
        if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
                return ide_stopped;
        /* retry only "normal" I/O: */
-       if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
+       if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
                rq->errors = 1;
                ide_end_drive_cmd(drive, stat, err);
                return ide_stopped;
@@ -608,7 +605,7 @@ ide_startstop_t ide_cdrom_abort (ide_drive_t *drive, const char *msg)
        if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
                return ide_stopped;
        /* retry only "normal" I/O: */
-       if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
+       if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
                rq->errors = 1;
                ide_end_drive_cmd(drive, BUSY_STAT, 0);
                return ide_stopped;
@@ -631,10 +628,21 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate)
                struct request *failed = (struct request *) rq->buffer;
                struct cdrom_info *info = drive->driver_data;
                void *sense = &info->sense_data;
-               
-               if (failed && failed->sense) {
-                       sense = failed->sense;
-                       failed->sense_len = rq->sense_len;
+               unsigned long flags;
+
+               if (failed) {
+                       if (failed->sense) {
+                               sense = failed->sense;
+                               failed->sense_len = rq->sense_len;
+                       }
+
+                       /*
+                        * now end failed request
+                        */
+                       spin_lock_irqsave(&ide_lock, flags);
+                       end_that_request_chunk(failed, 0, failed->data_len);
+                       end_that_request_last(failed);
+                       spin_unlock_irqrestore(&ide_lock, flags);
                }
 
                cdrom_analyze_sense_data(drive, failed, sense);
@@ -642,6 +650,9 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate)
 
        if (!rq->current_nr_sectors && blk_fs_request(rq))
                uptodate = 1;
+       /* make sure it's fully ended */
+       if (blk_pc_request(rq))
+               nsectors = (rq->data_len + 511) >> 9;
        if (!nsectors)
                nsectors = 1;
 
@@ -684,7 +695,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
 
        } else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) {
                /* All other functions, except for READ. */
-               struct completion *wait = NULL;
+               unsigned long flags;
 
                /*
                 * if we have an error, pass back CHECK_CONDITION as the
@@ -706,30 +717,23 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
                        ide_dump_status(drive, "packet command error", stat);
                }
                
-               /* Set the error flag and complete the request.
-                  Then, if we have a CHECK CONDITION status,
-                  queue a request sense command.  We must be careful,
-                  though: we don't want the thread in
-                  cdrom_queue_packet_command to wake up until
-                  the request sense has completed.  We do this
-                  by transferring the semaphore from the packet
-                  command request to the request sense request. */
-
                rq->flags |= REQ_FAILED;
-               if ((stat & ERR_STAT) != 0) {
-                       wait = rq->waiting;
-                       rq->waiting = NULL;
-                       if ((rq->flags & REQ_BLOCK_PC) != 0) {
-                               cdrom_queue_request_sense(drive, wait,
-                                                         rq->sense, rq);
-                               return 1; /* REQ_BLOCK_PC self-cares */
-                       }
-               }
 
-               cdrom_end_request(drive, 0);
+               /*
+                * instead of playing games with moving completions around,
+                * remove failed request completely and end it when the
+                * request sense has completed
+                */
+               if (stat & ERR_STAT) {
+                       spin_lock_irqsave(&ide_lock, flags);
+                       blkdev_dequeue_request(rq);
+                       HWGROUP(drive)->rq = NULL;
+                       spin_unlock_irqrestore(&ide_lock, flags);
+
+                       cdrom_queue_request_sense(drive, rq->sense, rq);
+               } else
+                       cdrom_end_request(drive, 0);
 
-               if ((stat & ERR_STAT) != 0)
-                       cdrom_queue_request_sense(drive, wait, rq->sense, rq);
        } else if (blk_fs_request(rq)) {
                int do_end_request = 0;
 
@@ -818,7 +822,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
                /* If we got a CHECK_CONDITION status,
                   queue a request sense command. */
                if ((stat & ERR_STAT) != 0)
-                       cdrom_queue_request_sense(drive, NULL, NULL, NULL);
+                       cdrom_queue_request_sense(drive, NULL, NULL);
        } else {
                blk_dump_rq_flags(rq, "ide-cd: bad rq");
                cdrom_end_request(drive, 0);
@@ -1666,14 +1670,8 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
                dma_error = HWIF(drive)->ide_dma_end(drive);
        }
 
-       if (cdrom_decode_status(drive, 0, &stat)) {
-               if ((stat & ERR_STAT) != 0) {
-                       end_that_request_chunk(rq, 0, rq->data_len);
-                       goto end_request; /* purge the whole thing... */
-               }
-               end_that_request_chunk(rq, 1, rq->data_len);
+       if (cdrom_decode_status(drive, 0, &stat))
                return ide_stopped;
-       }
 
        /*
         * using dma, transfer is complete now
@@ -2818,7 +2816,6 @@ int ide_cdrom_open_real (struct cdrom_device_info *cdi, int purpose)
        return 0;
 }
 
-
 /*
  * Close down the device.  Invalidate all cached blocks.
  */
@@ -2892,12 +2889,6 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
                devinfo->mask |= CDC_CLOSE_TRAY;
        if (!CDROM_CONFIG_FLAGS(drive)->mo_drive)
                devinfo->mask |= CDC_MO_DRIVE;
-       if (!CDROM_CONFIG_FLAGS(drive)->mrw)
-               devinfo->mask |= CDC_MRW;
-       if (!CDROM_CONFIG_FLAGS(drive)->mrw_w)
-               devinfo->mask |= CDC_MRW_W;
-       if (!CDROM_CONFIG_FLAGS(drive)->ram)
-               devinfo->mask |= CDC_RAM;
 
        devinfo->disk = drive->disk;
        return register_cdrom(devinfo);
@@ -2934,7 +2925,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
        struct cdrom_info *info = drive->driver_data;
        struct cdrom_device_info *cdi = &info->devinfo;
        struct atapi_capabilities_page cap;
-       int nslots = 1, mrw_write = 0, ram_write = 0;
+       int nslots = 1;
 
        if (drive->media == ide_optical) {
                CDROM_CONFIG_FLAGS(drive)->mo_drive = 1;
@@ -2963,17 +2954,6 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
        if (ide_cdrom_get_capabilities(drive, &cap))
                return 0;
 
-       if (!cdrom_is_mrw(cdi, &mrw_write)) {
-               CDROM_CONFIG_FLAGS(drive)->mrw = 1;
-               if (mrw_write) {
-                       CDROM_CONFIG_FLAGS(drive)->mrw_w = 1;
-                       CDROM_CONFIG_FLAGS(drive)->ram = 1;
-               }
-       }
-       if (!cdrom_is_random_writable(cdi, &ram_write))
-               if (ram_write)
-                       CDROM_CONFIG_FLAGS(drive)->ram = 1;
-
        if (cap.lock == 0)
                CDROM_CONFIG_FLAGS(drive)->no_doorlock = 1;
        if (cap.eject)
@@ -3053,9 +3033,6 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
                (CDROM_CONFIG_FLAGS(drive)->cd_r)? "-R" : "", 
                (CDROM_CONFIG_FLAGS(drive)->cd_rw)? "/RW" : "");
 
-       if (CDROM_CONFIG_FLAGS(drive)->mrw || CDROM_CONFIG_FLAGS(drive)->mrw_w)
-               printk(" CD-MR%s", CDROM_CONFIG_FLAGS(drive)->mrw_w ? "W" : "");
-
         if (CDROM_CONFIG_FLAGS(drive)->is_changer) 
                printk(" changer w/%d slots", nslots);
         else   
index 7a3bcd3..8305bca 100644 (file)
@@ -79,8 +79,6 @@ struct ide_cd_config_flags {
        __u8 dvd                : 1; /* Drive is a DVD-ROM */
        __u8 dvd_r              : 1; /* Drive can write DVD-R */
        __u8 dvd_ram            : 1; /* Drive can write DVD-RAM */
-       __u8 mrw                : 1; /* drive can read mrw */
-       __u8 mrw_w              : 1; /* drive can write mrw */
        __u8 ram                : 1; /* generic WRITE (dvd-ram/mrw) */
        __u8 test_write         : 1; /* Drive can fake writes */
        __u8 supp_disc_present  : 1; /* Changer can report exact contents
index 47761a0..9217f0c 100644 (file)
@@ -45,6 +45,8 @@
 
 #undef REALLY_SLOW_IO          /* most systems can safely undef this */
 
+//#define DEBUG
+
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -118,20 +120,6 @@ static int lba_capacity_is_ok (struct hd_driveid *id)
        return 0;       /* lba_capacity value may be bad */
 }
 
-static int idedisk_start_tag(ide_drive_t *drive, struct request *rq)
-{
-       unsigned long flags;
-       int ret = 1;
-
-       spin_lock_irqsave(&ide_lock, flags);
-
-       if (ata_pending_commands(drive) < drive->queue_depth)
-               ret = blk_queue_start_tag(drive->queue, rq);
-
-       spin_unlock_irqrestore(&ide_lock, flags);
-       return ret;
-}
-
 #ifndef CONFIG_IDE_TASKFILE_IO
 
 /*
@@ -365,18 +353,12 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
                if (drive->addressing == 1) {
                        task_ioreg_t tasklets[10];
 
-                       if (blk_rq_tagged(rq)) {
-                               tasklets[0] = nsectors.b.low;
-                               tasklets[1] = nsectors.b.high;
-                               tasklets[2] = rq->tag << 3;
-                               tasklets[3] = 0;
-                       } else {
-                               tasklets[0] = 0;
-                               tasklets[1] = 0;
-                               tasklets[2] = nsectors.b.low;
-                               tasklets[3] = nsectors.b.high;
-                       }
+                       pr_debug("%s: LBA=0x%012llx\n", drive->name, block);
 
+                       tasklets[0] = 0;
+                       tasklets[1] = 0;
+                       tasklets[2] = nsectors.b.low;
+                       tasklets[3] = nsectors.b.high;
                        tasklets[4] = (task_ioreg_t) block;
                        tasklets[5] = (task_ioreg_t) (block>>8);
                        tasklets[6] = (task_ioreg_t) (block>>16);
@@ -389,14 +371,6 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
                                tasklets[9] = (task_ioreg_t)((u64)block >> 40);
                        }
 #ifdef DEBUG
-                       printk("%s: %sing: LBAsect=%lu, sectors=%ld, "
-                               "buffer=0x%08lx, LBAsect=0x%012lx\n",
-                               drive->name,
-                               rq_data_dir(rq)==READ?"read":"writ",
-                               block,
-                               rq->nr_sectors,
-                               (unsigned long) rq->buffer,
-                               block);
                        printk("%s: 0x%02x%02x 0x%02x%02x%02x%02x%02x%02x\n",
                                drive->name, tasklets[3], tasklets[2],
                                tasklets[9], tasklets[8], tasklets[7],
@@ -415,22 +389,8 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
                        hwif->OUTB(tasklets[6], IDE_HCYL_REG);
                        hwif->OUTB(0x00|drive->select.all,IDE_SELECT_REG);
                } else {
-#ifdef DEBUG
-                       printk("%s: %sing: LBAsect=%llu, sectors=%ld, "
-                               "buffer=0x%08lx\n",
-                               drive->name,
-                               rq_data_dir(rq)==READ?"read":"writ",
-                               (unsigned long long)block, rq->nr_sectors,
-                               (unsigned long) rq->buffer);
-#endif
-                       if (blk_rq_tagged(rq)) {
-                               hwif->OUTB(nsectors.b.low, IDE_FEATURE_REG);
-                               hwif->OUTB(rq->tag << 3, IDE_NSECTOR_REG);
-                       } else {
-                               hwif->OUTB(0x00, IDE_FEATURE_REG);
-                               hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG);
-                       }
-
+                       hwif->OUTB(0x00, IDE_FEATURE_REG);
+                       hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG);
                        hwif->OUTB(block, IDE_SECTOR_REG);
                        hwif->OUTB(block>>=8, IDE_LCYL_REG);
                        hwif->OUTB(block>>=8, IDE_HCYL_REG);
@@ -444,29 +404,16 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
                head  = track % drive->head;
                cyl   = track / drive->head;
 
-               if (blk_rq_tagged(rq)) {
-                       hwif->OUTB(nsectors.b.low, IDE_FEATURE_REG);
-                       hwif->OUTB(rq->tag << 3, IDE_NSECTOR_REG);
-               } else {
-                       hwif->OUTB(0x00, IDE_FEATURE_REG);
-                       hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG);
-               }
+               pr_debug("%s: CHS=%u/%u/%u\n", drive->name, cyl, head, sect);
 
+               hwif->OUTB(0x00, IDE_FEATURE_REG);
+               hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG);
                hwif->OUTB(cyl, IDE_LCYL_REG);
                hwif->OUTB(cyl>>8, IDE_HCYL_REG);
                hwif->OUTB(head|drive->select.all,IDE_SELECT_REG);
-#ifdef DEBUG
-               printk("%s: %sing: CHS=%d/%d/%d, sectors=%ld, buffer=0x%08lx\n",
-                       drive->name, rq_data_dir(rq)==READ?"read":"writ", cyl,
-                       head, sect, rq->nr_sectors, (unsigned long) rq->buffer);
-#endif
        }
 
        if (rq_data_dir(rq) == READ) {
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-               if (blk_rq_tagged(rq))
-                       return __ide_dma_queued_read(drive);
-#endif
                if (drive->using_dma && !hwif->ide_dma_read(drive))
                        return ide_started;
 
@@ -477,10 +424,7 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
                return ide_started;
        } else {
                ide_startstop_t startstop;
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-               if (blk_rq_tagged(rq))
-                       return __ide_dma_queued_write(drive);
-#endif
+
                if (drive->using_dma && !(HWIF(drive)->ide_dma_write(drive)))
                        return ide_started;
 
@@ -550,8 +494,6 @@ static u8 get_command(ide_drive_t *drive, int cmd, ide_task_t *task)
 
        if (cmd == READ) {
                task->command_type = IDE_DRIVE_TASK_IN;
-               if (drive->using_tcq)
-                       return lba48 ? WIN_READDMA_QUEUED_EXT : WIN_READDMA_QUEUED;
                if (drive->using_dma)
                        return lba48 ? WIN_READDMA_EXT : WIN_READDMA;
                if (drive->mult_count) {
@@ -562,8 +504,6 @@ static u8 get_command(ide_drive_t *drive, int cmd, ide_task_t *task)
                return lba48 ? WIN_READ_EXT : WIN_READ;
        } else {
                task->command_type = IDE_DRIVE_TASK_RAW_WRITE;
-               if (drive->using_tcq)
-                       return lba48 ? WIN_WRITEDMA_QUEUED_EXT : WIN_WRITEDMA_QUEUED;
                if (drive->using_dma)
                        return lba48 ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
                if (drive->mult_count) {
@@ -589,23 +529,13 @@ static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsi
 
        nsectors.all = (u16) rq->nr_sectors;
 
-#ifdef DEBUG
-       printk("%s: %sing: ", drive->name, (rq_data_dir(rq)==READ) ? "read" : "writ");
-       printk("CHS=%d/%d/%d, ", cyl, head, sect);
-       printk("sectors=%ld, ", rq->nr_sectors);
-       printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
-#endif
+       pr_debug("%s: CHS=%u/%u/%u\n", drive->name, cyl, head, sect);
 
        memset(&args, 0, sizeof(ide_task_t));
 
        sectors = (rq->nr_sectors == 256) ? 0x00 : rq->nr_sectors;
 
-       if (blk_rq_tagged(rq)) {
-               args.tfRegister[IDE_FEATURE_OFFSET] = sectors;
-               args.tfRegister[IDE_NSECTOR_OFFSET] = rq->tag << 3;
-       } else
-               args.tfRegister[IDE_NSECTOR_OFFSET] = sectors;
-
+       args.tfRegister[IDE_NSECTOR_OFFSET]     = sectors;
        args.tfRegister[IDE_SECTOR_OFFSET]      = sect;
        args.tfRegister[IDE_LCYL_OFFSET]        = cyl;
        args.tfRegister[IDE_HCYL_OFFSET]        = (cyl>>8);
@@ -625,23 +555,11 @@ static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, u
 
        nsectors.all = (u16) rq->nr_sectors;
 
-#ifdef DEBUG
-       printk("%s: %sing: ", drive->name, (rq_data_dir(rq)==READ) ? "read" : "writ");
-       printk("LBAsect=%lld, ", block);
-       printk("sectors=%ld, ", rq->nr_sectors);
-       printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
-#endif
-
        memset(&args, 0, sizeof(ide_task_t));
 
        sectors = (rq->nr_sectors == 256) ? 0x00 : rq->nr_sectors;
 
-       if (blk_rq_tagged(rq)) {
-               args.tfRegister[IDE_FEATURE_OFFSET] = sectors;
-               args.tfRegister[IDE_NSECTOR_OFFSET] = rq->tag << 3;
-       } else
-               args.tfRegister[IDE_NSECTOR_OFFSET] = sectors;
-
+       args.tfRegister[IDE_NSECTOR_OFFSET]     = sectors;
        args.tfRegister[IDE_SECTOR_OFFSET]      = block;
        args.tfRegister[IDE_LCYL_OFFSET]        = (block>>=8);
        args.tfRegister[IDE_HCYL_OFFSET]        = (block>>=8);
@@ -667,27 +585,12 @@ static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, u
 
        nsectors.all = (u16) rq->nr_sectors;
 
-#ifdef DEBUG
-       printk("%s: %sing: ", drive->name, (rq_data_dir(rq)==READ) ? "read" : "writ");
-       printk("LBAsect=%lld, ", block);
-       printk("sectors=%ld, ", rq->nr_sectors);
-       printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
-#endif
-
        memset(&args, 0, sizeof(ide_task_t));
 
        sectors = (rq->nr_sectors == 65536) ? 0 : rq->nr_sectors;
 
-       if (blk_rq_tagged(rq)) {
-               args.tfRegister[IDE_FEATURE_OFFSET] = sectors;
-               args.tfRegister[IDE_NSECTOR_OFFSET] = rq->tag << 3;
-               args.hobRegister[IDE_FEATURE_OFFSET] = sectors >> 8;
-               args.hobRegister[IDE_NSECTOR_OFFSET] = 0;
-       } else {
-               args.tfRegister[IDE_NSECTOR_OFFSET] = sectors;
-               args.hobRegister[IDE_NSECTOR_OFFSET] = sectors >> 8;
-       }
-
+       args.tfRegister[IDE_NSECTOR_OFFSET]     = sectors;
+       args.hobRegister[IDE_NSECTOR_OFFSET]    = sectors >> 8;
        args.tfRegister[IDE_SECTOR_OFFSET]      = block;        /* low lba */
        args.tfRegister[IDE_LCYL_OFFSET]        = (block>>=8);  /* mid lba */
        args.tfRegister[IDE_HCYL_OFFSET]        = (block>>=8);  /* hi  lba */
@@ -717,12 +620,9 @@ static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, s
                return ide_stopped;
        }
 
-       if (drive->using_tcq && idedisk_start_tag(drive, rq)) {
-               if (!ata_pending_commands(drive))
-                       BUG();
-
-               return ide_started;
-       }
+       pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n",
+                drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
+                block, rq->nr_sectors, (unsigned long)rq->buffer);
 
        if (hwif->rw_disk)
                return hwif->rw_disk(drive, rq, block);
@@ -811,7 +711,6 @@ ide_startstop_t idedisk_error (ide_drive_t *drive, const char *msg, u8 stat)
        ide_hwif_t *hwif;
        struct request *rq;
        u8 err;
-       int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS;
 
        err = idedisk_dump_status(drive, msg, stat);
 
@@ -851,22 +750,8 @@ ide_startstop_t idedisk_error (ide_drive_t *drive, const char *msg, u8 stat)
                        rq->errors |= ERROR_RECAL;
                }
        }
-       if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ) {
-               /*
-                * try_to_flush_leftover_data() is invoked in response to
-                * a drive unexpectedly having its DRQ_STAT bit set.  As
-                * an alternative to resetting the drive, this routine
-                * tries to clear the condition by read a sector's worth
-                * of data from the drive.  Of course, this may not help
-                * if the drive is *waiting* for data from *us*.
-                */
-               while (i > 0) {
-                       u32 buffer[16];
-                       unsigned int wcount = (i > 16) ? 16 : i;
-                       i -= wcount;
-                       taskfile_input_data(drive, buffer, wcount);
-               }
-       }
+       if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ)
+               try_to_flush_leftover_data(drive);
        if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) {
                /* force an abort */
                hwif->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
@@ -963,7 +848,6 @@ static unsigned long long idedisk_read_native_max_address_ext(ide_drive_t *drive
        return addr;
 }
 
-#ifdef CONFIG_IDEDISK_STROKE
 /*
  * Sets maximum virtual LBA address of the drive.
  * Returns new maximum virtual LBA address (> 0) or 0 on failure.
@@ -1032,8 +916,6 @@ static unsigned long long idedisk_set_max_address_ext(ide_drive_t *drive, unsign
        return addr_set;
 }
 
-#endif /* CONFIG_IDEDISK_STROKE */
-
 static unsigned long long sectors_to_MB(unsigned long long n)
 {
        n <<= 9;                /* make it bytes */
@@ -1080,7 +962,10 @@ static inline void idedisk_check_hpa(ide_drive_t *drive)
                         drive->name,
                         capacity, sectors_to_MB(capacity),
                         set_max, sectors_to_MB(set_max));
-#ifdef CONFIG_IDEDISK_STROKE
+
+       if (!drive->stroke)
+               return;
+
        if (lba48)
                set_max = idedisk_set_max_address_ext(drive, set_max);
        else
@@ -1090,7 +975,6 @@ static inline void idedisk_check_hpa(ide_drive_t *drive)
                printk(KERN_INFO "%s: Host Protected Area disabled.\n",
                                 drive->name);
        }
-#endif
 }
 
 /*
@@ -1403,34 +1287,6 @@ static int set_acoustic (ide_drive_t *drive, int arg)
        return 0;
 }
 
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-static int set_using_tcq(ide_drive_t *drive, int arg)
-{
-       int ret;
-
-       if (!drive->driver)
-               return -EPERM;
-       if (arg == drive->queue_depth && drive->using_tcq)
-               return 0;
-
-       /*
-        * set depth, but check also id for max supported depth
-        */
-       drive->queue_depth = arg ? arg : 1;
-       if (drive->id) {
-               if (drive->queue_depth > drive->id->queue_depth + 1)
-                       drive->queue_depth = drive->id->queue_depth + 1;
-       }
-
-       if (arg)
-               ret = __ide_dma_queued_on(drive);
-       else
-               ret = __ide_dma_queued_off(drive);
-
-       return ret ? -EIO : 0;
-}
-#endif
-
 /*
  * drive->addressing:
  *     0: 28-bit
@@ -1466,9 +1322,6 @@ static void idedisk_add_settings(ide_drive_t *drive)
        ide_add_setting(drive,  "acoustic",             SETTING_RW,                                     HDIO_GET_ACOUSTIC,      HDIO_SET_ACOUSTIC,      TYPE_BYTE,      0,      254,                            1,      1,      &drive->acoustic,               set_acoustic);
        ide_add_setting(drive,  "failures",             SETTING_RW,                                     -1,                     -1,                     TYPE_INT,       0,      65535,                          1,      1,      &drive->failures,               NULL);
        ide_add_setting(drive,  "max_failures",         SETTING_RW,                                     -1,                     -1,                     TYPE_INT,       0,      65535,                          1,      1,      &drive->max_failures,           NULL);
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-       ide_add_setting(drive,  "using_tcq",            SETTING_RW,                                     HDIO_GET_QDMA,          HDIO_SET_QDMA,          TYPE_BYTE,      0,      IDE_MAX_TAG,                    1,              1,              &drive->using_tcq,              set_using_tcq);
-#endif
 }
 
 /*
@@ -1679,11 +1532,6 @@ static void idedisk_setup (ide_drive_t *drive)
                drive->wcache = 1;
 
        write_cache(drive, 1);
-
-#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
-       if (drive->using_dma)
-               __ide_dma_queued_on(drive);
-#endif
 }
 
 static void ide_cacheflush_p(ide_drive_t *drive)
index 4f44c29..19ae46d 100644 (file)
@@ -513,9 +513,7 @@ int __ide_dma_off_quietly (ide_drive_t *drive)
 
        if (HWIF(drive)->ide_dma_host_off(drive))
                return 1;
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-       __ide_dma_queued_off(drive);
-#endif
+
        return 0;
 }
 
index ae2d5b9..56fec5c 100644 (file)
@@ -1482,7 +1482,7 @@ static int idefloppy_get_capacity (ide_drive_t *drive)
 **
 */
 
-static int idefloppy_get_format_capacities(ide_drive_t *drive, int *arg)
+static int idefloppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
 {
         idefloppy_pc_t pc;
        idefloppy_capacity_header_t *header;
@@ -1490,7 +1490,7 @@ static int idefloppy_get_format_capacities(ide_drive_t *drive, int *arg)
        int i, descriptors, blocks, length;
        int u_array_size;
        int u_index;
-       int *argp;
+       int __user *argp;
 
        if (get_user(u_array_size, arg))
                return (-EFAULT);
@@ -1558,7 +1558,7 @@ static int idefloppy_get_format_capacities(ide_drive_t *drive, int *arg)
 **        0x01 - verify media after format.
 */
 
-static int idefloppy_begin_format(ide_drive_t *drive, int *arg)
+static int idefloppy_begin_format(ide_drive_t *drive, int __user *arg)
 {
        int blocks;
        int length;
@@ -1591,7 +1591,7 @@ static int idefloppy_begin_format(ide_drive_t *drive, int *arg)
 ** the dsc bit, and return either 0 or 65536.
 */
 
-static int idefloppy_get_format_progress(ide_drive_t *drive, int *arg)
+static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg)
 {
        idefloppy_floppy_t *floppy = drive->driver_data;
        idefloppy_pc_t pc;
@@ -1945,6 +1945,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
        struct block_device *bdev = inode->i_bdev;
        ide_drive_t *drive = bdev->bd_disk->private_data;
        idefloppy_floppy_t *floppy = drive->driver_data;
+       void __user *argp = (void __user *)arg;
        int err = generic_ide_ioctl(bdev, cmd, arg);
        int prevent = (arg) ? 1 : 0;
        idefloppy_pc_t pc;
@@ -1972,7 +1973,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
        case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED:
                return 0;
        case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:
-               return idefloppy_get_format_capacities(drive, (int *)arg);
+               return idefloppy_get_format_capacities(drive, argp);
        case IDEFLOPPY_IOCTL_FORMAT_START:
 
                if (!(file->f_mode & 2))
@@ -1988,7 +1989,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
 
                set_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
 
-               err = idefloppy_begin_format(drive, (int *)arg);
+               err = idefloppy_begin_format(drive, argp);
                if (err)
                        clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
                return err;
@@ -1999,7 +2000,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
                ** format progress reporting.
                */
        case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
-               return idefloppy_get_format_progress(drive, (int *)arg);
+               return idefloppy_get_format_progress(drive, argp);
        }
        return -EINVAL;
 }
index 37f95e1..ff5b16a 100644 (file)
@@ -97,10 +97,7 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
 
        if (!end_that_request_first(rq, uptodate, nr_sectors)) {
                add_disk_randomness(rq->rq_disk);
-               if (!blk_rq_tagged(rq))
-                       blkdev_dequeue_request(rq);
-               else
-                       blk_queue_end_tag(drive->queue, rq);
+               blkdev_dequeue_request(rq);
                HWGROUP(drive)->rq = NULL;
                end_that_request_last(rq);
                ret = 0;
@@ -855,18 +852,7 @@ void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
                drive->sleep = 0;
                drive->service_start = jiffies;
 
-queue_next:
-               if (!ata_can_queue(drive)) {
-                       if (!ata_pending_commands(drive))
-                               hwgroup->busy = 0;
-
-                       break;
-               }
-
                if (blk_queue_plugged(drive->queue)) {
-                       if (drive->using_tcq)
-                               break;
-
                        printk(KERN_ERR "ide: huh? queue was plugged!\n");
                        break;
                }
@@ -877,7 +863,7 @@ queue_next:
                 */
                rq = elv_next_request(drive->queue);
                if (!rq) {
-                       hwgroup->busy = !!ata_pending_commands(drive);
+                       hwgroup->busy = 0;
                        break;
                }
 
@@ -900,9 +886,6 @@ queue_next:
                        break;
                }
 
-               if (!rq->bio && ata_pending_commands(drive))
-                       break;
-
                hwgroup->rq = rq;
 
                /*
@@ -922,8 +905,6 @@ queue_next:
                spin_lock_irq(&ide_lock);
                if (hwif->irq != masked_irq)
                        enable_irq(hwif->irq);
-               if (startstop == ide_released)
-                       goto queue_next;
                if (startstop == ide_stopped)
                        hwgroup->busy = 0;
        }
index 5b5db47..6b9bcdb 100644 (file)
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
  */
 
-#include <linux/ide.h>
 #include <linux/init.h>
-
 #include <linux/pnp.h>
-
-#define GENERIC_HD_DATA                0
-#define GENERIC_HD_ERROR       1
-#define GENERIC_HD_NSECTOR     2
-#define GENERIC_HD_SECTOR      3
-#define GENERIC_HD_LCYL                4
-#define GENERIC_HD_HCYL                5
-#define GENERIC_HD_SELECT      6
-#define GENERIC_HD_STATUS      7
-
-static int generic_ide_offsets[IDE_NR_PORTS] = {
-       GENERIC_HD_DATA, GENERIC_HD_ERROR, GENERIC_HD_NSECTOR, 
-       GENERIC_HD_SECTOR, GENERIC_HD_LCYL, GENERIC_HD_HCYL,
-       GENERIC_HD_SELECT, GENERIC_HD_STATUS, -1, -1
-};
+#include <linux/ide.h>
 
 /* Add your devices here :)) */
 struct pnp_device_id idepnp_devices[] = {
@@ -52,12 +36,11 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
        if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0)))
                return -1;
 
-       ide_setup_ports(&hw, (unsigned long) pnp_port_start(dev, 0),
-                       generic_ide_offsets,
-                       (unsigned long) pnp_port_start(dev, 1),
-                       0, NULL,
-//                     generic_pnp_ide_iops,
-                       pnp_irq(dev, 0));
+       memset(&hw, 0, sizeof(hw));
+       ide_std_init_ports(&hw, pnp_port_start(dev, 0),
+                               pnp_port_start(dev, 1));
+       hw.irq = pnp_irq(dev, 0);
+       hw.dma = NO_DMA;
 
        index = ide_register_hw(&hw, &hwif);
 
@@ -86,11 +69,7 @@ static struct pnp_driver idepnp_driver = {
        .remove         = idepnp_remove,
 };
 
-
-void pnpide_init(int enable)
+void __init pnpide_init(void)
 {
-       if(enable)
-               pnp_register_driver(&idepnp_driver);
-       else
-               pnp_unregister_driver(&idepnp_driver);
+       pnp_register_driver(&idepnp_driver);
 }
index ed26518..4ffaf90 100644 (file)
@@ -241,17 +241,6 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
        drive->media = ide_disk;
        printk("%s DISK drive\n", (drive->is_flash) ? "CFA" : "ATA" );
        QUIRK_LIST(drive);
-
-       /* Initialize queue depth settings */
-       drive->queue_depth = 1;
-#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEPTH
-       drive->queue_depth = CONFIG_BLK_DEV_IDE_TCQ_DEPTH;
-#else
-       drive->queue_depth = drive->id->queue_depth + 1;
-#endif
-       if (drive->queue_depth < 1 || drive->queue_depth > IDE_MAX_TAG)
-               drive->queue_depth = IDE_MAX_TAG;
-
        return;
 
 err_misc:
@@ -646,8 +635,6 @@ static void hwif_register (ide_hwif_t *hwif)
        device_register(&hwif->gendev);
 }
 
-//EXPORT_SYMBOL(hwif_register);
-
 #ifdef CONFIG_PPC
 static int wait_hwif_ready(ide_hwif_t *hwif)
 {
@@ -690,7 +677,7 @@ static int wait_hwif_ready(ide_hwif_t *hwif)
  * This routine only knows how to look for drive units 0 and 1
  * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
  */
-void probe_hwif (ide_hwif_t *hwif)
+static void probe_hwif(ide_hwif_t *hwif)
 {
        unsigned int unit;
        unsigned long flags;
@@ -834,9 +821,7 @@ void probe_hwif (ide_hwif_t *hwif)
        }
 }
 
-EXPORT_SYMBOL(probe_hwif);
-
-int hwif_init (ide_hwif_t *hwif);
+static int hwif_init(ide_hwif_t *hwif);
 int probe_hwif_init (ide_hwif_t *hwif)
 {
        probe_hwif(hwif);
@@ -871,7 +856,7 @@ EXPORT_SYMBOL(probe_hwif_init);
  *
  * This routine detects and reports such situations, but does not fix them.
  */
-void save_match (ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
+static void save_match(ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
 {
        ide_hwif_t *m = *match;
 
@@ -884,7 +869,6 @@ void save_match (ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
        if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */
                *match = new;
 }
-EXPORT_SYMBOL(save_match);
 #endif /* MAX_HWIFS > 1 */
 
 /*
@@ -1231,9 +1215,7 @@ static void init_gendisk (ide_hwif_t *hwif)
                        THIS_MODULE, ata_probe, ata_lock, hwif);
 }
 
-EXPORT_SYMBOL(init_gendisk);
-
-int hwif_init (ide_hwif_t *hwif)
+static int hwif_init(ide_hwif_t *hwif)
 {
        int old_irq, unit;
 
@@ -1301,8 +1283,6 @@ out:
        return 0;
 }
 
-EXPORT_SYMBOL(hwif_init);
-
 int ideprobe_init (void)
 {
        unsigned int index;
index 4b799d0..b7e5cb8 100644 (file)
@@ -233,27 +233,6 @@ static int proc_ide_write_config(struct file *file, const char __user *buffer,
                        }
 #endif /* CONFIG_BLK_DEV_IDEPCI */
                } else {        /* not pci */
-#if !defined(__mc68000__) && !defined(CONFIG_APUS)
-
-/*
-* Geert Uytterhoeven
-*
-* unless you can explain me what it really does.
-* On m68k, we don't have outw() and outl() yet,
-* and I need a good reason to implement it.
-* 
-* BTW, IMHO the main remaining portability problem with the IDE driver 
-* is that it mixes IO (ioport) and MMIO (iomem) access on different platforms.
-* 
-* I think all accesses should be done using
-* 
-*     ide_in[bwl](ide_device_instance, offset)
-*     ide_out[bwl](ide_device_instance, value, offset)
-* 
-* so the architecture specific code can #define ide_{in,out}[bwl] to the
-* appropriate function.
-* 
-*/
                        switch (r->size) {
                                case 1: hwif->OUTB(val, reg);
                                        break;
@@ -262,7 +241,6 @@ static int proc_ide_write_config(struct file *file, const char __user *buffer,
                                case 4: hwif->OUTL(val, reg);
                                        break;
                        }
-#endif /* !__mc68000__ && !CONFIG_APUS */
                }
        }
        spin_unlock_irqrestore(&ide_lock, flags);
@@ -280,7 +258,7 @@ parse_error:
        goto out1;
 }
 
-int proc_ide_read_config
+static int proc_ide_read_config
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
        char            *out = page;
@@ -317,8 +295,6 @@ int proc_ide_read_config
        PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
-EXPORT_SYMBOL(proc_ide_read_config);
-
 static int proc_ide_read_imodel
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
@@ -345,16 +321,13 @@ static int proc_ide_read_imodel
                case ide_cy82c693:      name = "cy82c693";      break;
                case ide_4drives:       name = "4drives";       break;
                case ide_pmac:          name = "mac-io";        break;
-               case ide_pc9800:        name = "pc9800";        break;
                default:                name = "(unknown)";     break;
        }
        len = sprintf(page, "%s\n", name);
        PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
-EXPORT_SYMBOL(proc_ide_read_imodel);
-
-int proc_ide_read_mate
+static int proc_ide_read_mate
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
        ide_hwif_t      *hwif = (ide_hwif_t *) data;
@@ -367,9 +340,7 @@ int proc_ide_read_mate
        PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
-EXPORT_SYMBOL(proc_ide_read_mate);
-
-int proc_ide_read_channel
+static int proc_ide_read_channel
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
        ide_hwif_t      *hwif = (ide_hwif_t *) data;
@@ -381,9 +352,7 @@ int proc_ide_read_channel
        PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
-EXPORT_SYMBOL(proc_ide_read_channel);
-
-int proc_ide_read_identify
+static int proc_ide_read_identify
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
        ide_drive_t     *drive = (ide_drive_t *)data;
@@ -425,9 +394,7 @@ int proc_ide_read_identify
        PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
-EXPORT_SYMBOL(proc_ide_read_identify);
-
-int proc_ide_read_settings
+static int proc_ide_read_settings
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
        ide_drive_t     *drive = (ide_drive_t *) data;
@@ -459,12 +426,10 @@ int proc_ide_read_settings
        PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
-EXPORT_SYMBOL(proc_ide_read_settings);
-
 #define MAX_LEN        30
 
-int proc_ide_write_settings(struct file *file, const char __user *buffer,
-                           unsigned long count, void *data)
+static int proc_ide_write_settings(struct file *file, const char __user *buffer,
+                                  unsigned long count, void *data)
 {
        ide_drive_t     *drive = (ide_drive_t *) data;
        char            name[MAX_LEN + 1];
@@ -555,8 +520,6 @@ parse_error:
        return -EINVAL;
 }
 
-EXPORT_SYMBOL(proc_ide_write_settings);
-
 int proc_ide_read_capacity
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
@@ -568,8 +531,6 @@ int proc_ide_read_capacity
        PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
-EXPORT_SYMBOL(proc_ide_read_capacity);
-
 int proc_ide_read_geometry
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
@@ -588,7 +549,7 @@ int proc_ide_read_geometry
 
 EXPORT_SYMBOL(proc_ide_read_geometry);
 
-int proc_ide_read_dmodel
+static int proc_ide_read_dmodel
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
        ide_drive_t     *drive = (ide_drive_t *) data;
@@ -600,9 +561,7 @@ int proc_ide_read_dmodel
        PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
-EXPORT_SYMBOL(proc_ide_read_dmodel);
-
-int proc_ide_read_driver
+static int proc_ide_read_driver
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
        ide_drive_t     *drive = (ide_drive_t *) data;
@@ -614,9 +573,7 @@ int proc_ide_read_driver
        PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
-EXPORT_SYMBOL(proc_ide_read_driver);
-
-int proc_ide_write_driver
+static int proc_ide_write_driver
        (struct file *file, const char __user *buffer, unsigned long count, void *data)
 {
        ide_drive_t     *drive = (ide_drive_t *) data;
@@ -634,9 +591,7 @@ int proc_ide_write_driver
        return count;
 }
 
-EXPORT_SYMBOL(proc_ide_write_driver);
-
-int proc_ide_read_media
+static int proc_ide_read_media
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
        ide_drive_t     *drive = (ide_drive_t *) data;
@@ -660,8 +615,6 @@ int proc_ide_read_media
        PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
-EXPORT_SYMBOL(proc_ide_read_media);
-
 static ide_proc_entry_t generic_drive_entries[] = {
        { "driver",     S_IFREG|S_IRUGO,        proc_ide_read_driver,   proc_ide_write_driver },
        { "identify",   S_IFREG|S_IRUSR,        proc_ide_read_identify, NULL },
@@ -688,8 +641,6 @@ void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void
        }
 }
 
-EXPORT_SYMBOL(ide_add_proc_entries);
-
 void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p)
 {
        if (!dir || !p)
@@ -700,9 +651,7 @@ void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p)
        }
 }
 
-EXPORT_SYMBOL(ide_remove_proc_entries);
-
-void create_proc_ide_drives(ide_hwif_t *hwif)
+static void create_proc_ide_drives(ide_hwif_t *hwif)
 {
        int     d;
        struct proc_dir_entry *ent;
@@ -726,9 +675,7 @@ void create_proc_ide_drives(ide_hwif_t *hwif)
        }
 }
 
-EXPORT_SYMBOL(create_proc_ide_drives);
-
-void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
+static void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
 {
        ide_driver_t *driver = drive->driver;
 
@@ -741,8 +688,6 @@ void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
        }
 }
 
-EXPORT_SYMBOL(destroy_proc_ide_device);
-
 void destroy_proc_ide_drives(ide_hwif_t *hwif)
 {
        int     d;
@@ -754,8 +699,6 @@ void destroy_proc_ide_drives(ide_hwif_t *hwif)
        }
 }
 
-EXPORT_SYMBOL(destroy_proc_ide_drives);
-
 static ide_proc_entry_t hwif_entries[] = {
        { "channel",    S_IFREG|S_IRUGO,        proc_ide_read_channel,  NULL },
        { "config",     S_IFREG|S_IRUGO|S_IWUSR,proc_ide_read_config,   proc_ide_write_config },
@@ -843,13 +786,9 @@ void proc_ide_create(void)
                entry->proc_fops = &ide_drivers_operations;
 }
 
-EXPORT_SYMBOL(proc_ide_create);
-
 void proc_ide_destroy(void)
 {
        remove_proc_entry("ide/drivers", proc_ide_root);
        destroy_proc_ide_interfaces();
        remove_proc_entry("ide", 0);
 }
-
-EXPORT_SYMBOL(proc_ide_destroy);
index 7603f6a..480426f 100644 (file)
@@ -2674,7 +2674,7 @@ static idetape_stage_t *idetape_kmalloc_stage (idetape_tape_t *tape)
        return __idetape_kmalloc_stage(tape, 0, 0);
 }
 
-static void idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t *stage, const char *buf, int n)
+static void idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t *stage, const char __user *buf, int n)
 {
        struct idetape_bh *bh = tape->bh;
        int count;
@@ -2701,7 +2701,7 @@ static void idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t
        tape->bh = bh;
 }
 
-static void idetape_copy_stage_to_user (idetape_tape_t *tape, char *buf, idetape_stage_t *stage, int n)
+static void idetape_copy_stage_to_user (idetape_tape_t *tape, char __user *buf, idetape_stage_t *stage, int n)
 {
        struct idetape_bh *bh = tape->bh;
        int count;
@@ -3610,6 +3610,7 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, unsigned l
 {
        idetape_tape_t *tape = drive->driver_data;
        idetape_config_t config;
+       void __user *argp = (void __user *)arg;
 
 #if IDETAPE_DEBUG_LOG  
        if (tape->debug_level >= 4)
@@ -3617,7 +3618,7 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, unsigned l
 #endif /* IDETAPE_DEBUG_LOG */
        switch (cmd) {
                case 0x0340:
-                       if (copy_from_user ((char *) &config, (char *) arg, sizeof (idetape_config_t)))
+                       if (copy_from_user(&config, argp, sizeof (idetape_config_t)))
                                return -EFAULT;
                        tape->best_dsc_rw_frequency = config.dsc_rw_frequency;
                        tape->max_stages = config.nr_stages;
@@ -3625,7 +3626,7 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, unsigned l
                case 0x0350:
                        config.dsc_rw_frequency = (int) tape->best_dsc_rw_frequency;
                        config.nr_stages = tape->max_stages; 
-                       if (copy_to_user((char *) arg, (char *) &config, sizeof (idetape_config_t)))
+                       if (copy_to_user(argp, &config, sizeof (idetape_config_t)))
                                return -EFAULT;
                        break;
                default:
@@ -3747,7 +3748,7 @@ static int idetape_space_over_filemarks (ide_drive_t *drive,short mt_op,int mt_c
  *     will no longer hit performance.
  *      This is not applicable to Onstream.
  */
-static ssize_t idetape_chrdev_read (struct file *file, char *buf,
+static ssize_t idetape_chrdev_read (struct file *file, char __user *buf,
                                    size_t count, loff_t *ppos)
 {
        ide_drive_t *drive = file->private_data;
@@ -3810,7 +3811,7 @@ finish:
        return actually_read;
 }
 
-static ssize_t idetape_chrdev_write (struct file *file, const char *buf,
+static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf,
                                     size_t count, loff_t *ppos)
 {
        ide_drive_t *drive = file->private_data;
@@ -4127,6 +4128,7 @@ static int idetape_chrdev_ioctl (struct inode *inode, struct file *file, unsigne
        struct mtget mtget;
        struct mtpos mtpos;
        int block_offset = 0, position = tape->first_frame_position;
+       void __user *argp = (void __user *)arg;
 
 #if IDETAPE_DEBUG_LOG
        if (tape->debug_level >= 3)
@@ -4146,7 +4148,7 @@ static int idetape_chrdev_ioctl (struct inode *inode, struct file *file, unsigne
        }
        switch (cmd) {
                case MTIOCTOP:
-                       if (copy_from_user((char *) &mtop, (char *) arg, sizeof (struct mtop)))
+                       if (copy_from_user(&mtop, argp, sizeof (struct mtop)))
                                return -EFAULT;
                        return (idetape_mtioctop(drive,mtop.mt_op,mtop.mt_count));
                case MTIOCGET:
@@ -4157,12 +4159,12 @@ static int idetape_chrdev_ioctl (struct inode *inode, struct file *file, unsigne
                        if (tape->drv_write_prot) {
                                mtget.mt_gstat |= GMT_WR_PROT(0xffffffff);
                        }
-                       if (copy_to_user((char *) arg,(char *) &mtget, sizeof(struct mtget)))
+                       if (copy_to_user(argp, &mtget, sizeof(struct mtget)))
                                return -EFAULT;
                        return 0;
                case MTIOCPOS:
                        mtpos.mt_blkno = position / tape->user_bs_factor - block_offset;
-                       if (copy_to_user((char *) arg,(char *) &mtpos, sizeof(struct mtpos)))
+                       if (copy_to_user(argp, &mtpos, sizeof(struct mtpos)))
                                return -EFAULT;
                        return 0;
                default:
index c684ad5..98f4f3e 100644 (file)
@@ -201,14 +201,6 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
                        if (!hwif->ide_dma_read(drive))
                                return ide_started;
                        break;
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-               case WIN_READDMA_QUEUED:
-               case WIN_READDMA_QUEUED_EXT:
-                       return __ide_dma_queued_read(drive);
-               case WIN_WRITEDMA_QUEUED:
-               case WIN_WRITEDMA_QUEUED_EXT:
-                       return __ide_dma_queued_write(drive);
-#endif
                default:
                        if (task->handler == NULL)
                                return ide_stopped;
@@ -309,38 +301,18 @@ EXPORT_SYMBOL(task_no_data_intr);
  */
 #ifndef CONFIG_IDE_TASKFILE_IO
 
-#define task_map_rq(rq, flags)         ide_map_buffer((rq), (flags))
-#define task_unmap_rq(rq, buf, flags)  ide_unmap_buffer((rq), (buf), (flags))
-
 /*
  * Handler for command with PIO data-in phase, READ
  */
-/*
- * FIXME before 2.4 enable ...
- *     DATA integrity issue upon error. <andre@linux-ide.org>
- */
 ide_startstop_t task_in_intr (ide_drive_t *drive)
 {
        struct request *rq      = HWGROUP(drive)->rq;
        ide_hwif_t *hwif        = HWIF(drive);
        char *pBuf              = NULL;
        u8 stat;
-       unsigned long flags;
 
        if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) {
                if (stat & (ERR_STAT|DRQ_STAT)) {
-#if 0
-                       DTF("%s: attempting to recover last " \
-                               "sector counter status=0x%02x\n",
-                               drive->name, stat);
-                       /*
-                        * Expect a BUG BOMB if we attempt to rewind the
-                        * offset in the BH aka PAGE in the current BLOCK
-                        * segment.  This is different than the HOST segment.
-                        */
-#endif
-                       if (!rq->bio)
-                               rq->current_nr_sectors++;
                        return DRIVER(drive)->error(drive, "task_in_intr", stat);
                }
                if (!(stat & BUSY_STAT)) {
@@ -350,39 +322,13 @@ ide_startstop_t task_in_intr (ide_drive_t *drive)
                        return ide_started;  
                }
        }
-#if 0
 
-       /*
-        * Holding point for a brain dump of a thought :-/
-        */
-
-       if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) {
-               DTF("%s: READ attempting to recover last " \
-                       "sector counter status=0x%02x\n",
-                       drive->name, stat);
-               rq->current_nr_sectors++;
-               return DRIVER(drive)->error(drive, "task_in_intr", stat);
-        }
-       if (!rq->current_nr_sectors)
-               if (!DRIVER(drive)->end_request(drive, 1, 0))
-                       return ide_stopped;
-
-       if (--rq->current_nr_sectors <= 0)
-               if (!DRIVER(drive)->end_request(drive, 1, 0))
-                       return ide_stopped;
-#endif
-
-       pBuf = task_map_rq(rq, &flags);
+       pBuf = rq->buffer + task_rq_offset(rq);
        DTF("Read: %p, rq->current_nr_sectors: %d, stat: %02x\n",
                pBuf, (int) rq->current_nr_sectors, stat);
        taskfile_input_data(drive, pBuf, SECTOR_WORDS);
-       task_unmap_rq(rq, pBuf, &flags);
-       /*
-        * FIXME :: We really can not legally get a new page/bh
-        * regardless, if this is the end of our segment.
-        * BH walking or segment can only be updated after we have a good
-        * hwif->INB(IDE_STATUS_REG); return.
-        */
+
+       /* FIXME: check drive status */
        if (--rq->current_nr_sectors <= 0)
                if (!DRIVER(drive)->end_request(drive, 1, 0))
                        return ide_stopped;
@@ -407,21 +353,10 @@ ide_startstop_t task_mulin_intr (ide_drive_t *drive)
        char *pBuf              = NULL;
        unsigned int msect      = drive->mult_count;
        unsigned int nsect;
-       unsigned long flags;
        u8 stat;
 
        if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) {
                if (stat & (ERR_STAT|DRQ_STAT)) {
-                       if (!rq->bio) {
-                               rq->current_nr_sectors += drive->mult_count;
-                               /*
-                                * NOTE: could rewind beyond beginning :-/
-                                */
-                       } else {
-                               printk(KERN_ERR "%s: MULTI-READ assume all data " \
-                                       "transfered is bad status=0x%02x\n",
-                                       drive->name, stat);
-                       }
                        return DRIVER(drive)->error(drive, "task_mulin_intr", stat);
                }
                /* no data yet, so wait for another interrupt */
@@ -434,21 +369,16 @@ ide_startstop_t task_mulin_intr (ide_drive_t *drive)
                nsect = rq->current_nr_sectors;
                if (nsect > msect)
                        nsect = msect;
-               pBuf = task_map_rq(rq, &flags);
+               pBuf = rq->buffer + task_rq_offset(rq);
                DTF("Multiread: %p, nsect: %d, msect: %d, " \
                        " rq->current_nr_sectors: %d\n",
                        pBuf, nsect, msect, rq->current_nr_sectors);
                taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS);
-               task_unmap_rq(rq, pBuf, &flags);
                rq->errors = 0;
                rq->current_nr_sectors -= nsect;
                msect -= nsect;
-               /*
-                * FIXME :: We really can not legally get a new page/bh
-                * regardless, if this is the end of our segment.
-                * BH walking or segment can only be updated after we have a
-                * good hwif->INB(IDE_STATUS_REG); return.
-                */
+
+               /* FIXME: check drive status */
                if (!rq->current_nr_sectors) {
                        if (!DRIVER(drive)->end_request(drive, 1, 0))
                                return ide_stopped;
@@ -467,8 +397,6 @@ EXPORT_SYMBOL(task_mulin_intr);
  */
 ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
 {
-       char *pBuf              = NULL;
-       unsigned long flags;
        ide_startstop_t startstop;
 
        if (ide_wait_stat(&startstop, drive, DATA_READY,
@@ -479,10 +407,8 @@ ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
                return startstop;
        }
        /* For Write_sectors we need to stuff the first sector */
-       pBuf = task_map_rq(rq, &flags);
-       taskfile_output_data(drive, pBuf, SECTOR_WORDS);
+       taskfile_output_data(drive, rq->buffer + task_rq_offset(rq), SECTOR_WORDS);
        rq->current_nr_sectors--;
-       task_unmap_rq(rq, pBuf, &flags);
        return ide_started;
 }
 
@@ -498,14 +424,9 @@ ide_startstop_t task_out_intr (ide_drive_t *drive)
        ide_hwif_t *hwif        = HWIF(drive);
        struct request *rq      = HWGROUP(drive)->rq;
        char *pBuf              = NULL;
-       unsigned long flags;
        u8 stat;
 
        if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), DRIVE_READY, drive->bad_wstat)) {
-               DTF("%s: WRITE attempting to recover last " \
-                       "sector counter status=0x%02x\n",
-                       drive->name, stat);
-               rq->current_nr_sectors++;
                return DRIVER(drive)->error(drive, "task_out_intr", stat);
        }
        /*
@@ -517,11 +438,10 @@ ide_startstop_t task_out_intr (ide_drive_t *drive)
                        return ide_stopped;
        if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) {
                rq = HWGROUP(drive)->rq;
-               pBuf = task_map_rq(rq, &flags);
+               pBuf = rq->buffer + task_rq_offset(rq);
                DTF("write: %p, rq->current_nr_sectors: %d\n",
                        pBuf, (int) rq->current_nr_sectors);
                taskfile_output_data(drive, pBuf, SECTOR_WORDS);
-               task_unmap_rq(rq, pBuf, &flags);
                rq->errors = 0;
                rq->current_nr_sectors--;
        }
@@ -532,28 +452,11 @@ ide_startstop_t task_out_intr (ide_drive_t *drive)
 
 EXPORT_SYMBOL(task_out_intr);
 
-#undef ALTERNATE_STATE_DIAGRAM_MULTI_OUT
-
 ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq)
 {
-#ifdef ALTERNATE_STATE_DIAGRAM_MULTI_OUT
-       ide_hwif_t *hwif                = HWIF(drive);
-       char *pBuf                      = NULL;
-       unsigned int nsect = 0, msect   = drive->mult_count;
-        u8 stat;
-       unsigned long flags;
-#endif /* ALTERNATE_STATE_DIAGRAM_MULTI_OUT */
-
        ide_task_t *args = rq->special;
        ide_startstop_t startstop;
 
-#if 0
-       /*
-        * assign private copy for multi-write
-        */
-       memcpy(&HWGROUP(drive)->wrq, rq, sizeof(struct request));
-#endif
-
        if (ide_wait_stat(&startstop, drive, DATA_READY,
                        drive->bad_wstat, WAIT_DRQ)) {
                printk(KERN_ERR "%s: no DRQ after issuing %s\n",
@@ -561,31 +464,6 @@ ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq)
                        drive->addressing ? "MULTWRITE_EXT" : "MULTWRITE");
                return startstop;
        }
-#ifdef ALTERNATE_STATE_DIAGRAM_MULTI_OUT
-
-       do {
-               nsect = rq->current_nr_sectors;
-               if (nsect > msect)
-                       nsect = msect;
-               pBuf = task_map_rq(rq, &flags);
-               DTF("Pre-Multiwrite: %p, nsect: %d, msect: %d, " \
-                       "rq->current_nr_sectors: %ld\n",
-                       pBuf, nsect, msect, rq->current_nr_sectors);
-               msect -= nsect;
-               taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
-               task_unmap_rq(rq, pBuf, &flags);
-               rq->current_nr_sectors -= nsect;
-               if (!rq->current_nr_sectors) {
-                       if (!DRIVER(drive)->end_request(drive, 1, 0))
-                               if (!rq->bio) {
-                                       stat = hwif->INB(IDE_STATUS_REG);
-                                       return ide_stopped;
-                               }
-               }
-       } while (msect);
-       rq->errors = 0;
-       return ide_started;
-#else /* ! ALTERNATE_STATE_DIAGRAM_MULTI_OUT */
        if (!(drive_is_ready(drive))) {
                int i;
                for (i=0; i<100; i++) {
@@ -599,14 +477,10 @@ ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq)
         * move the DATA-TRANSFER T-Bar as BSY != 0. <andre@linux-ide.org>
         */
        return args->handler(drive);
-#endif /* ALTERNATE_STATE_DIAGRAM_MULTI_OUT */
 }
 
 EXPORT_SYMBOL(pre_task_mulout_intr);
 
-/*
- * FIXME before enabling in 2.4 ... DATA integrity issue upon error.
- */
 /*
  * Handler for command write multiple
  * Called directly from execute_drive_cmd for the first bunch of sectors,
@@ -618,49 +492,17 @@ ide_startstop_t task_mulout_intr (ide_drive_t *drive)
        u8 stat                         = hwif->INB(IDE_STATUS_REG);
        struct request *rq              = HWGROUP(drive)->rq;
        char *pBuf                      = NULL;
-       ide_startstop_t startstop       = ide_stopped;
        unsigned int msect              = drive->mult_count;
        unsigned int nsect;
-       unsigned long flags;
 
-       /*
-        * (ks/hs): Handle last IRQ on multi-sector transfer,
-        * occurs after all data was sent in this chunk
-        */
-       if (rq->current_nr_sectors == 0) {
+       if (!OK_STAT(stat, DATA_READY, BAD_R_STAT) || !rq->current_nr_sectors) {
                if (stat & (ERR_STAT|DRQ_STAT)) {
-                       if (!rq->bio) {
-                                rq->current_nr_sectors += drive->mult_count;
-                               /*
-                                * NOTE: could rewind beyond beginning :-/
-                                */
-                       } else {
-                               printk(KERN_ERR "%s: MULTI-WRITE assume all data " \
-                                       "transfered is bad status=0x%02x\n",
-                                       drive->name, stat);
-                       }
                        return DRIVER(drive)->error(drive, "task_mulout_intr", stat);
                }
-               if (!rq->bio)
+               /* Handle last IRQ, occurs after all data was sent. */
+               if (!rq->current_nr_sectors) {
                        DRIVER(drive)->end_request(drive, 1, 0);
-               return startstop;
-       }
-       /*
-        * DON'T be lazy code the above and below togather !!!
-        */
-       if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
-               if (stat & (ERR_STAT|DRQ_STAT)) {
-                       if (!rq->bio) {
-                               rq->current_nr_sectors += drive->mult_count;
-                               /*
-                                * NOTE: could rewind beyond beginning :-/
-                                */
-                       } else {
-                               printk("%s: MULTI-WRITE assume all data " \
-                                       "transfered is bad status=0x%02x\n",
-                                       drive->name, stat);
-                       }
-                       return DRIVER(drive)->error(drive, "task_mulout_intr", stat);
+                       return ide_stopped;
                }
                /* no data yet, so wait for another interrupt */
                if (HWGROUP(drive)->handler == NULL)
@@ -668,7 +510,6 @@ ide_startstop_t task_mulout_intr (ide_drive_t *drive)
                return ide_started;
        }
 
-#ifndef ALTERNATE_STATE_DIAGRAM_MULTI_OUT
        if (HWGROUP(drive)->handler != NULL) {
                unsigned long lflags;
                spin_lock_irqsave(&ide_lock, lflags);
@@ -676,26 +517,20 @@ ide_startstop_t task_mulout_intr (ide_drive_t *drive)
                del_timer(&HWGROUP(drive)->timer);
                spin_unlock_irqrestore(&ide_lock, lflags);
        }
-#endif /* ALTERNATE_STATE_DIAGRAM_MULTI_OUT */
 
        do {
                nsect = rq->current_nr_sectors;
                if (nsect > msect)
                        nsect = msect;
-               pBuf = task_map_rq(rq, &flags);
+               pBuf = rq->buffer + task_rq_offset(rq);
                DTF("Multiwrite: %p, nsect: %d, msect: %d, " \
                        "rq->current_nr_sectors: %ld\n",
                        pBuf, nsect, msect, rq->current_nr_sectors);
                msect -= nsect;
                taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
-               task_unmap_rq(rq, pBuf, &flags);
                rq->current_nr_sectors -= nsect;
-               /*
-                * FIXME :: We really can not legally get a new page/bh
-                * regardless, if this is the end of our segment.
-                * BH walking or segment can only be updated after we
-                * have a good  hwif->INB(IDE_STATUS_REG); return.
-                */
+
+               /* FIXME: check drive status */
                if (!rq->current_nr_sectors) {
                        if (!DRIVER(drive)->end_request(drive, 1, 0))
                                if (!rq->bio)
@@ -1011,6 +846,12 @@ int ide_diag_taskfile (ide_drive_t *drive, ide_task_t *args, unsigned long data_
                else
                        rq.nr_sectors = data_size / SECTOR_SIZE;
 
+               if (!rq.nr_sectors) {
+                       printk(KERN_ERR "%s: in/out command without data\n",
+                                       drive->name);
+                       return -EFAULT;
+               }
+
                rq.hard_nr_sectors = rq.nr_sectors;
                rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors;
        }
@@ -1495,9 +1336,6 @@ ide_startstop_t flagged_task_in_intr (ide_drive_t *drive)
        char *pBuf              = NULL;
        int retries             = 5;
 
-       if (rq->current_nr_sectors == 0) 
-               return DRIVER(drive)->error(drive, "flagged_task_in_intr (no data requested)", stat); 
-
        if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
                if (stat & ERR_STAT) {
                        return DRIVER(drive)->error(drive, "flagged_task_in_intr", stat);
@@ -1544,9 +1382,6 @@ ide_startstop_t flagged_task_mulin_intr (ide_drive_t *drive)
        int retries             = 5;
        unsigned int msect, nsect;
 
-       if (rq->current_nr_sectors == 0) 
-               return DRIVER(drive)->error(drive, "flagged_task_mulin_intr (no data requested)", stat); 
-
        msect = drive->mult_count;
        if (msect == 0) 
                return DRIVER(drive)->error(drive, "flagged_task_mulin_intr (multimode not set)", stat); 
@@ -1598,14 +1433,8 @@ ide_startstop_t flagged_task_mulin_intr (ide_drive_t *drive)
  */
 ide_startstop_t flagged_pre_task_out_intr (ide_drive_t *drive, struct request *rq)
 {
-       ide_hwif_t *hwif        = HWIF(drive);
-       u8 stat                 = hwif->INB(IDE_STATUS_REG);
        ide_startstop_t startstop;
 
-       if (!rq->current_nr_sectors) {
-               return DRIVER(drive)->error(drive, "flagged_pre_task_out_intr (write data not specified)", stat);
-       }
-
        if (ide_wait_stat(&startstop, drive, DATA_READY,
                        BAD_W_STAT, WAIT_DRQ)) {
                printk(KERN_ERR "%s: No DRQ bit after issuing write command.\n", drive->name);
@@ -1667,9 +1496,6 @@ ide_startstop_t flagged_pre_task_mulout_intr (ide_drive_t *drive, struct request
        ide_startstop_t startstop;
        unsigned int msect, nsect;
 
-       if (!rq->current_nr_sectors) 
-               return DRIVER(drive)->error(drive, "flagged_pre_task_mulout_intr (write data not specified)", stat);
-
        msect = drive->mult_count;
        if (msect == 0)
                return DRIVER(drive)->error(drive, "flagged_pre_task_mulout_intr (multimode not set)", stat);
index bc60dfb..2714aa1 100644 (file)
@@ -188,7 +188,6 @@ int noautodma = 1;
 #endif
 
 EXPORT_SYMBOL(noautodma);
-EXPORT_SYMBOL(ide_bus_type);
 
 /*
  * This is declared extern in ide.h, for access by other IDE modules:
@@ -554,8 +553,6 @@ control_region_busy:
        return -EBUSY;
 }
 
-EXPORT_SYMBOL(ide_hwif_request_regions);
-
 /**
  *     ide_hwif_release_regions - free IDE resources
  *
@@ -584,8 +581,6 @@ void ide_hwif_release_regions(ide_hwif_t *hwif)
                        release_region(hwif->io_ports[i], 1);
 }
 
-EXPORT_SYMBOL(ide_hwif_release_regions);
-
 /* restore hwif to a sane state */
 static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
 {
@@ -936,8 +931,6 @@ void ide_setup_ports (      hw_regs_t *hw,
  */
 }
 
-EXPORT_SYMBOL(ide_setup_ports);
-
 /*
  * Register an IDE interface, specifying exactly the registers etc
  * Set init=1 iff calling before probes have taken place.
@@ -998,7 +991,6 @@ EXPORT_SYMBOL(ide_register_hw);
  */
 
 DECLARE_MUTEX(ide_setting_sem);
-EXPORT_SYMBOL(ide_setting_sem);
 
 /**
  *     ide_add_setting -       add an ide setting option
@@ -1091,26 +1083,6 @@ static void __ide_remove_setting (ide_drive_t *drive, char *name)
        kfree(setting);
 }
 
-/**
- *     ide_remove_setting      -       remove an ide setting option
- *     @drive: drive to use
- *     @name: setting name
- *
- *     Removes the setting named from the device if it is present.
- *     The function takes the settings_lock to protect against 
- *     parallel changes. This function must not be called from IRQ
- *     context.
- */
-void ide_remove_setting (ide_drive_t *drive, char *name)
-{
-       down(&ide_setting_sem);
-       __ide_remove_setting(drive, name);
-       up(&ide_setting_sem);
-}
-
-EXPORT_SYMBOL(ide_remove_setting);
-
 /**
  *     ide_find_setting_by_ioctl       -       find a drive specific ioctl
  *     @drive: drive to scan
@@ -1292,8 +1264,6 @@ int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val)
        return 0;
 }
 
-EXPORT_SYMBOL(ide_write_setting);
-
 static int set_io_32bit(ide_drive_t *drive, int arg)
 {
        drive->io_32bit = arg;
@@ -1421,8 +1391,6 @@ abort:
        return 1;
 }
 
-EXPORT_SYMBOL(ide_replace_subdriver);
-
 int ata_attach(ide_drive_t *drive)
 {
        struct list_head *p;
@@ -1447,8 +1415,6 @@ int ata_attach(ide_drive_t *drive)
        return 1;
 }
 
-EXPORT_SYMBOL(ata_attach);
-
 static int generic_ide_suspend(struct device *dev, u32 state)
 {
        ide_drive_t *drive = dev->driver_data;
@@ -1806,7 +1772,7 @@ int __init ide_setup (char *s)
        if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
                const char *hd_words[] = {
                        "none", "noprobe", "nowerr", "cdrom", "serialize",
-                       "autotune", "noautotune", "minus8", "swapdata", "bswap",
+                       "autotune", "noautotune", "stroke", "swapdata", "bswap",
                        "minus11", "remap", "remap63", "scsi", NULL };
                unit = s[2] - 'a';
                hw   = unit / MAX_DRIVES;
@@ -1840,6 +1806,9 @@ int __init ide_setup (char *s)
                        case -7: /* "noautotune" */
                                drive->autotune = IDE_TUNE_NOAUTO;
                                goto done;
+                       case -8: /* stroke */
+                               drive->stroke = 1;
+                               goto done;
                        case -9: /* "swapdata" */
                        case -10: /* "bswap" */
                                drive->bswap = 1;
@@ -2034,6 +2003,7 @@ done:
        return 1;
 }
 
+extern void pnpide_init(void);
 extern void h8300_ide_init(void);
 
 /*
@@ -2100,12 +2070,9 @@ static void __init probe_for_hwifs (void)
                buddha_init();
        }
 #endif /* CONFIG_BLK_DEV_BUDDHA */
-#if defined(CONFIG_BLK_DEV_IDEPNP) && defined(CONFIG_PNP)
-       {
-               extern void pnpide_init(int enable);
-               pnpide_init(1);
-       }
-#endif /* CONFIG_BLK_DEV_IDEPNP */
+#ifdef CONFIG_BLK_DEV_IDEPNP
+       pnpide_init();
+#endif
 #ifdef CONFIG_H8300
        h8300_ide_init();
 #endif
@@ -2243,9 +2210,6 @@ int ide_unregister_subdriver (ide_drive_t *drive)
                up(&ide_setting_sem);
                return 1;
        }
-#if defined(CONFIG_BLK_DEV_IDEPNP) && defined(CONFIG_PNP) && defined(MODULE)
-       pnpide_init(0);
-#endif /* CONFIG_BLK_DEV_IDEPNP */
 #ifdef CONFIG_PROC_FS
        ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc);
        ide_remove_proc_entries(drive->proc, generic_subdriver_entries);
index 0addbae..73e833d 100644 (file)
@@ -756,12 +756,6 @@ static ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq,
 
        BUG_ON(rq->nr_sectors > 127);
 
-#ifdef DEBUG
-       printk(KERN_DEBUG "%s: %sing: LBAsect=%lu, sectors=%lu\n",
-                         drive->name, rq_data_dir(rq) ? "writ" : "read",
-                         block, rq->nr_sectors);
-#endif
-
 #ifndef CONFIG_IDE_TASKFILE_IO
        if (IDE_CONTROL_REG)
                hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
index 0c3b227..b032d24 100644 (file)
@@ -409,7 +409,7 @@ static int aec62xx_irq_timeout (ide_drive_t *drive)
        return 0;
 }
 
-static unsigned int __init init_chipset_aec62xx (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name)
 {
        int bus_speed = system_bus_clock();
 
@@ -435,7 +435,7 @@ static unsigned int __init init_chipset_aec62xx (struct pci_dev *dev, const char
        return dev->irq;
 }
 
-static void __init init_hwif_aec62xx (ide_hwif_t *hwif)
+static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
 {
        hwif->autodma = 0;
        hwif->tuneproc = &aec62xx_tune_drive;
@@ -468,7 +468,7 @@ static void __init init_hwif_aec62xx (ide_hwif_t *hwif)
        hwif->drives[1].autodma = hwif->autodma;
 }
 
-static void __init init_dma_aec62xx (ide_hwif_t *hwif, unsigned long dmabase)
+static void __devinit init_dma_aec62xx(ide_hwif_t *hwif, unsigned long dmabase)
 {
        struct pci_dev *dev     = hwif->pci_dev;
 
@@ -490,12 +490,12 @@ static void __init init_dma_aec62xx (ide_hwif_t *hwif, unsigned long dmabase)
        ide_setup_dma(hwif, dmabase, 8);
 }
 
-static void __init init_setup_aec62xx (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d)
 {
        ide_setup_pci_device(dev, d);
 }
 
-static void __init init_setup_aec6x80 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d)
 {
        unsigned long bar4reg = pci_resource_start(dev, 4);
 
index eb51201..2a34367 100644 (file)
@@ -38,7 +38,7 @@
 
 #include <asm/io.h>
 
-#include "alim15x3.h"
+#define DISPLAY_ALI_TIMINGS
 
 /*
  *     ALi devices are not plug in. Otherwise these static values would
@@ -853,6 +853,16 @@ static void __init init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
        ide_setup_dma(hwif, dmabase, 8);
 }
 
+static ide_pci_device_t ali15x3_chipset __devinitdata = {
+       .name           = "ALI15X3",
+       .init_chipset   = init_chipset_ali15x3,
+       .init_hwif      = init_hwif_ali15x3,
+       .init_dma       = init_dma_ali15x3,
+       .channels       = 2,
+       .autodma        = AUTODMA,
+       .bootable       = ON_BOARD,
+};
+
 /**
  *     alim15x3_init_one       -       set up an ALi15x3 IDE controller
  *     @dev: PCI device to set up
@@ -863,8 +873,8 @@ static void __init init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
  
 static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_pci_device_t *d = &ali15x3_chipsets[id->driver_data];
-       
+       ide_pci_device_t *d = &ali15x3_chipset;
+
        if(pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, NULL))
                printk(KERN_ERR "Warning: ATI Radeon IGP Northbridge is not yet fully tested.\n");
 
index 1f4d084..06b00a3 100644 (file)
@@ -586,7 +586,7 @@ static int cmd646_1_ide_dma_end (ide_drive_t *drive)
        return (dma_stat & 7) != 4;
 }
 
-static unsigned int __init init_chipset_cmd64x (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const char *name)
 {
        u32 class_rev = 0;
        u8 mrdmode = 0;
@@ -674,7 +674,7 @@ static unsigned int __init init_chipset_cmd64x (struct pci_dev *dev, const char
        return 0;
 }
 
-static unsigned int __init ata66_cmd64x (ide_hwif_t *hwif)
+static unsigned int __devinit ata66_cmd64x(ide_hwif_t *hwif)
 {
        u8 ata66 = 0, mask = (hwif->channel) ? 0x02 : 0x01;
 
@@ -689,7 +689,7 @@ static unsigned int __init ata66_cmd64x (ide_hwif_t *hwif)
        return (ata66 & mask) ? 1 : 0;
 }
 
-static void __init init_hwif_cmd64x (ide_hwif_t *hwif)
+static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
 {
        struct pci_dev *dev     = hwif->pci_dev;
        unsigned int class_rev;
index 588ac3a..8ddd2ce 100644 (file)
@@ -51,7 +51,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "cs5520.h"
+#define DISPLAY_CS5520_TIMINGS
 
 #if defined(DISPLAY_CS5520_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
@@ -251,7 +251,24 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
        hwif->drives[0].autodma = hwif->autodma;
        hwif->drives[1].autodma = hwif->autodma;
 }
-               
+
+#define DECLARE_CS_DEV(name_str)                               \
+       {                                                       \
+               .name           = name_str,                     \
+               .init_chipset   = init_chipset_cs5520,          \
+               .init_setup_dma = cs5520_init_setup_dma,        \
+               .init_hwif      = init_hwif_cs5520,             \
+               .channels       = 2,                            \
+               .autodma        = AUTODMA,                      \
+               .bootable       = ON_BOARD,                     \
+               .flags          = IDEPCI_FLAG_ISA_PORTS,        \
+       }
+
+static ide_pci_device_t cyrix_chipsets[] __devinitdata = {
+       /* 0 */ DECLARE_CS_DEV("Cyrix 5510"),
+       /* 1 */ DECLARE_CS_DEV("Cyrix 5520")
+};
+
 /*
  *     The 5510/5520 are a bit weird. They don't quite set up the way
  *     the PCI helper layer expects so we must do much of the set up 
index 19c97e8..b63e2d6 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "cs5530.h"
+#define DISPLAY_CS5530_TIMINGS
 
 #if defined(DISPLAY_CS5530_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
@@ -404,9 +404,19 @@ static void __init init_hwif_cs5530 (ide_hwif_t *hwif)
        hwif->drives[1].autodma = hwif->autodma;
 }
 
+static ide_pci_device_t cs5530_chipset __devinitdata = {
+       .name           = "CS5530",
+       .init_chipset   = init_chipset_cs5530,
+       .init_hwif      = init_hwif_cs5530,
+       .channels       = 2,
+       .autodma        = AUTODMA,
+       .bootable       = ON_BOARD,
+       .flags          = IDEPCI_FLAG_FORCE_MASTER,
+};
+
 static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_setup_pci_device(dev, &cs5530_chipsets[id->driver_data]);
+       ide_setup_pci_device(dev, &cs5530_chipset);
        return 0;
 }
 
index c33cd8e..f9c9ab6 100644 (file)
@@ -235,7 +235,7 @@ no_dma_set:
  */
 #define        HPT34X_PCI_INIT_REG             0x80
 
-static unsigned int __init init_chipset_hpt34x (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const char *name)
 {
        int i = 0;
        unsigned long hpt34xIoBase = pci_resource_start(dev, 4);
@@ -289,7 +289,7 @@ static unsigned int __init init_chipset_hpt34x (struct pci_dev *dev, const char
        return dev->irq;
 }
 
-static void __init init_hwif_hpt34x (ide_hwif_t *hwif)
+static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
 {
        u16 pcicmd = 0;
 
index 5ca4a58..77bc208 100644 (file)
@@ -795,7 +795,7 @@ static int hpt370_busproc(ide_drive_t * drive, int state)
        return 0;
 }
 
-static int __init init_hpt37x(struct pci_dev *dev)
+static int __devinit init_hpt37x(struct pci_dev *dev)
 {
        int adjust, i;
        u16 freq;
@@ -923,7 +923,7 @@ init_hpt37X_done:
        return 0;
 }
 
-static int __init init_hpt366 (struct pci_dev *dev)
+static int __devinit init_hpt366(struct pci_dev *dev)
 {
        u32 reg1        = 0;
        u8 drive_fast   = 0;
@@ -958,7 +958,7 @@ static int __init init_hpt366 (struct pci_dev *dev)
        return 0;
 }
 
-static unsigned int __init init_chipset_hpt366 (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const char *name)
 {
        int ret = 0;
        u8 test = 0;
@@ -1004,7 +1004,7 @@ static unsigned int __init init_chipset_hpt366 (struct pci_dev *dev, const char
        return dev->irq;
 }
 
-static void __init init_hwif_hpt366 (ide_hwif_t *hwif)
+static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
 {
        struct pci_dev *dev             = hwif->pci_dev;
        u8 ata66 = 0, regmask           = (hwif->channel) ? 0x01 : 0x02;
@@ -1116,7 +1116,7 @@ static void __init init_hwif_hpt366 (ide_hwif_t *hwif)
        hwif->drives[1].autodma = hwif->autodma;
 }
 
-static void __init init_dma_hpt366 (ide_hwif_t *hwif, unsigned long dmabase)
+static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
 {
        u8 masterdma    = 0, slavedma = 0;
        u8 dma_new      = 0, dma_old = 0;
@@ -1151,7 +1151,7 @@ static void __init init_dma_hpt366 (ide_hwif_t *hwif, unsigned long dmabase)
        ide_setup_dma(hwif, dmabase, 8);
 }
 
-static void __init init_setup_hpt374 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d)
 {
        struct pci_dev *findev = NULL;
 
@@ -1176,12 +1176,12 @@ static void __init init_setup_hpt374 (struct pci_dev *dev, ide_pci_device_t *d)
        ide_setup_pci_device(dev, d);
 }
 
-static void __init init_setup_hpt37x (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_hpt37x(struct pci_dev *dev, ide_pci_device_t *d)
 {
        ide_setup_pci_device(dev, d);
 }
 
-static void __init init_setup_hpt366 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
 {
        struct pci_dev *findev = NULL;
        u8 pin1 = 0, pin2 = 0;
index 1809edd..a5b6e7e 100644 (file)
@@ -25,8 +25,6 @@
 
 #include <asm/io.h>
 
-#include "ns87415.h"
-
 static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 };
 
 /*
@@ -217,9 +215,17 @@ static void __init init_hwif_ns87415 (ide_hwif_t *hwif)
        hwif->drives[1].autodma = hwif->autodma;
 }
 
+static ide_pci_device_t ns87415_chipset __devinitdata = {
+       .name           = "NS87415",
+       .init_hwif      = init_hwif_ns87415,
+       .channels       = 2,
+       .autodma        = AUTODMA,
+       .bootable       = ON_BOARD,
+};
+
 static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_setup_pci_device(dev, &ns87415_chipsets[id->driver_data]);
+       ide_setup_pci_device(dev, &ns87415_chipset);
        return 0;
 }
 
index fbc0bd8..f493b29 100644 (file)
@@ -404,7 +404,7 @@ static void __devinit apple_kiwi_init(struct pci_dev *pdev)
 }
 #endif /* CONFIG_PPC_PMAC */
 
-static unsigned int __init init_chipset_pdcnew (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const char *name)
 {
        if (dev->resource[PCI_ROM_RESOURCE].start) {
                pci_write_config_dword(dev, PCI_ROM_ADDRESS,
@@ -429,7 +429,7 @@ static unsigned int __init init_chipset_pdcnew (struct pci_dev *dev, const char
        return dev->irq;
 }
 
-static void __init init_hwif_pdc202new (ide_hwif_t *hwif)
+static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
 {
        hwif->autodma = 0;
 
@@ -457,12 +457,12 @@ static void __init init_hwif_pdc202new (ide_hwif_t *hwif)
 #endif /* PDC202_DEBUG_CABLE */
 }
 
-static void __init init_setup_pdcnew (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d)
 {
        ide_setup_pci_device(dev, d);
 }
 
-static void __init init_setup_pdc20270 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *d)
 {
        struct pci_dev *findev = NULL;
 
@@ -488,7 +488,7 @@ static void __init init_setup_pdc20270 (struct pci_dev *dev, ide_pci_device_t *d
        ide_setup_pci_device(dev, d);
 }
 
-static void __init init_setup_pdc20276 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d)
 {
        if ((dev->bus->self) &&
            (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) &&
index 99fbe04..cf6082a 100644 (file)
@@ -670,7 +670,7 @@ static int pdc202xx_tristate (ide_drive_t * drive, int state)
        return 0;
 }
 
-static unsigned int __init init_chipset_pdc202xx (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, const char *name)
 {
        if (dev->resource[PCI_ROM_RESOURCE].start) {
                pci_write_config_dword(dev, PCI_ROM_ADDRESS,
@@ -715,7 +715,7 @@ static unsigned int __init init_chipset_pdc202xx (struct pci_dev *dev, const cha
        return dev->irq;
 }
 
-static void __init init_hwif_pdc202xx (ide_hwif_t *hwif)
+static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
 {
        hwif->autodma = 0;
        hwif->tuneproc  = &config_chipset_for_pio;
@@ -755,7 +755,7 @@ static void __init init_hwif_pdc202xx (ide_hwif_t *hwif)
 #endif /* PDC202_DEBUG_CABLE */        
 }
 
-static void __init init_dma_pdc202xx (ide_hwif_t *hwif, unsigned long dmabase)
+static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
 {
        u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0;
 
@@ -807,7 +807,7 @@ static void __init init_dma_pdc202xx (ide_hwif_t *hwif, unsigned long dmabase)
        ide_setup_dma(hwif, dmabase, 8);
 }
 
-static void __init init_setup_pdc202ata4 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_pdc202ata4(struct pci_dev *dev, ide_pci_device_t *d)
 {
        if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) {
                u8 irq = 0, irq2 = 0;
@@ -837,7 +837,7 @@ static void __init init_setup_pdc202ata4 (struct pci_dev *dev, ide_pci_device_t
        ide_setup_pci_device(dev, d);
 }
 
-static void __init init_setup_pdc20265 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_pdc20265(struct pci_dev *dev, ide_pci_device_t *d)
 {
        if ((dev->bus->self) &&
            (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) &&
@@ -866,7 +866,7 @@ static void __init init_setup_pdc20265 (struct pci_dev *dev, ide_pci_device_t *d
        ide_setup_pci_device(dev, d);
 }
 
-static void __init init_setup_pdc202xx (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_pdc202xx(struct pci_dev *dev, ide_pci_device_t *d)
 {
        ide_setup_pci_device(dev, d);
 }
index 3d21a5b..fec700b 100644 (file)
@@ -49,9 +49,9 @@
  * pci_read_config_word(HWIF(drive)->pci_dev, 0x40, &reg40);
  * pci_read_config_word(HWIF(drive)->pci_dev, 0x42, &reg42);
  * pci_read_config_word(HWIF(drive)->pci_dev, 0x44, &reg44);
- * pci_read_config_word(HWIF(drive)->pci_dev, 0x48, &reg48);
+ * pci_read_config_byte(HWIF(drive)->pci_dev, 0x48, &reg48);
  * pci_read_config_word(HWIF(drive)->pci_dev, 0x4a, &reg4a);
- * pci_read_config_word(HWIF(drive)->pci_dev, 0x54, &reg54);
+ * pci_read_config_byte(HWIF(drive)->pci_dev, 0x54, &reg54);
  *
  * Documentation
  *     Publically available from Intel web site. Errata documentation
@@ -432,15 +432,14 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
        int w_flag              = 0x10 << drive->dn;
        int u_speed             = 0;
        int                     sitre;
-       u16                     reg4042, reg44, reg48, reg4a, reg54;
-       u8                      reg55;
+       u16                     reg4042, reg4a;
+       u8                      reg48, reg54, reg55;
 
        pci_read_config_word(dev, maslave, &reg4042);
        sitre = (reg4042 & 0x4000) ? 1 : 0;
-       pci_read_config_word(dev, 0x44, &reg44);
-       pci_read_config_word(dev, 0x48, &reg48);
+       pci_read_config_byte(dev, 0x48, &reg48);
        pci_read_config_word(dev, 0x4a, &reg4a);
-       pci_read_config_word(dev, 0x54, &reg54);
+       pci_read_config_byte(dev, 0x54, &reg54);
        pci_read_config_byte(dev, 0x55, &reg55);
 
        switch(speed) {
@@ -462,30 +461,26 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
 
        if (speed >= XFER_UDMA_0) {
                if (!(reg48 & u_flag))
-                       pci_write_config_word(dev, 0x48, reg48|u_flag);
+                       pci_write_config_byte(dev, 0x48, reg48 | u_flag);
                if (speed == XFER_UDMA_5) {
                        pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
                } else {
                        pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
                }
-               if (!(reg4a & u_speed)) {
-                       pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
-                       pci_write_config_word(dev, 0x4a, reg4a|u_speed);
-               }
+               if ((reg4a & a_speed) != u_speed)
+                       pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
                if (speed > XFER_UDMA_2) {
-                       if (!(reg54 & v_flag)) {
-                               pci_write_config_word(dev, 0x54, reg54|v_flag);
-                       }
-               } else {
-                       pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
-               }
+                       if (!(reg54 & v_flag))
+                               pci_write_config_byte(dev, 0x54, reg54 | v_flag);
+               } else
+                       pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
        } else {
                if (reg48 & u_flag)
-                       pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
+                       pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
                if (reg4a & a_speed)
                        pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
                if (reg54 & v_flag)
-                       pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
+                       pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
                if (reg55 & w_flag)
                        pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
        }
@@ -655,8 +650,8 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char
  *     Set up the ide_hwif_t for the PIIX interface according to the
  *     capabilities of the hardware.
  */
-static void __init init_hwif_piix (ide_hwif_t *hwif)
+
+static void __devinit init_hwif_piix(ide_hwif_t *hwif)
 {
        u8 reg54h = 0, reg55h = 0, ata66 = 0;
        u8 mask = hwif->channel ? 0xc0 : 0x30;
@@ -725,8 +720,8 @@ static void __init init_hwif_piix (ide_hwif_t *hwif)
  *     Enable the xp fixup for the PIIX controller and then perform
  *     a standard ide PCI setup
  */
-static void __init init_setup_piix (struct pci_dev *dev, ide_pci_device_t *d)
+
+static void __devinit init_setup_piix(struct pci_dev *dev, ide_pci_device_t *d)
 {
        ide_setup_pci_device(dev, d);
 }
@@ -754,8 +749,8 @@ static int __devinit piix_init_one(struct pci_dev *dev, const struct pci_device_
  *     Check for the present of 450NX errata #19 and errata #25. If
  *     they are found, disable use of DMA IDE
  */
-static void __init piix_check_450nx(void)
+
+static void __devinit piix_check_450nx(void)
 {
        struct pci_dev *pdev = NULL;
        u16 cfg;
index 7866906..3405e6a 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <asm/io.h>
 
-#include "rz1000.h"
-
 static void __init init_hwif_rz1000 (ide_hwif_t *hwif)
 {
        u16 reg;
@@ -54,15 +52,23 @@ static void __init init_hwif_rz1000 (ide_hwif_t *hwif)
        }
 }
 
+static ide_pci_device_t rz1000_chipset __devinitdata = {
+       .name           = "RZ100x",
+       .init_hwif      = init_hwif_rz1000,
+       .channels       = 2,
+       .autodma        = NODMA,
+       .bootable       = ON_BOARD,
+};
+
 static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_setup_pci_device(dev, &rz1000_chipsets[id->driver_data]);
+       ide_setup_pci_device(dev, &rz1000_chipset);
        return 0;
 }
 
 static struct pci_device_id rz1000_pci_tbl[] = {
        { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+       { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, rz1000_pci_tbl);
index 58d1e58..902408d 100644 (file)
@@ -29,8 +29,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "sc1200.h"
-
 #define SC1200_REV_A   0x00
 #define SC1200_REV_B1  0x01
 #define SC1200_REV_B3  0x02
@@ -545,9 +543,18 @@ static void __init init_hwif_sc1200 (ide_hwif_t *hwif)
         hwif->drives[1].autodma = hwif->autodma;
 }
 
+static ide_pci_device_t sc1200_chipset __devinitdata = {
+       .name           = "SC1200",
+       .init_chipset   = init_chipset_sc1200,
+       .init_hwif      = init_hwif_sc1200,
+       .channels       = 2,
+       .autodma        = AUTODMA,
+       .bootable       = ON_BOARD,
+};
+
 static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_setup_pci_device(dev, &sc1200_chipsets[id->driver_data]);
+       ide_setup_pci_device(dev, &sc1200_chipset);
        return 0;
 }
 
index 5b2ab76..5a7483e 100644 (file)
@@ -31,7 +31,8 @@
 
 #include <asm/io.h>
 
-#include "siimage.h"
+#undef SIIMAGE_VIRTUAL_DMAPIO
+#undef SIIMAGE_LARGE_DMA
 
 /**
  *     pdev_is_sata            -       check if device is SATA
@@ -812,7 +813,7 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
  *     to 133MHz clocking if the system isn't already set up to do it.
  */
 
-static unsigned int __init init_chipset_siimage (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const char *name)
 {
        u32 class_rev   = 0;
        u8 tmpbyte      = 0;
@@ -877,8 +878,8 @@ static unsigned int __init init_chipset_siimage (struct pci_dev *dev, const char
  *     The hardware supports buffered taskfiles and also some rather nice
  *     extended PRD tables. Unfortunately right now we don't.
  */
-static void __init init_mmio_iops_siimage (ide_hwif_t *hwif)
+
+static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
 {
        struct pci_dev *dev     = hwif->pci_dev;
        void *addr              = pci_get_drvdata(dev);
@@ -996,8 +997,8 @@ static int is_dev_seagate_sata(ide_drive_t *drive)
  *     look in we get for setting up the hwif so that we
  *     can get the iops right before using them.
  */
-static void __init init_iops_siimage (ide_hwif_t *hwif)
+
+static void __devinit init_iops_siimage(ide_hwif_t *hwif)
 {
        struct pci_dev *dev     = hwif->pci_dev;
        u32 class_rev           = 0;
@@ -1023,8 +1024,8 @@ static void __init init_iops_siimage (ide_hwif_t *hwif)
  *     Check for the presence of an ATA66 capable cable on the
  *     interface.
  */
-static unsigned int __init ata66_siimage (ide_hwif_t *hwif)
+
+static unsigned int __devinit ata66_siimage(ide_hwif_t *hwif)
 {
        unsigned long addr = siimage_selreg(hwif, 0);
        if (pci_get_drvdata(hwif->pci_dev) == NULL) {
@@ -1044,8 +1045,8 @@ static unsigned int __init ata66_siimage (ide_hwif_t *hwif)
  *     requires several custom handlers so we override the default
  *     ide DMA handlers appropriately
  */
-static void __init init_hwif_siimage (ide_hwif_t *hwif)
+
+static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
 {
        hwif->autodma = 0;
        
@@ -1092,6 +1093,23 @@ static void __init init_hwif_siimage (ide_hwif_t *hwif)
        hwif->drives[1].autodma = hwif->autodma;
 }
 
+#define DECLARE_SII_DEV(name_str)                      \
+       {                                               \
+               .name           = name_str,             \
+               .init_chipset   = init_chipset_siimage, \
+               .init_iops      = init_iops_siimage,    \
+               .init_hwif      = init_hwif_siimage,    \
+               .channels       = 2,                    \
+               .autodma        = AUTODMA,              \
+               .bootable       = ON_BOARD,             \
+       }
+
+static ide_pci_device_t siimage_chipsets[] __devinitdata = {
+       /* 0 */ DECLARE_SII_DEV("SiI680"),
+       /* 1 */ DECLARE_SII_DEV("SiI3112 Serial ATA"),
+       /* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA")
+};
+
 /**
  *     siimage_init_one        -       pci layer discovery entry
  *     @dev: PCI device
index 6254eab..d06b1fd 100644 (file)
@@ -63,7 +63,8 @@
 #include <asm/irq.h>
 
 #include "ide-timing.h"
-#include "sis5513.h"
+
+#define DISPLAY_SIS_TIMINGS
 
 /* registers layout and init values are chipset family dependant */
 
@@ -944,9 +945,19 @@ static void __init init_hwif_sis5513 (ide_hwif_t *hwif)
        return;
 }
 
+static ide_pci_device_t sis5513_chipset __devinitdata = {
+       .name           = "SIS5513",
+       .init_chipset   = init_chipset_sis5513,
+       .init_hwif      = init_hwif_sis5513,
+       .channels       = 2,
+       .autodma        = NOAUTODMA,
+       .enablebits     = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
+       .bootable       = ON_BOARD,
+};
+
 static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_setup_pci_device(dev, &sis5513_chipsets[id->driver_data]);
+       ide_setup_pci_device(dev, &sis5513_chipset);
        return 0;
 }
 
index 4706ebf..38bd807 100644 (file)
@@ -29,8 +29,6 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 
-#include "sl82c105.h"
-
 #undef DEBUG
 
 #ifdef DEBUG
@@ -481,9 +479,20 @@ static void __init init_hwif_sl82c105(ide_hwif_t *hwif)
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 }
 
+static ide_pci_device_t sl82c105_chipset __devinitdata = {
+       .name           = "W82C105",
+       .init_chipset   = init_chipset_sl82c105,
+       .init_hwif      = init_hwif_sl82c105,
+       .init_dma       = init_dma_sl82c105,
+       .channels       = 2,
+       .autodma        = NOAUTODMA,
+       .enablebits     = {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
+       .bootable       = ON_BOARD,
+};
+
 static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_setup_pci_device(dev, &sl82c105_chipsets[id->driver_data]);
+       ide_setup_pci_device(dev, &sl82c105_chipset);
        return 0;
 }
 
index 7842242..1a0183d 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <asm/io.h>
 
-#include "slc90e66.h"
+#define DISPLAY_SLC90E66_TIMINGS
 
 #if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
@@ -364,9 +364,19 @@ static void __init init_hwif_slc90e66 (ide_hwif_t *hwif)
 #endif /* !CONFIG_BLK_DEV_IDEDMA */
 }
 
+static ide_pci_device_t slc90e66_chipset __devinitdata = {
+       .name           = "SLC90E66",
+       .init_chipset   = init_chipset_slc90e66,
+       .init_hwif      = init_hwif_slc90e66,
+       .channels       = 2,
+       .autodma        = AUTODMA,
+       .enablebits     = {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+       .bootable       = ON_BOARD,
+};
+
 static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_setup_pci_device(dev, &slc90e66_chipsets[id->driver_data]);
+       ide_setup_pci_device(dev, &slc90e66_chipset);
        return 0;
 }
 
index fc61865..52e088e 100644 (file)
@@ -41,8 +41,6 @@
 #include <linux/ide.h>
 #include <linux/init.h>
 
-#include "triflex.h"
-
 static struct pci_dev *triflex_dev;
 
 #ifdef CONFIG_PROC_FS
@@ -217,15 +215,32 @@ static unsigned int __init init_chipset_triflex(struct pci_dev *dev,
        return 0;       
 }
 
+static ide_pci_device_t triflex_device __devinitdata = {
+       .name           = "TRIFLEX",
+       .init_chipset   = init_chipset_triflex,
+       .init_hwif      = init_hwif_triflex,
+       .channels       = 2,
+       .autodma        = AUTODMA,
+       .enablebits     = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}},
+       .bootable       = ON_BOARD,
+};
+
 static int __devinit triflex_init_one(struct pci_dev *dev, 
                const struct pci_device_id *id)
 {
-       ide_setup_pci_device(dev, &triflex_devices[id->driver_data]);
+       ide_setup_pci_device(dev, &triflex_device);
        triflex_dev = dev;
 
        return 0;
 }
 
+static struct pci_device_id triflex_pci_tbl[] = {
+       { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { 0, },
+};
+MODULE_DEVICE_TABLE(pci, triflex_pci_tbl);
+
 static struct pci_driver driver = {
        .name           = "TRIFLEX IDE",
        .id_table       = triflex_pci_tbl,
index c074089..d482d83 100644 (file)
 
 #include <asm/io.h>
 
-#include "trm290.h"
-
 static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
 {
        ide_hwif_t *hwif = HWIF(drive);
@@ -302,7 +300,7 @@ static int trm290_ide_dma_test_irq (ide_drive_t *drive)
 /*
  * Invoked from ide-dma.c at boot time.
  */
-void __init init_hwif_trm290 (ide_hwif_t *hwif)
+void __devinit init_hwif_trm290(ide_hwif_t *hwif)
 {
        unsigned int cfgbase = 0;
        unsigned long flags;
@@ -395,9 +393,17 @@ void __init init_hwif_trm290 (ide_hwif_t *hwif)
 #endif
 }
 
+static ide_pci_device_t trm290_chipset __devinitdata = {
+       .name           = "TRM290",
+       .init_hwif      = init_hwif_trm290,
+       .channels       = 2,
+       .autodma        = NOAUTODMA,
+       .bootable       = ON_BOARD,
+};
+
 static int __devinit trm290_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_setup_pci_device(dev, &trm290_chipsets[id->driver_data]);
+       ide_setup_pci_device(dev, &trm290_chipset);
        return 0;
 }
 
index 47c241d..9aa5633 100644 (file)
@@ -37,7 +37,8 @@
 #include <asm/io.h>
 
 #include "ide-timing.h"
-#include "via82cxxx.h"
+
+#define DISPLAY_VIA_TIMINGS
 
 #define VIA_IDE_ENABLE         0x40
 #define VIA_IDE_CONFIG         0x41
@@ -607,9 +608,19 @@ static void __init init_hwif_via82cxxx(ide_hwif_t *hwif)
        hwif->drives[1].autodma = hwif->autodma;
 }
 
+static ide_pci_device_t via82cxxx_chipset __devinitdata = {
+       .name           = "VP_IDE",
+       .init_chipset   = init_chipset_via82cxxx,
+       .init_hwif      = init_hwif_via82cxxx,
+       .channels       = 2,
+       .autodma        = NOAUTODMA,
+       .enablebits     = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+       .bootable       = ON_BOARD,
+};
+
 static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]);
+       ide_setup_pci_device(dev, &via82cxxx_chipset);
        return 0;
 }
 
index 301011c..931464b 100644 (file)
@@ -1061,6 +1061,10 @@ void csr1212_fill_cache(struct csr1212_csr_rom_cache *cache)
                }
 
                nkv = kv->next;
+               if (kv->prev)
+                       kv->prev->next = NULL;
+               if (kv->next)
+                       kv->next->prev = NULL;
                kv->prev = NULL;
                kv->next = NULL;
        }
@@ -1134,7 +1138,7 @@ int csr1212_generate_csr_image(struct csr1212_csr *csr)
                        /* Make sure the Extended ROM leaf is a multiple of
                         * max_rom in size. */
                        leaf_size = (cache->len + (csr->max_rom - 1)) &
-                               (csr->max_rom - 1);
+                               ~(csr->max_rom - 1);
 
                        /* Zero out the unused ROM region */
                        memset(cache->data + bytes_to_quads(cache->len), 0x00,
index e7f1d30..e673426 100644 (file)
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/vmalloc.h>
+#include <asm/pgalloc.h>
 
-#define CSR1212_MALLOC(size)           kmalloc((size), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL)
-#define CSR1212_FREE(ptr)              kfree(ptr)
+#define CSR1212_MALLOC(size)           vmalloc((size))
+#define CSR1212_FREE(ptr)              vfree(ptr)
 #define CSR1212_BE16_TO_CPU(quad)      be16_to_cpu(quad)
 #define CSR1212_CPU_TO_BE16(quad)      cpu_to_be16(quad)
 #define CSR1212_BE32_TO_CPU(quad)      be32_to_cpu(quad)
index d99ac5d..95ccc69 100644 (file)
@@ -89,7 +89,7 @@
 #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
 
 static char version[] __devinitdata =
-       "$Rev: 1198 $ Ben Collins <bcollins@debian.org>";
+       "$Rev: 1224 $ Ben Collins <bcollins@debian.org>";
 
 struct fragment_info {
        struct list_head list;
@@ -191,7 +191,7 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev);
 static void ether1394_iso(struct hpsb_iso *iso);
 
 static int ether1394_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
-static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr);
+static int ether1394_ethtool_ioctl(struct net_device *dev, void __user *useraddr);
 
 static int ether1394_write(struct hpsb_host *host, int srcid, int destid,
                           quadlet_t *data, u64 addr, size_t len, u16 flags);
@@ -431,9 +431,12 @@ static int eth1394_update(struct unit_directory *ud)
                if (!node)
                        return -ENOMEM;
 
-
                node_info = kmalloc(sizeof(struct eth1394_node_info),
                                    in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+               if (!node_info) {
+                       kfree(node);
+                       return -ENOMEM;
+                }
 
                spin_lock_init(&node_info->pdg.lock);
                INIT_LIST_HEAD(&node_info->pdg.list);
@@ -1770,7 +1773,7 @@ static int ether1394_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd
 {
        switch(cmd) {
                case SIOCETHTOOL:
-                       return ether1394_ethtool_ioctl(dev, (void *) ifr->ifr_data);
+                       return ether1394_ethtool_ioctl(dev, ifr->ifr_data);
 
                case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
                case SIOCGMIIREG:               /* Read MII PHY register. */
@@ -1782,18 +1785,18 @@ static int ether1394_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd
        return 0;
 }
 
-static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int ether1394_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
        u32 ethcmd;
 
-       if (get_user(ethcmd, (u32 *)useraddr))
+       if (get_user(ethcmd, (u32 __user *)useraddr))
                return -EFAULT;
 
        switch (ethcmd) {
                case ETHTOOL_GDRVINFO: {
                        struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
                        strcpy (info.driver, driver_name);
-                       strcpy (info.version, "$Rev: 1198 $");
+                       strcpy (info.version, "$Rev: 1224 $");
                        /* FIXME XXX provide sane businfo */
                        strcpy (info.bus_info, "ieee1394");
                        if (copy_to_user (useraddr, &info, sizeof (info)))
index 67fc9f7..50c403c 100644 (file)
@@ -383,7 +383,7 @@ u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
                a2sa = a2->start & align_mask;
                a2ea = (a2->end + alignment -1) & align_mask;
 
-               if ((a2sa - a1ea >= size) && (a2sa - start >= size) && (end - a1ea >= size)) {
+               if ((a2sa - a1ea >= size) && (a2sa - start >= size) && (a2sa > start)) {
                        as->start = max(start, a1ea);
                        as->end = as->start + size;
                        list_add(&as->host_list, entry);
index 47a6141..c502c6e 100644 (file)
@@ -30,7 +30,7 @@
 #include "config_roms.h"
 
 
-static void delayed_reset_bus(unsigned long __reset_info)
+static void delayed_reset_bus(void * __reset_info)
 {
        struct hpsb_host *host = (struct hpsb_host*)__reset_info;
        int generation = host->csr.generation + 1;
@@ -129,9 +129,6 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
        skb_queue_head_init(&h->pending_packet_queue);
        INIT_LIST_HEAD(&h->addr_space);
 
-       init_timer(&h->delayed_reset);
-       h->delayed_reset.function = delayed_reset_bus;
-       h->delayed_reset.data = (unsigned long)h;
        for (i = 2; i < 16; i++)
                h->csr.gen_timestamp[i] = jiffies - 60 * HZ;
 
@@ -140,6 +137,8 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
 
        atomic_set(&h->generation, 0);
 
+       INIT_WORK(&h->delayed_reset, delayed_reset_bus, h);
+       
        init_timer(&h->timeout);
        h->timeout.data = (unsigned long) h;
        h->timeout.function = abort_timedouts;
@@ -188,7 +187,8 @@ void hpsb_remove_host(struct hpsb_host *host)
 {
         host->is_shutdown = 1;
 
-       del_timer_sync(&host->delayed_reset);
+       cancel_delayed_work(&host->delayed_reset);
+       flush_scheduled_work();
 
         host->driver = &dummy_driver;
 
@@ -202,7 +202,7 @@ void hpsb_remove_host(struct hpsb_host *host)
 
 int hpsb_update_config_rom_image(struct hpsb_host *host)
 {
-       unsigned long reset_time;
+       unsigned long reset_delay;
        int next_gen = host->csr.generation + 1;
 
        if (!host->update_config_rom)
@@ -213,21 +213,21 @@ int hpsb_update_config_rom_image(struct hpsb_host *host)
 
        /* Stop the delayed interrupt, we're about to change the config rom and
         * it would be a waste to do a bus reset twice. */
-       del_timer_sync(&host->delayed_reset);
+       cancel_delayed_work(&host->delayed_reset);
 
        /* IEEE 1394a-2000 prohibits using the same generation number
         * twice in a 60 second period. */
        if (jiffies - host->csr.gen_timestamp[next_gen] < 60 * HZ)
                /* Wait 60 seconds from the last time this generation number was
                 * used. */
-               reset_time = (60 * HZ) + host->csr.gen_timestamp[next_gen];
+               reset_delay = (60 * HZ) + host->csr.gen_timestamp[next_gen] - jiffies;
        else
                /* Wait 1 second in case some other code wants to change the
                 * Config ROM in the near future. */
-               reset_time = jiffies + HZ;
+               reset_delay = HZ;
 
-       /* This will add the timer as well as modify it */
-       mod_timer(&host->delayed_reset, reset_time);
+       PREPARE_WORK(&host->delayed_reset, delayed_reset_bus, host);
+       schedule_delayed_work(&host->delayed_reset, reset_delay);
 
        return 0;
 }
index 000e44c..739e768 100644 (file)
@@ -66,7 +66,7 @@ struct hpsb_host {
        struct class_device class_dev;
 
        int update_config_rom;
-       struct timer_list delayed_reset;
+       struct work_struct delayed_reset;
 
        unsigned int config_roms;
 
index c6fa4c8..9a3c586 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/bitops.h>
 #include <linux/kdev_t.h>
 #include <linux/skbuff.h>
+#include <linux/suspend.h>
 
 #include <asm/byteorder.h>
 #include <asm/semaphore.h>
@@ -1033,6 +1034,11 @@ static int hpsbpkt_thread(void *__hi)
                if (khpsbpkt_kill)
                        break;
 
+               if (current->flags & PF_FREEZE) {
+                       refrigerator(0);
+                       continue;
+               }
+
                while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) {
                        packet = (struct hpsb_packet *)skb->data;
 
index 9bfd293..c912be4 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/moduleparam.h>
+#include <linux/suspend.h>
 #include <asm/atomic.h>
 
 #include "ieee1394_types.h"
@@ -1474,11 +1475,20 @@ static int nodemgr_host_thread(void *__hi)
 
        /* Sit and wait for a signal to probe the nodes on the bus. This
         * happens when we get a bus reset. */
-       while (!down_interruptible(&hi->reset_sem) &&
-              !down_interruptible(&nodemgr_serialize)) {
+       while (1) {
                unsigned int generation = 0;
                int i;
 
+               if (down_interruptible(&hi->reset_sem) ||
+                   down_interruptible(&nodemgr_serialize)) {
+                       if (current->flags & PF_FREEZE) {
+                               refrigerator(0);
+                               continue;
+                       }
+                       printk("NodeMgr: received unexpected signal?!\n" );
+                       break;
+               }
+
                if (hi->kill_me)
                        break;
 
index 88438b5..afcf7f8 100644 (file)
@@ -162,7 +162,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
 
 static char version[] __devinitdata =
-       "$Rev: 1203 $ Ben Collins <bcollins@debian.org>";
+       "$Rev: 1223 $ Ben Collins <bcollins@debian.org>";
 
 /* Module Parameters */
 static int phys_dma = 1;
@@ -516,6 +516,12 @@ static void ohci_initialize(struct ti_ohci *ohci)
        ohci->max_packet_size =
                1<<(((reg_read(ohci, OHCI1394_BusOptions)>>12)&0xf)+1);
 
+       if (ohci->max_packet_size < 512) {
+               HPSB_ERR("warning: Invalid max packet size of %d, setting to 512",
+                            ohci->max_packet_size);
+               ohci->max_packet_size = 512;
+       }
+               
        /* Don't accept phy packets into AR request context */
        reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400);
 
index 624cca5..47de79f 100644 (file)
@@ -65,7 +65,7 @@
 #include <asm/scatterlist.h>
 
 #include "../scsi/scsi.h"
-#include "../scsi/hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "csr1212.h"
 #include "ieee1394.h"
@@ -78,7 +78,7 @@
 #include "sbp2.h"
 
 static char version[] __devinitdata =
-       "$Rev: 1205 $ Ben Collins <bcollins@debian.org>";
+       "$Rev: 1219 $ Ben Collins <bcollins@debian.org>";
 
 /*
  * Module load parameter definitions
index a9b92c1..7a757fc 100644 (file)
@@ -864,6 +864,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
                        return -EFAULT;
 
                d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
+               if (d == NULL) return -EFAULT;
 
                if ((v.buffer<0) || (v.buffer>d->num_desc)) {
                        PRINT(KERN_ERR, ohci->host->id,
@@ -926,6 +927,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
                        return -EFAULT;
 
                d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
+               if (d == NULL) return -EFAULT;
 
                if ((v.buffer<0) || (v.buffer>d->num_desc)) {
                        PRINT(KERN_ERR, ohci->host->id,
@@ -1009,6 +1011,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
                        return -EFAULT;
 
                d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
+               if (d == NULL) return -EFAULT;
 
                if ((v.buffer<0) || (v.buffer>d->num_desc)) {
                        PRINT(KERN_ERR, ohci->host->id,
@@ -1112,6 +1115,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
                        return -EFAULT;
 
                d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
+               if (d == NULL) return -EFAULT;
 
                if ((v.buffer<0) || (v.buffer>d->num_desc)) {
                        PRINT(KERN_ERR, ohci->host->id,
index b786284..94dece4 100644 (file)
@@ -44,6 +44,13 @@ config INPUT_MOUSEDEV_PSAUX
        bool "Provide legacy /dev/psaux device"
        default y
        depends on INPUT_MOUSEDEV
+       ---help---
+         Say Y here if you want your mouse also be accessible as char device
+         10:1 - /dev/psaux. The data available through /dev/psaux is exactly
+         the same as the data from /dev/input/mice.
+
+         If unsure, say Y.
+
 
 config INPUT_MOUSEDEV_SCREEN_X
        int "Horizontal screen resolution"
index c31f5ab..7eabb5f 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -35,7 +35,7 @@
 #include <linux/device.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("Input driver event debug module"); 
+MODULE_DESCRIPTION("Input driver event debug module");
 MODULE_LICENSE("GPL");
 
 static char evbug_name[] = "evbug";
@@ -67,7 +67,7 @@ static struct input_handle *evbug_connect(struct input_handler *handler, struct
 static void evbug_disconnect(struct input_handle *handle)
 {
        printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys);
-       
+
        input_close_device(handle);
 
        kfree(handle);
@@ -79,7 +79,7 @@ static struct input_device_id evbug_ids[] = {
 };
 
 MODULE_DEVICE_TABLE(input, evbug_ids);
-       
+
 static struct input_handler evbug_handler = {
        .event =        evbug_event,
        .connect =      evbug_connect,
index 4f784c8..3737e5a 100644 (file)
@@ -126,7 +126,7 @@ static int evdev_open(struct inode * inode, struct file * file)
        int i = iminor(inode) - EVDEV_MINOR_BASE;
        int accept_err;
 
-       if (i >= EVDEV_MINORS || !evdev_table[i])
+       if (i >= EVDEV_MINORS || !evdev_table[i] || !evdev_table[i]->exist)
                return -ENODEV;
 
        if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file)))
@@ -175,7 +175,7 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count
                return -EAGAIN;
 
        retval = wait_event_interruptible(list->evdev->wait,
-               list->head != list->tail && list->evdev->exist);
+               list->head != list->tail || (!list->evdev->exist));
 
        if (retval)
                return retval;
@@ -222,7 +222,7 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
                case EVIOCGID:
                        return copy_to_user(p, &dev->id, sizeof(struct input_id)) ? -EFAULT : 0;
-               
+
                case EVIOCGKEYCODE:
                        if (get_user(t, ip)) return -EFAULT;
                        if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL;
@@ -430,7 +430,7 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct
 
        devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
                        S_IFCHR|S_IRUGO|S_IWUSR, "input/event%d", minor);
-       class_simple_device_add(input_class, 
+       class_simple_device_add(input_class,
                                MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
                                dev->dev, "event%d", minor);
 
index 0ec91ea..71fcad1 100644 (file)
@@ -1,8 +1,8 @@
 /*
-       The all defines and part of code (such as cs461x_*) are 
-       contributed from ALSA 0.5.8 sources. 
+       The all defines and part of code (such as cs461x_*) are
+       contributed from ALSA 0.5.8 sources.
        See http://www.alsa-project.org/ for sources
-       
+
        Tested on Linux 686 2.4.0-test9, ALSA 0.5.8a and CS4610
 */
 
@@ -89,8 +89,8 @@ MODULE_LICENSE("GPL");
 #define JSIO_BXOE                               0x00000040
 #define JSIO_BYOE                               0x00000080
 
-/* 
-   The card initialization code is obfuscated; the module cs461x 
+/*
+   The card initialization code is obfuscated; the module cs461x
    need to be loaded after ALSA modules initialized and something
    played on the CS 4610 chip (see sources for details of CS4610
    initialization code from ALSA)
@@ -112,7 +112,7 @@ MODULE_LICENSE("GPL");
 #define BA1_DWORD_SIZE          (13 * 1024 + 512)
 #define BA1_MEMORY_COUNT        3
 
-/* 
+/*
    Only one CS461x card is still suppoted; the code requires
    redesign to avoid this limitatuion.
 */
@@ -163,7 +163,7 @@ static int cs461x_free(struct pci_dev *pdev)
        if(port){
            gameport_unregister_port(port);
            kfree(port);
-       }    
+       }
        if (ba0) iounmap(ba0);
 #ifdef CS461X_FULL_MAP
        if (ba1.name.data0) iounmap(ba1.name.data0);
@@ -187,13 +187,13 @@ static unsigned char cs461x_gameport_read(struct gameport *gameport)
 static int cs461x_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
 {
        unsigned js1, js2, jst;
-       
+
        js1 = cs461x_peekBA0(BA0_JSC1);
        js2 = cs461x_peekBA0(BA0_JSC2);
        jst = cs461x_peekBA0(BA0_JSPT);
-       
-       *buttons = (~jst >> 4) & 0x0F; 
-       
+
+       *buttons = (~jst >> 4) & 0x0F;
+
        axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
        axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
        axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
@@ -228,7 +228,7 @@ static int __devinit cs461x_pci_probe(struct pci_dev *pdev, const struct pci_dev
 {
        int rc;
        struct gameport* port;
-       
+
        rc = pci_enable_device(pdev);
        if (rc) {
                printk(KERN_ERR "cs461x: Cannot enable PCI gameport (bus %d, devfn %d) error=%d\n",
@@ -240,7 +240,7 @@ static int __devinit cs461x_pci_probe(struct pci_dev *pdev, const struct pci_dev
 #ifdef CS461X_FULL_MAP
        ba1_addr = pci_resource_start(pdev, 1);
 #endif
-       if (ba0_addr == 0 || ba0_addr == ~0 
+       if (ba0_addr == 0 || ba0_addr == ~0
 #ifdef CS461X_FULL_MAP
             || ba1_addr == 0 || ba1_addr == ~0
 #endif
@@ -281,7 +281,7 @@ static int __devinit cs461x_pci_probe(struct pci_dev *pdev, const struct pci_dev
        memset(port, 0, sizeof(struct gameport));
 
        pci_set_drvdata(pdev, port);
-       
+
        port->open = cs461x_gameport_open;
        port->trigger = cs461x_gameport_trigger;
        port->read = cs461x_gameport_read;
@@ -310,7 +310,7 @@ static void __devexit cs461x_pci_remove(struct pci_dev *pdev)
 {
        cs461x_free(pdev);
 }
-       
+
 static struct pci_driver cs461x_pci_driver = {
         .name =         "CS461x Gameport",
         .id_table =     cs461x_pci_tbl,
index ec18fb3..89d4693 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -48,7 +48,7 @@ struct emu {
        int size;
        char phys[32];
 };
-       
+
 static struct pci_device_id emu_tbl[] = {
        { 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */
        { 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */
@@ -61,7 +61,7 @@ static int __devinit emu_probe(struct pci_dev *pdev, const struct pci_device_id
 {
        int ioport, iolen;
        struct emu *emu;
-        
+
        if (pci_enable_device(pdev))
                return -EBUSY;
 
index 7cd7deb..ff3b620 100644 (file)
@@ -111,7 +111,7 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
 
        pci_set_drvdata(pci, gp);
 
-       outb(0x60, gp->gameport.io + 0x0d); /* enable joystick 1 and 2 */ 
+       outb(0x60, gp->gameport.io + 0x0d); /* enable joystick 1 and 2 */
 
        gameport_register_port(&gp->gameport);
 
index 431883c..b2a68ab 100644 (file)
@@ -168,7 +168,7 @@ int gameport_open(struct gameport *gameport, struct gameport_dev *dev, int mode)
                return -1;
 
        gameport->dev = dev;
-       
+
        return 0;
 }
 
index 8a8adb5..7d1d383 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -106,7 +106,7 @@ static int l4_cooked_read(struct gameport *gameport, int *axes, int *buttons)
 
        result = 0;
 
-fail:  outb(L4_SELECT_ANALOG, L4_PORT);        
+fail:  outb(L4_SELECT_ANALOG, L4_PORT);
        return result;
 }
 
@@ -126,7 +126,7 @@ static int l4_open(struct gameport *gameport, int mode)
 static int l4_getcal(int port, int *cal)
 {
        int i, result = -1;
-       
+
        outb(L4_SELECT_ANALOG, L4_PORT);
        outb(L4_SELECT_DIGITAL + (port >> 2), L4_PORT);
 
@@ -208,7 +208,7 @@ static int l4_calibrate(struct gameport *gameport, int *axes, int *max)
 
        return 0;
 }
-       
+
 static int __init l4_init(void)
 {
        int cal[4] = {255,255,255,255};
@@ -266,7 +266,7 @@ static int __init l4_init(void)
 
                        if (rev > 0x28)         /* on 2.9+ the setcal command works correctly */
                                l4_setcal(l4->port, cal);
-                       
+
                        gameport_register_port(gameport);
                }
 
index 3528789..f31ce0b 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -59,7 +59,7 @@ struct ns558 {
        char phys[32];
        char name[32];
 };
-       
+
 static LIST_HEAD(ns558_list);
 
 /*
@@ -116,7 +116,7 @@ static void ns558_isa_probe(int io)
                        i = 0;
                        goto out;
                }
-/* 
+/*
  * And now find the number of mirrors of the port.
  */
 
@@ -292,7 +292,7 @@ void __exit ns558_exit(void)
                                release_region(port->gameport.io & ~(port->size - 1), port->size);
                                kfree(port);
                                break;
-               
+
                        default:
                                break;
                }
index fa20a33..02c31b7 100644 (file)
@@ -83,7 +83,7 @@ static int vortex_cooked_read(struct gameport *gameport, int *axes, int *buttons
                axes[i] = readw(vortex->io + VORTEX_AXD + i * sizeof(u32));
                if (axes[i] == 0x1fff) axes[i] = -1;
        }
-        
+
         return 0;
 }
 
@@ -122,7 +122,7 @@ static int __devinit vortex_probe(struct pci_dev *dev, const struct pci_device_i
 
        vortex->gameport.driver = vortex;
        vortex->gameport.fuzz = 64;
-       
+
        vortex->gameport.read = vortex_read;
        vortex->gameport.trigger = vortex_trigger;
        vortex->gameport.cooked_read = vortex_cooked_read;
@@ -145,7 +145,7 @@ static int __devinit vortex_probe(struct pci_dev *dev, const struct pci_device_i
        vortex->io = vortex->base + id->driver_data;
 
        gameport_register_port(&vortex->gameport);
-       
+
        printk(KERN_INFO "gameport at pci%s speed %d kHz\n",
                pci_name(dev), vortex->gameport.speed);
 
index 41bb521..73b1741 100644 (file)
@@ -106,7 +106,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
                        }
 
                        break;
-               
+
                case EV_ABS:
 
                        if (code > ABS_MAX || !test_bit(code, dev->absbit))
@@ -144,27 +144,27 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
                        if (code > MSC_MAX || !test_bit(code, dev->mscbit))
                                return;
 
-                       if (dev->event) dev->event(dev, type, code, value);     
-       
+                       if (dev->event) dev->event(dev, type, code, value);
+
                        break;
 
                case EV_LED:
-       
+
                        if (code > LED_MAX || !test_bit(code, dev->ledbit) || !!test_bit(code, dev->led) == value)
                                return;
 
                        change_bit(code, dev->led);
-                       if (dev->event) dev->event(dev, type, code, value);     
-       
+                       if (dev->event) dev->event(dev, type, code, value);
+
                        break;
 
                case EV_SND:
-       
+
                        if (code > SND_MAX || !test_bit(code, dev->sndbit))
                                return;
 
-                       if (dev->event) dev->event(dev, type, code, value);     
-       
+                       if (dev->event) dev->event(dev, type, code, value);
+
                        break;
 
                case EV_REP:
@@ -181,7 +181,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
                        break;
        }
 
-       if (type != EV_SYN) 
+       if (type != EV_SYN)
                dev->sync = 0;
 
        if (dev->grab)
@@ -282,11 +282,11 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st
                if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
                        if (id->id.vendor != dev->id.vendor)
                                continue;
-       
+
                if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
                        if (id->id.product != dev->id.product)
                                continue;
-               
+
                if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
                        if (id->id.version != dev->id.version)
                                continue;
@@ -351,11 +351,11 @@ static void input_call_hotplug(char *verb, struct input_dev *dev)
        }
        if (in_interrupt()) {
                printk(KERN_ERR "input.c: calling hotplug from interrupt\n");
-               return; 
+               return;
        }
        if (!current->fs->root) {
                printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n");
-               return; 
+               return;
        }
        if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) {
                printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
@@ -381,17 +381,17 @@ static void input_call_hotplug(char *verb, struct input_dev *dev)
 
        envp[i++] = scratch;
        scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x",
-               dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1; 
-       
+               dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1;
+
        if (dev->name) {
                envp[i++] = scratch;
-               scratch += sprintf(scratch, "NAME=%s", dev->name) + 1; 
+               scratch += sprintf(scratch, "NAME=%s", dev->name) + 1;
        }
 
        if (dev->phys) {
                envp[i++] = scratch;
-               scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1; 
-       }       
+               scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1;
+       }
 
        SPRINTF_BIT_A(evbit, "EV=", EV_MAX);
        SPRINTF_BIT_A2(keybit, "KEY=", KEY_MAX, EV_KEY);
@@ -506,7 +506,7 @@ void input_register_handler(struct input_handler *handler)
                input_table[handler->minor >> 5] = handler;
 
        list_add_tail(&handler->node, &input_handler_list);
-       
+
        list_for_each_entry(dev, &input_dev_list, node)
                if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
                        if ((id = input_match_device(handler->id_table, dev)))
index abc2e10..5eb8846 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Joystick device driver for the input driver suite.
  *
- * Copyright (c) 1999-2002 Vojtech Pavlik 
- * Copyright (c) 1999 Colin Van Dyke 
+ * Copyright (c) 1999-2002 Vojtech Pavlik
+ * Copyright (c) 1999 Colin Van Dyke
  *
  * 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.
  */
 
@@ -34,7 +34,7 @@ MODULE_SUPPORTED_DEVICE("input/js");
 MODULE_LICENSE("GPL");
 
 #define JOYDEV_MINOR_BASE      0
-#define JOYDEV_MINORS          16      
+#define JOYDEV_MINORS          16
 #define JOYDEV_BUFFER_SIZE     64
 
 #define MSECS(t)       (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
@@ -115,7 +115,7 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne
 
                default:
                        return;
-       }  
+       }
 
        event.time = MSECS(jiffies);
 
@@ -191,12 +191,12 @@ static int joydev_open(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t joydev_write(struct file * file, const char * buffer, size_t count, loff_t *ppos)
+static ssize_t joydev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
 {
        return -EINVAL;
 }
 
-static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
        struct joydev_list *list = file->private_data;
        struct joydev *joydev = list->joydev;
@@ -291,6 +291,7 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
        struct joydev_list *list = file->private_data;
        struct joydev *joydev = list->joydev;
        struct input_dev *dev = joydev->handle.dev;
+       void __user *argp = (void __user *)arg;
        int i, j;
 
        if (!joydev->exist) return -ENODEV;
@@ -298,34 +299,34 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
        switch (cmd) {
 
                case JS_SET_CAL:
-                       return copy_from_user(&joydev->glue.JS_CORR, (struct JS_DATA_TYPE *) arg,
+                       return copy_from_user(&joydev->glue.JS_CORR, argp,
                                sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;
                case JS_GET_CAL:
-                       return copy_to_user((struct JS_DATA_TYPE *) arg, &joydev->glue.JS_CORR,
+                       return copy_to_user(argp, &joydev->glue.JS_CORR,
                                sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;
                case JS_SET_TIMEOUT:
-                       return get_user(joydev->glue.JS_TIMEOUT, (int *) arg);
+                       return get_user(joydev->glue.JS_TIMEOUT, (int __user *) arg);
                case JS_GET_TIMEOUT:
-                       return put_user(joydev->glue.JS_TIMEOUT, (int *) arg);
+                       return put_user(joydev->glue.JS_TIMEOUT, (int __user *) arg);
                case JS_SET_TIMELIMIT:
-                       return get_user(joydev->glue.JS_TIMELIMIT, (long *) arg);
+                       return get_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
                case JS_GET_TIMELIMIT:
-                       return put_user(joydev->glue.JS_TIMELIMIT, (long *) arg);
+                       return put_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
                case JS_SET_ALL:
-                       return copy_from_user(&joydev->glue, (struct JS_DATA_SAVE_TYPE *) arg,
+                       return copy_from_user(&joydev->glue, argp,
                                                sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
                case JS_GET_ALL:
-                       return copy_to_user((struct JS_DATA_SAVE_TYPE *) arg, &joydev->glue,
+                       return copy_to_user(argp, &joydev->glue,
                                                sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
 
                case JSIOCGVERSION:
-                       return put_user(JS_VERSION, (__u32 *) arg);
+                       return put_user(JS_VERSION, (__u32 __user *) arg);
                case JSIOCGAXES:
-                       return put_user(joydev->nabs, (__u8 *) arg);
+                       return put_user(joydev->nabs, (__u8 __user *) arg);
                case JSIOCGBUTTONS:
-                       return put_user(joydev->nkey, (__u8 *) arg);
+                       return put_user(joydev->nkey, (__u8 __user *) arg);
                case JSIOCSCORR:
-                       if (copy_from_user(joydev->corr, (struct js_corr *)arg,
+                       if (copy_from_user(joydev->corr, argp,
                                      sizeof(struct js_corr) * joydev->nabs))
                            return -EFAULT;
                        for (i = 0; i < joydev->nabs; i++) {
@@ -334,10 +335,10 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        }
                        return 0;
                case JSIOCGCORR:
-                       return copy_to_user((struct js_corr *) arg, joydev->corr,
+                       return copy_to_user(argp, joydev->corr,
                                                sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0;
                case JSIOCSAXMAP:
-                       if (copy_from_user(joydev->abspam, (__u8 *) arg, sizeof(__u8) * ABS_MAX))
+                       if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * ABS_MAX))
                                return -EFAULT;
                        for (i = 0; i < joydev->nabs; i++) {
                                if (joydev->abspam[i] > ABS_MAX) return -EINVAL;
@@ -345,10 +346,10 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        }
                        return 0;
                case JSIOCGAXMAP:
-                       return copy_to_user((__u8 *) arg, joydev->abspam,
+                       return copy_to_user(argp, joydev->abspam,
                                                sizeof(__u8) * ABS_MAX) ? -EFAULT : 0;
                case JSIOCSBTNMAP:
-                       if (copy_from_user(joydev->keypam, (__u16 *) arg, sizeof(__u16) * (KEY_MAX - BTN_MISC)))
+                       if (copy_from_user(joydev->keypam, argp, sizeof(__u16) * (KEY_MAX - BTN_MISC)))
                                return -EFAULT;
                        for (i = 0; i < joydev->nkey; i++) {
                                if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL;
@@ -356,7 +357,7 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        }
                        return 0;
                case JSIOCGBTNMAP:
-                       return copy_to_user((__u16 *) arg, joydev->keypam,
+                       return copy_to_user(argp, joydev->keypam,
                                                sizeof(__u16) * (KEY_MAX - BTN_MISC)) ? -EFAULT : 0;
                default:
                        if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) {
@@ -364,7 +365,7 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                                if (!dev->name) return 0;
                                len = strlen(dev->name) + 1;
                                if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-                               if (copy_to_user((char *) arg, dev->name, len)) return -EFAULT;
+                               if (copy_to_user(argp, dev->name, len)) return -EFAULT;
                                return len;
                        }
        }
@@ -449,10 +450,10 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
        }
 
        joydev_table[minor] = joydev;
-       
+
        devfs_mk_cdev(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
                        S_IFCHR|S_IRUGO|S_IWUSR, "input/js%d", minor);
-       class_simple_device_add(input_class, 
+       class_simple_device_add(input_class,
                                MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
                                dev->dev, "js%d", minor);
 
@@ -466,7 +467,7 @@ static void joydev_disconnect(struct input_handle *handle)
        joydev->exist = 0;
 
        if (joydev->open)
-               input_close_device(handle);     
+               input_close_device(handle);
        else
                joydev_free(joydev);
 }
index 1ae0338..7d506f1 100644 (file)
@@ -22,7 +22,7 @@ config JOYSTICK_ANALOG
          supports many extensions, including joysticks with throttle control,
          with rudders, additional hats and buttons compatible with CH
          Flightstick Pro, ThrustMaster FCS, 6 and 8 button gamepads, or
-         Saitek Cyborg joysticks. 
+         Saitek Cyborg joysticks.
 
          Please read the file <file:Documentation/input/joystick.txt> which
          contains more information.
@@ -35,7 +35,7 @@ config JOYSTICK_A3D
        depends on INPUT && INPUT_JOYSTICK && GAMEPORT
        help
          Say Y here if you have an FPGaming or MadCatz controller using the
-         A3D protocol over the PC gameport. 
+         A3D protocol over the PC gameport.
 
          To compile this driver as a module, choose M here: the
          module will be called a3d.
@@ -45,7 +45,7 @@ config JOYSTICK_ADI
        depends on INPUT && INPUT_JOYSTICK && GAMEPORT
        help
          Say Y here if you have a Logitech controller using the ADI
-         protocol over the PC gameport. 
+         protocol over the PC gameport.
 
          To compile this driver as a module, choose M here: the
          module will be called adi.
@@ -74,7 +74,7 @@ config JOYSTICK_GRIP
        depends on INPUT && INPUT_JOYSTICK && GAMEPORT
        help
          Say Y here if you have a Gravis controller using the GrIP protocol
-         over the PC gameport. 
+         over the PC gameport.
 
          To compile this driver as a module, choose M here: the
          module will be called grip.
@@ -94,7 +94,7 @@ config JOYSTICK_GUILLEMOT
        depends on INPUT && INPUT_JOYSTICK && GAMEPORT
        help
          Say Y here if you have a Guillemot joystick using a digital
-         protocol over the PC gameport. 
+         protocol over the PC gameport.
 
          To compile this driver as a module, choose M here: the
          module will be called guillemot.
@@ -124,7 +124,7 @@ config JOYSTICK_TMDC
        depends on INPUT && INPUT_JOYSTICK && GAMEPORT
        help
          Say Y here if you have a ThrustMaster controller using the
-         DirectConnect (BSP) protocol over the PC gameport. 
+         DirectConnect (BSP) protocol over the PC gameport.
 
          To compile this driver as a module, choose M here: the
          module will be called tmdc.
@@ -137,7 +137,7 @@ config JOYSTICK_WARRIOR
        select SERIO
        help
          Say Y here if you have a Logitech WingMan Warrior joystick connected
-         to your computer's serial port. 
+         to your computer's serial port.
 
          To compile this driver as a module, choose M here: the
          module will be called warrior.
@@ -253,7 +253,7 @@ config INPUT_JOYDUMP
        help
          Say Y here if you want to dump data from your joystick into the system
          log for debugging purposes. Say N if you are making a production
-         configuration or aren't sure. 
+         configuration or aren't sure.
 
          To compile this driver as a module, choose M here: the
          module will be called joydump.
index 9d66a65..b3eb64f 100644 (file)
@@ -39,8 +39,8 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("FP-Gaming Assasin 3D joystick driver");
 MODULE_LICENSE("GPL");
 
-#define A3D_MAX_START          400     /* 400 us */ 
-#define A3D_MAX_STROBE         60      /* 40 us */ 
+#define A3D_MAX_START          400     /* 400 us */
+#define A3D_MAX_STROBE         60      /* 40 us */
 #define A3D_DELAY_READ         3       /* 3 ms */
 #define A3D_MAX_LENGTH         40      /* 40*3 bits */
 #define A3D_REFRESH_TIME       HZ/50   /* 20 ms */
@@ -125,7 +125,7 @@ static void a3d_read(struct a3d *a3d, unsigned char *data)
 
                        input_report_rel(dev, REL_X, ((data[5] << 6) | (data[6] << 3) | data[ 7]) - ((data[5] & 4) << 7));
                        input_report_rel(dev, REL_Y, ((data[8] << 6) | (data[9] << 3) | data[10]) - ((data[8] & 4) << 7));
-                       
+
                        input_report_key(dev, BTN_RIGHT,  data[2] & 1);
                        input_report_key(dev, BTN_LEFT,   data[3] & 2);
                        input_report_key(dev, BTN_MIDDLE, data[3] & 4);
@@ -201,7 +201,7 @@ int a3d_adc_cooked_read(struct gameport *gameport, int *axes, int *buttons)
        int i;
        for (i = 0; i < 4; i++)
                axes[i] = (a3d->axes[i] < 254) ? a3d->axes[i] : -1;
-       *buttons = a3d->buttons; 
+       *buttons = a3d->buttons;
        return 0;
 }
 
@@ -216,7 +216,7 @@ int a3d_adc_open(struct gameport *gameport, int mode)
        if (mode != GAMEPORT_MODE_COOKED)
                return -1;
        if (!a3d->used++)
-               mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);     
+               mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
        return 0;
 }
 
@@ -239,7 +239,7 @@ static int a3d_open(struct input_dev *dev)
 {
        struct a3d *a3d = dev->private;
        if (!a3d->used++)
-               mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);     
+               mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
        return 0;
 }
 
@@ -340,7 +340,7 @@ static void a3d_connect(struct gameport *gameport, struct gameport_dev *dev)
                a3d->adc.open = a3d_adc_open;
                a3d->adc.close = a3d_adc_close;
                a3d->adc.cooked_read = a3d_adc_cooked_read;
-               a3d->adc.fuzz = 1; 
+               a3d->adc.fuzz = 1;
 
                a3d->adc.name = a3d_names[a3d->mode];
                a3d->adc.phys = a3d->adcphys;
index 10ef222..da70b5d 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -72,8 +72,8 @@ MODULE_LICENSE("GPL");
  */
 
 static char *adi_names[] = {   "WingMan Extreme Digital", "ThunderPad Digital", "SideCar", "CyberMan 2",
-                               "WingMan Interceptor", "WingMan Formula", "WingMan GamePad", 
-                               "WingMan Extreme Digital 3D", "WingMan GamePad Extreme", 
+                               "WingMan Interceptor", "WingMan Formula", "WingMan GamePad",
+                               "WingMan Extreme Digital 3D", "WingMan GamePad Extreme",
                                "WingMan GamePad USB", "Unknown Device %#x" };
 
 static char adi_wmgpe_abs[] =  { ABS_X, ABS_Y, ABS_HAT0X, ABS_HAT0Y };
@@ -178,7 +178,7 @@ static void adi_read_packet(struct adi_port *port)
 
 /*
  * adi_move_bits() detects a possible 2-stream mode, and moves
- * the bits accordingly. 
+ * the bits accordingly.
  */
 
 static void adi_move_bits(struct adi_port *port, int length)
@@ -208,7 +208,7 @@ static inline int adi_get_bits(struct adi *adi, int count)
        int i;
        if ((adi->idx += count) > adi->ret) return 0;
        for (i = 0; i < count; i++)
-               bits |= ((adi->data[adi->idx - i] >> 5) & 1) << i; 
+               bits |= ((adi->data[adi->idx - i] >> 5) & 1) << i;
        return bits;
 }
 
@@ -224,12 +224,12 @@ static int adi_decode(struct adi *adi)
        int i, t;
 
        if (adi->ret < adi->length || adi->id != (adi_get_bits(adi, 4) | (adi_get_bits(adi, 4) << 4)))
-               return -1;      
+               return -1;
 
-       for (i = 0; i < adi->axes10; i++) 
+       for (i = 0; i < adi->axes10; i++)
                input_report_abs(dev, *abs++, adi_get_bits(adi, 10));
 
-       for (i = 0; i < adi->axes8; i++) 
+       for (i = 0; i < adi->axes8; i++)
                input_report_abs(dev, *abs++, adi_get_bits(adi, 8));
 
        for (i = 0; i < adi->buttons && i < 63; i++) {
@@ -249,7 +249,7 @@ static int adi_decode(struct adi *adi)
 
        for (i = 63; i < adi->buttons; i++)
                input_report_key(dev, *key++, adi_get_bits(adi, 1));
-       
+
        input_sync(dev);
 
        return 0;
@@ -294,7 +294,7 @@ static int adi_open(struct input_dev *dev)
 {
        struct adi_port *port = dev->private;
        if (!port->used++)
-               mod_timer(&port->timer, jiffies + ADI_REFRESH_TIME);    
+               mod_timer(&port->timer, jiffies + ADI_REFRESH_TIME);
        return 0;
 }
 
@@ -334,7 +334,7 @@ static void adi_id_decode(struct adi *adi, struct adi_port *port)
                return;
 
        if (adi->ret < (t = adi_get_bits(adi, 10))) {
-               printk(KERN_WARNING "adi: Short ID packet: reported: %d != read: %d\n", t, adi->ret); 
+               printk(KERN_WARNING "adi: Short ID packet: reported: %d != read: %d\n", t, adi->ret);
                return;
        }
 
@@ -498,7 +498,7 @@ static void adi_connect(struct gameport *gameport, struct gameport_dev *dev)
 
        adi_init_digital(gameport);
        adi_read_packet(port);
-       
+
        if (port->adi[0].ret >= ADI_MIN_LEN_LENGTH)
                adi_move_bits(port, adi_get_bits(port->adi, 10));
 
index df57287..8b5fc35 100644 (file)
@@ -46,7 +46,7 @@ MODULE_DESCRIPTION("Driver for Amiga joysticks");
 MODULE_LICENSE("GPL");
 
 static int amijoy[2] = { 0, 1 };
-static int amijoy_nargs;  
+static int amijoy_nargs;
 module_param_array_named(map, amijoy, uint, amijoy_nargs, 0);
 MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is 0,1)");
 
index 5d10a64..3e83968 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -237,7 +237,7 @@ static int analog_cooked_read(struct analog_port *port)
 
        loopout = (ANALOG_LOOP_TIME * port->loop) / 1000;
        timeout = ANALOG_MAX_TIME * port->speed;
-       
+
        local_irq_save(flags);
        gameport_trigger(gameport);
        GET_TIME(now);
@@ -284,7 +284,7 @@ static int analog_button_read(struct analog_port *port, char saitek, char chf)
 
        u = gameport_read(port->gameport);
 
-       if (!chf) { 
+       if (!chf) {
                port->buttons = (~u >> 4) & 0xf;
                return 0;
        }
@@ -333,7 +333,7 @@ static void analog_timer(unsigned long data)
                }
        }
 
-       for (i = 0; i < 2; i++) 
+       for (i = 0; i < 2; i++)
                if (port->analog[i].mask)
                        analog_decode(port->analog + i, port->axes, port->initial, port->buttons);
 
@@ -348,7 +348,7 @@ static int analog_open(struct input_dev *dev)
 {
        struct analog_port *port = dev->private;
        if (!port->used++)
-               mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME); 
+               mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME);
        return 0;
 }
 
@@ -408,7 +408,7 @@ static void analog_calibrate_timer(struct analog_port *port)
 
 static void analog_name(struct analog *analog)
 {
-       sprintf(analog->name, "Analog %d-axis %d-button", 
+       sprintf(analog->name, "Analog %d-axis %d-button",
                hweight8(analog->mask & ANALOG_AXES_STD),
                hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 +
                hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4);
@@ -450,10 +450,10 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
        analog->dev.close = analog_close;
        analog->dev.private = port;
        analog->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       
+
        for (i = j = 0; i < 4; i++)
                if (analog->mask & (1 << i)) {
-                       
+
                        t = analog_axes[j];
                        x = port->axes[i];
                        y = (port->axes[0] + port->axes[1]) >> 1;
@@ -481,8 +481,8 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
                        j++;
                }
 
-       for (i = j = 0; i < 3; i++) 
-               if (analog->mask & analog_exts[i]) 
+       for (i = j = 0; i < 3; i++)
+               if (analog->mask & analog_exts[i])
                        for (x = 0; x < 2; x++) {
                                t = analog_hats[j++];
                                set_bit(t, analog->dev.absbit);
@@ -517,7 +517,7 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
        else
                printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME,
                port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed,
-               port->speed > 10000 ? "M" : "k", 
+               port->speed > 10000 ? "M" : "k",
                port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000)
                                    : (port->loop * 1000000) / port->speed);
 }
@@ -580,11 +580,11 @@ static int analog_init_masks(struct analog_port *port)
 
                gameport_calibrate(port->gameport, port->axes, max);
        }
-               
-       for (i = 0; i < 4; i++) 
+
+       for (i = 0; i < 4; i++)
                port->initial[i] = port->axes[i];
 
-       return -!(analog[0].mask || analog[1].mask);    
+       return -!(analog[0].mask || analog[1].mask);
 }
 
 static int analog_init_port(struct gameport *gameport, struct gameport_dev *dev, struct analog_port *port)
@@ -606,7 +606,7 @@ static int analog_init_port(struct gameport *gameport, struct gameport_dev *dev,
                msleep(ANALOG_MAX_TIME);
                port->mask = (gameport_read(gameport) ^ t) & t & 0xf;
                port->fuzz = (port->speed * ANALOG_FUZZ_MAGIC) / port->loop / 1000 + ANALOG_FUZZ_BITS;
-       
+
                for (i = 0; i < ANALOG_INIT_RETRIES; i++) {
                        if (!analog_cooked_read(port)) break;
                        msleep(ANALOG_MAX_TIME);
@@ -617,11 +617,11 @@ static int analog_init_port(struct gameport *gameport, struct gameport_dev *dev,
                msleep(ANALOG_MAX_TIME);
                t = gameport_time(gameport, ANALOG_MAX_TIME * 1000);
                gameport_trigger(gameport);
-               while ((gameport_read(port->gameport) & port->mask) && (u < t)) u++; 
+               while ((gameport_read(port->gameport) & port->mask) && (u < t)) u++;
                udelay(ANALOG_SAITEK_DELAY);
                t = gameport_time(gameport, ANALOG_SAITEK_TIME);
                gameport_trigger(gameport);
-               while ((gameport_read(port->gameport) & port->mask) && (v < t)) v++; 
+               while ((gameport_read(port->gameport) & port->mask) && (v < t)) v++;
 
                if (v < (u >> 1)) { /* FIXME - more than one port */
                        analog_options[0] |= /* FIXME - more than one port */
@@ -721,7 +721,7 @@ static void analog_parse_options(void)
                        if (!strcmp(analog_types[j].name, js[i])) {
                                analog_options[i] = analog_types[j].value;
                                break;
-                       } 
+                       }
                if (analog_types[j].name) continue;
 
                analog_options[i] = simple_strtoul(js[i], &end, 0);
index 9ca36ed..fc29ad7 100644 (file)
@@ -72,7 +72,7 @@ static unsigned char cobra_read_packet(struct gameport *gameport, unsigned int *
                r[i] = buf[i] = 0;
                t[i] = COBRA_MAX_STROBE;
        }
-       
+
        local_irq_save(flags);
 
        u = gameport_read(gameport);
@@ -140,14 +140,14 @@ static void cobra_timer(unsigned long private)
 
                }
 
-       mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME); 
+       mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME);
 }
 
 static int cobra_open(struct input_dev *dev)
 {
        struct cobra *cobra = dev->private;
        if (!cobra->used++)
-               mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME); 
+               mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME);
        return 0;
 }
 
@@ -180,7 +180,7 @@ static void cobra_connect(struct gameport *gameport, struct gameport_dev *dev)
 
        cobra->exists = cobra_read_packet(gameport, data);
 
-       for (i = 0; i < 2; i++) 
+       for (i = 0; i < 2; i++)
                if ((cobra->exists >> i) & data[i] & 1) {
                        printk(KERN_WARNING "cobra.c: Device %d on %s has the Ext bit set. ID is: %d"
                                " Contact vojtech@ucw.cz\n", i, gameport->phys, (data[i] >> 2) & 7);
@@ -205,7 +205,7 @@ static void cobra_connect(struct gameport *gameport, struct gameport_dev *dev)
                        cobra->dev[i].id.vendor = GAMEPORT_ID_VENDOR_CREATIVE;
                        cobra->dev[i].id.product = 0x0008;
                        cobra->dev[i].id.version = 0x0100;
-               
+
                        cobra->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
                        cobra->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
 
index f7d3eeb..5ad6127 100644 (file)
 /*
  * 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
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -95,7 +95,7 @@ __obsolete_setup("db9_3=");
 struct db9 {
        struct input_dev dev[DB9_MAX_DEVICES];
        struct timer_list timer;
-       struct pardevice *pd;   
+       struct pardevice *pd;
        int mode;
        int used;
        char phys[2][32];
@@ -188,7 +188,7 @@ static unsigned char db9_saturn_read_analog(struct parport *port, int type, int
 }
 
 /*
- * db9_saturn_read_packet() reads whole saturn packet at connector 
+ * db9_saturn_read_packet() reads whole saturn packet at connector
  * and returns device identifier code.
  */
 static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char *data, int type, int powered)
@@ -481,16 +481,16 @@ static void db9_timer(unsigned long private)
                        input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
                        input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
 
-                       parport_write_control(port, 0x0a); 
+                       parport_write_control(port, 0x0a);
 
-                       for (i = 0; i < 7; i++) { 
+                       for (i = 0; i < 7; i++) {
                                data = parport_read_data(port);
-                               parport_write_control(port, 0x02); 
-                               parport_write_control(port, 0x0a); 
+                               parport_write_control(port, 0x02);
+                               parport_write_control(port, 0x0a);
                                input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2);
                                }
 
-                       parport_write_control(port, 0x00); 
+                       parport_write_control(port, 0x00);
                        break;
                }
 
@@ -600,7 +600,7 @@ static struct db9 __init *db9_probe(int *config, int nargs)
 
                db9->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
                for (j = 0; j < db9_buttons[db9->mode]; j++)
-                       set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit); 
+                       set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit);
                for (j = 0; j < db9_num_axis[db9->mode]; j++) {
                        set_bit(db9_abs[j], db9->dev[i].absbit);
                        if (j < 2) {
@@ -635,7 +635,7 @@ void __exit db9_exit(void)
 {
        int i, j;
 
-       for (i = 0; i < 3; i++) 
+       for (i = 0; i < 3; i++)
                if (db9_base[i]) {
                        for (j = 0; j < min(db9_max_pads[db9_base[i]->mode], DB9_MAX_DEVICES); j++)
                                input_unregister_device(db9_base[i]->dev + j);
index 02ee05a..555fb36 100644 (file)
 /*
  * 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
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -70,13 +70,13 @@ __obsolete_setup("gc_3=");
 #define GC_NES4                3
 #define GC_MULTI       4
 #define GC_MULTI2      5
-#define GC_N64         6       
+#define GC_N64         6
 #define GC_PSX         7
 
 #define GC_MAX         7
 
 #define GC_REFRESH_TIME        HZ/100
+
 struct gc {
        struct pardevice *pd;
        struct input_dev dev[5];
@@ -104,7 +104,7 @@ static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL,
 #define GC_N64_DELAY           133             /* delay between transmit request, and response ready (us) */
 #define GC_N64_REQUEST         0x1dd1111111ULL /* the request data command (encoded for 000000011) */
 #define GC_N64_DWS             3               /* delay between write segments (required for sound playback because of ISA DMA) */
-                                               /* GC_N64_DWS > 24 is known to fail */ 
+                                               /* GC_N64_DWS > 24 is known to fail */
 #define GC_N64_POWER_W         0xe2            /* power during write (transmit request) */
 #define GC_N64_POWER_R         0xfd            /* power during read */
 #define GC_N64_OUT             0x1d            /* output bits to the 4 pads */
@@ -113,8 +113,8 @@ static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL,
                                                /* than 123 us */
 #define GC_N64_CLOCK           0x02            /* clock bits for read */
 
-/* 
- * gc_n64_read_packet() reads an N64 packet. 
+/*
+ * gc_n64_read_packet() reads an N64 packet.
  * Each pad uses one bit per byte. So all pads connected to this port are read in parallel.
  */
 
@@ -224,7 +224,7 @@ static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data)
  *     http://www.dim.com/~mackys/psxmemcard/ps-eng2.txt
  *     http://www.gamesx.com/controldata/psxcont/psxcont.htm
  *     ftp://milano.usal.es/pablo/
- *     
+ *
  */
 
 #define GC_PSX_DELAY   25              /* 25 usec */
@@ -331,13 +331,13 @@ static void gc_timer(unsigned long private)
                        s = gc_status_bit[i];
 
                        if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) {
-       
+
                                signed char axes[2];
                                axes[0] = axes[1] = 0;
 
                                for (j = 0; j < 8; j++) {
-                                       if (data[23 - j] & s) axes[0] |= 1 << j; 
-                                       if (data[31 - j] & s) axes[1] |= 1 << j; 
+                                       if (data[23 - j] & s) axes[0] |= 1 << j;
+                                       if (data[31 - j] & s) axes[1] |= 1 << j;
                                }
 
                                input_report_abs(dev + i, ABS_X,  axes[0]);
@@ -588,7 +588,7 @@ static struct gc __init *gc_probe(int *config, int nargs)
                                break;
 
                        case GC_PSX:
-                               
+
                                psx = gc_psx_read_packet(gc, data);
 
                                switch(psx) {
@@ -629,7 +629,7 @@ static struct gc __init *gc_probe(int *config, int nargs)
                }
 
                sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i);
-               
+
                 gc->dev[i].name = gc_names[config[i + 1]];
                gc->dev[i].phys = gc->phys[i];
                 gc->dev[i].id.bustype = BUS_PARPORT;
@@ -646,7 +646,7 @@ static struct gc __init *gc_probe(int *config, int nargs)
                return NULL;
        }
 
-       for (i = 0; i < 5; i++) 
+       for (i = 0; i < 5; i++)
                if (gc->pads[0] & gc_status_bit[i]) {
                        input_register_device(gc->dev + i);
                        printk(KERN_INFO "input: %s on %s\n", gc->dev[i].name, gc->pd->port->name);
@@ -675,7 +675,7 @@ void __exit gc_exit(void)
                if (gc_base[i]) {
                        for (j = 0; j < 5; j++)
                                if (gc_base[i]->pads[0] & gc_status_bit[j])
-                                       input_unregister_device(gc_base[i]->dev + j); 
+                                       input_unregister_device(gc_base[i]->dev + j);
                        parport_unregister_device(gc_base[i]->pd);
                }
 }
index 7cec946..10cc6ca 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -223,7 +223,7 @@ static int gf2k_open(struct input_dev *dev)
 {
        struct gf2k *gf2k = dev->private;
        if (!gf2k->used++)
-               mod_timer(&gf2k->timer, jiffies + GF2K_REFRESH);        
+               mod_timer(&gf2k->timer, jiffies + GF2K_REFRESH);
        return 0;
 }
 
@@ -324,7 +324,7 @@ static void gf2k_connect(struct gameport *gameport, struct gameport_dev *dev)
 
        for (i = 0; i < gf2k_axes[gf2k->id]; i++) {
                gf2k->dev.absmax[gf2k_abs[i]] = (i < 2) ? gf2k->dev.abs[gf2k_abs[i]] * 2 - 32 :
-                         gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32; 
+                         gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32;
                gf2k->dev.absmin[gf2k_abs[i]] = 32;
                gf2k->dev.absfuzz[gf2k_abs[i]] = 8;
                gf2k->dev.absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
index 9acf65a..3b1b07e 100644 (file)
@@ -48,8 +48,8 @@ MODULE_LICENSE("GPL");
 #define GRIP_STROBE_GPP                200     /* 200 us */
 #define GRIP_LENGTH_XT         4
 #define GRIP_STROBE_XT         64      /* 64 us */
-#define GRIP_MAX_CHUNKS_XT     10      
-#define GRIP_MAX_BITS_XT       30      
+#define GRIP_MAX_CHUNKS_XT     10
+#define GRIP_MAX_BITS_XT       30
 
 #define GRIP_REFRESH_TIME      HZ/50   /* 20 ms */
 
@@ -153,7 +153,7 @@ static int grip_xt_read_packet(struct gameport *gameport, int shift, unsigned in
                                buf = (buf << 1) | (u >> 1);
                                t = strobe;
                                i++;
-                       } else 
+                       } else
 
                        if ((((u ^ v) & (v ^ w)) >> 1) & ~(u | v | w) & 1) {
                                if (i == 20) {
index d762348..995caa3 100644 (file)
@@ -69,7 +69,7 @@ struct grip_mp {
 #define IO_MODE_FAST         0x0200           /* Used 3 data bits per gameport read     */
 #define IO_SLOT_CHANGE       0x0800           /* Multiport physical slot status changed */
 #define IO_DONE              0x1000           /* Multiport is done sending packets      */
-#define IO_RETRY             0x4000           /* Try again later to get packet          */ 
+#define IO_RETRY             0x4000           /* Try again later to get packet          */
 #define IO_RESET             0x8000           /* Force multiport to resend all packets  */
 
 /*
@@ -144,8 +144,8 @@ static inline int poll_until(u8 onbits, u8 offbits, int u_sec, struct gameport*
 /*
  * Gets a 28-bit packet from the multiport.
  *
- * After getting a packet successfully, commands encoded by sendcode may 
- * be sent to the multiport.  
+ * After getting a packet successfully, commands encoded by sendcode may
+ * be sent to the multiport.
  *
  * The multiport clock value is reflected in gameport bit B4.
  *
@@ -169,7 +169,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
 
        *packet = 0;
        raw_data = gameport_read(gameport);
-       if (raw_data & 1)                          
+       if (raw_data & 1)
                return IO_RETRY;
 
        for (i = 0; i < 64; i++) {
@@ -183,11 +183,11 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
 
                if (raw_data & 0x31)
                        return IO_RESET;
-               gameport_trigger(gameport); 
+               gameport_trigger(gameport);
 
                if (!poll_until(0x10, 0, 308, gameport, &raw_data))
                        return IO_RESET;
-       } else 
+       } else
                return IO_RETRY;
 
        /* Determine packet transfer mode and prepare for packet construction. */
@@ -195,7 +195,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
        if (raw_data & 0x20) {                 /* 3 data bits/read */
                portvals |= raw_data >> 4;     /* Compare B4-B7 before & after trigger */
 
-               if (portvals != 0xb)           
+               if (portvals != 0xb)
                        return 0;
                data_mask = 7;
                bits_per_read = 3;
@@ -221,7 +221,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
                        return IO_RESET;
        }
 
-       if (raw_data)                            
+       if (raw_data)
                return IO_RESET;
 
        /* If 3 bits/read used, drop from 30 bits to 28. */
@@ -231,7 +231,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
                pkt = (pkt >> 2) | 0xf0000000;
        }
 
-       if (bit_parity(pkt) == 1) 
+       if (bit_parity(pkt) == 1)
                return IO_RESET;
 
        /* Acknowledge packet receipt */
@@ -251,10 +251,10 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
 
         /* Return if we just wanted the packet or multiport wants to send more */
 
-       *packet = pkt;                               
+       *packet = pkt;
        if ((sendflags == 0) || ((sendflags & IO_RETRY) && !(pkt & PACKET_MP_DONE)))
                return IO_GOT_PACKET;
-       
+
        if (pkt & PACKET_MP_MORE)
                return IO_GOT_PACKET | IO_RETRY;
 
@@ -277,7 +277,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
                if (!poll_until(0x30, 0, 193, gameport, &raw_data))
                        return IO_GOT_PACKET | IO_RESET;
 
-               if (raw_data & 1)   
+               if (raw_data & 1)
                        return IO_GOT_PACKET | IO_RESET;
 
                if (sendcode & 1)
@@ -429,19 +429,19 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags)
                        strange_code = joytype;
                }
        }
-       return flags;  
+       return flags;
 }
 
 /*
  * Returns true if all multiport slot states appear valid.
  */
+
 static int slots_valid(struct grip_mp *grip)
 {
        int flags, slot, invalid = 0, active = 0;
 
        flags = get_and_decode_packet(grip, 0);
-       if (!(flags & IO_GOT_PACKET))          
+       if (!(flags & IO_GOT_PACKET))
                return 0;
 
        for (slot = 0; slot < 4; slot++) {
@@ -463,7 +463,7 @@ static int slots_valid(struct grip_mp *grip)
  * Returns whether the multiport was placed into digital mode and
  * able to communicate its state successfully.
  */
+
 static int multiport_init(struct grip_mp *grip)
 {
        int dig_mode, initialized = 0, tries = 0;
@@ -481,7 +481,7 @@ static int multiport_init(struct grip_mp *grip)
                dbg("multiport_init(): unable to achieve digital mode.\n");
                return 0;
        }
-       
+
        /* Get packets, store multiport state, and check state's validity */
        for (tries = 0; tries < 4096; tries++) {
                if ( slots_valid(grip) ) {
@@ -520,9 +520,9 @@ static void report_slot(struct grip_mp *grip, int slot)
 }
 
 /*
- * Get the multiport state.  
+ * Get the multiport state.
  */
+
 static void get_and_report_mp_state(struct grip_mp *grip)
 {
        int i, npkts, flags;
@@ -538,7 +538,7 @@ static void get_and_report_mp_state(struct grip_mp *grip)
                        break;
        }
 
-       for (i = 0; i < 4; i++)      
+       for (i = 0; i < 4; i++)
                if (grip->dirty[i])
                        report_slot(grip, i);
 }
@@ -546,7 +546,7 @@ static void get_and_report_mp_state(struct grip_mp *grip)
 /*
  * Called when a joystick device file is opened
  */
+
 static int grip_open(struct input_dev *dev)
 {
        struct grip_mp *grip = dev->private;
@@ -607,7 +607,7 @@ static void register_slot(int slot, struct grip_mp *grip)
 /*
  * Repeatedly polls the multiport and generates events.
  */
+
 static void grip_timer(unsigned long private)
 {
        struct grip_mp *grip = (void*) private;
index 456e199..cfe8c6b 100644 (file)
@@ -45,7 +45,7 @@ MODULE_LICENSE("GPL");
 #define GUILLEMOT_MAX_LENGTH   17      /* 17 bytes */
 #define GUILLEMOT_REFRESH_TIME HZ/50   /* 20 ms */
 
-static short guillemot_abs_pad[] = 
+static short guillemot_abs_pad[] =
        { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, -1 };
 
 static short guillemot_btn_pad[] =
@@ -160,7 +160,7 @@ static int guillemot_open(struct input_dev *dev)
 {
        struct guillemot *guillemot = dev->private;
        if (!guillemot->used++)
-               mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME); 
+               mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME);
        return 0;
 }
 
@@ -211,7 +211,7 @@ static void guillemot_connect(struct gameport *gameport, struct gameport_dev *de
        if (!guillemot_type[i].name) {
                printk(KERN_WARNING "guillemot.c: Unknown joystick on %s. [ %02x%02x:%04x, ver %d.%02d ]\n",
                        gameport->phys, data[12], data[13], data[11], data[14], data[15]);
-               goto fail2;     
+               goto fail2;
        }
 
        sprintf(guillemot->phys, "%s/input0", gameport->phys);
@@ -237,7 +237,7 @@ static void guillemot_connect(struct gameport *gameport, struct gameport_dev *de
                guillemot->dev.absmax[t] = 255;
        }
 
-       if (guillemot->type->hat) 
+       if (guillemot->type->hat)
                for (i = 0; i < 2; i++) {
                        t = ABS_HAT0X + i;
                        set_bit(t, guillemot->dev.absbit);
index 8b01957..2e964e5 100644 (file)
@@ -17,7 +17,7 @@ config JOYSTICK_IFORCE_USB
        depends on JOYSTICK_IFORCE && (JOYSTICK_IFORCE=m || USB=y) && USB
        help
          Say Y here if you have an I-Force joystick or steering wheel
-         connected to your USB port. 
+         connected to your USB port.
 
 config JOYSTICK_IFORCE_232
        bool "I-Force Serial joysticks and wheels"
index 96a0771..17ae42b 100644 (file)
@@ -7,14 +7,14 @@
 # Goal definition
 iforce-objs    := iforce-ff.o iforce-main.o iforce-packets.o
 
-obj-$(CONFIG_JOYSTICK_IFORCE)  += iforce.o 
+obj-$(CONFIG_JOYSTICK_IFORCE)  += iforce.o
 
 ifeq ($(CONFIG_JOYSTICK_IFORCE_232),y)
-       iforce-objs += iforce-serio.o 
+       iforce-objs += iforce-serio.o
 endif
 
 ifeq ($(CONFIG_JOYSTICK_IFORCE_USB),y)
-       iforce-objs += iforce-usb.o 
+       iforce-objs += iforce-usb.o
 endif
 
 EXTRA_CFLAGS = -Werror-implicit-function-declaration
index 267f92f..4678b6d 100644 (file)
@@ -195,7 +195,7 @@ 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 
+ * 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)
@@ -372,7 +372,7 @@ int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int
        int core_err = 0;
 
        if (!is_update || need_period_modifier(iforce, effect)) {
-               param1_err = make_period_modifier(iforce, mod1_chunk, 
+               param1_err = make_period_modifier(iforce, mod1_chunk,
                        is_update,
                        effect->u.periodic.magnitude, effect->u.periodic.offset,
                        effect->u.periodic.period, effect->u.periodic.phase);
index c53e61a..71cb7db 100644 (file)
@@ -166,7 +166,7 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
        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;
@@ -273,7 +273,7 @@ static int iforce_flush(struct input_dev *dev, struct file *file)
 
                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);
 
index 0c37044..58728eb 100644 (file)
@@ -56,7 +56,7 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
        int empty;
        int head, tail;
        unsigned long flags;
-                       
+
 /*
  * Update head and tail of xmit buffer
  */
@@ -108,7 +108,7 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
                break;
 #endif
 #ifdef CONFIG_JOYSTICK_IFORCE_USB
-               case IFORCE_USB: 
+               case IFORCE_USB:
 
                if (iforce->usbdev && empty &&
                        !test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)) {
index e17c2e8..0665b54 100644 (file)
@@ -62,7 +62,7 @@ again:
                cs ^= iforce->xmit.buf[iforce->xmit.tail];
                XMIT_INC(iforce->xmit.tail, 1);
        }
-       
+
        serio_write(iforce->serio, cs);
 
        if (test_and_clear_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags))
index 5b90252..a8586ab 100644 (file)
@@ -141,7 +141,7 @@ struct iforce {
        struct circ_buf xmit;
        unsigned char xmit_data[XMIT_SIZE];
        long xmit_flags[1];
-       
+
                                        /* Force Feedback */
        wait_queue_head_t wait;
        struct resource device_memory;
index adc20ac..b2d7cad 100644 (file)
@@ -63,7 +63,7 @@ struct interact {
        char phys[32];
 };
 
-static short interact_abs_hhfx[] = 
+static short interact_abs_hhfx[] =
        { ABS_RX, ABS_RY, ABS_X, ABS_Y, ABS_HAT0X, ABS_HAT0Y, -1 };
 static short interact_abs_pp8d[] =
        { ABS_X, ABS_Y, -1 };
@@ -166,7 +166,7 @@ static void interact_timer(unsigned long private)
                        case INTERACT_TYPE_PP8D:
 
                                for (i = 0; i < 2; i++)
-                                       input_report_abs(dev, interact_abs_pp8d[i], 
+                                       input_report_abs(dev, interact_abs_pp8d[i],
                                                ((data[0] >> ((i << 1) + 20)) & 1)  - ((data[0] >> ((i << 1) + 21)) & 1));
 
                                for (i = 0; i < 8; i++)
@@ -190,7 +190,7 @@ static int interact_open(struct input_dev *dev)
 {
        struct interact *interact = dev->private;
        if (!interact->used++)
-               mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME);   
+               mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME);
        return 0;
 }
 
@@ -242,7 +242,7 @@ static void interact_connect(struct gameport *gameport, struct gameport_dev *dev
        if (!interact_type[i].length) {
                printk(KERN_WARNING "interact.c: Unknown joystick on %s. [len %d d0 %08x d1 %08x i2 %08x]\n",
                        gameport->phys, i, data[0], data[1], data[2]);
-               goto fail2;     
+               goto fail2;
        }
 
        sprintf(interact->phys, "%s/input0", gameport->phys);
index 9f3bed2..15962a6 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -63,7 +63,7 @@ static void __devinit joydump_connect(struct gameport *gameport, struct gameport
                printk(KERN_INFO "joydump: | Raw mode not available - trying cooked.    |\n");
 
                if (gameport_open(gameport, dev, GAMEPORT_MODE_COOKED)) {
-                       
+
                        printk(KERN_INFO "joydump: | Cooked not available either. Failing.      |\n");
                        printk(KERN_INFO "joydump: `-------------------- END -------------------'\n");
                        return;
index 992511d..f326299 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -159,7 +159,7 @@ static void magellan_connect(struct serio *serio, struct serio_dev *dev)
 
        memset(magellan, 0, sizeof(struct magellan));
 
-       magellan->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);     
+       magellan->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
        for (i = 0; i < 9; i++)
                set_bit(magellan_buttons[i], magellan->dev.keybit);
@@ -181,7 +181,7 @@ static void magellan_connect(struct serio *serio, struct serio_dev *dev)
        magellan->dev.id.vendor = SERIO_MAGELLAN;
        magellan->dev.id.product = 0x0001;
        magellan->dev.id.version = 0x0100;
-       
+
        serio->private = magellan;
 
        if (serio_open(serio, dev)) {
index af8263e..084643d 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -176,19 +176,19 @@ static int sw_read_packet(struct gameport *gameport, unsigned char *buf, int len
                                buf[i] = v >> 5;                /* Store it */
                        i++;                                    /* Advance index */
                        bitout = strobe;                        /* Extend timeout for next bit */
-               } 
+               }
 
                if (kick && (~v & u & 0x01)) {                  /* Falling edge on axis 0 */
                        sched = kick;                           /* Schedule second trigger */
                        kick = 0;                               /* Don't schedule next time on falling edge */
                        pending = 1;                            /* Mark schedule */
-               } 
+               }
 
                if (pending && sched < 0 && (i > -SW_END)) {    /* Second trigger time */
                        gameport_trigger(gameport);             /* Trigger */
                        bitout = start;                         /* Long bit timeout */
                        pending = 0;                            /* Unmark schedule */
-                       timeout = 0;                            /* Switch from global to bit timeouts */ 
+                       timeout = 0;                            /* Switch from global to bit timeouts */
                }
        }
 
@@ -482,14 +482,14 @@ static int sw_read(struct sw *sw)
        sw_read_packet(sw->gameport, buf, SW_LENGTH, i);                        /* Read ID packet, this initializes the stick */
 
        sw->fail = SW_FAIL;
-       
+
        return -1;
 }
 
 static void sw_timer(unsigned long private)
 {
        struct sw *sw = (void *) private;
-       
+
        sw->reads++;
        if (sw_read(sw)) sw->bads++;
        mod_timer(&sw->timer, jiffies + SW_REFRESH);
@@ -653,7 +653,7 @@ static void sw_connect(struct gameport *gameport, struct gameport_dev *dev)
                                case 60:
                                        sw->number++;
                                case 45:                                /* Ambiguous packet length */
-                                       if (j <= 40) {                  /* ID length less or eq 40 -> FSP */    
+                                       if (j <= 40) {                  /* ID length less or eq 40 -> FSP */
                                case 43:
                                                sw->type = SW_ID_FSP;
                                                break;
index 4e288b5..eb5b6f7 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -59,8 +59,8 @@ MODULE_LICENSE("GPL");
 
 static int spaceball_axes[] = { ABS_X, ABS_Z, ABS_Y, ABS_RX, ABS_RZ, ABS_RY };
 static char *spaceball_names[] = {
-       "?", "SpaceTec SpaceBall 1003", "SpaceTec SpaceBall 2003", "SpaceTec SpaceBall 2003B", 
-       "SpaceTec SpaceBall 2003C", "SpaceTec SpaceBall 3003", "SpaceTec SpaceBall SpaceController", 
+       "?", "SpaceTec SpaceBall 1003", "SpaceTec SpaceBall 2003", "SpaceTec SpaceBall 2003B",
+       "SpaceTec SpaceBall 2003C", "SpaceTec SpaceBall 3003", "SpaceTec SpaceBall SpaceController",
        "SpaceTec SpaceBall 3003C", "SpaceTec SpaceBall 4000FLX", "SpaceTec SpaceBall 4000FLX Lefty" };
 
 /*
@@ -96,7 +96,7 @@ static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs
                case 'D':                                       /* Ball data */
                        if (spaceball->idx != 15) return;
                        for (i = 0; i < 6; i++)
-                               input_report_abs(dev, spaceball_axes[i], 
+                               input_report_abs(dev, spaceball_axes[i],
                                        (__s16)((data[2 * i + 3] << 8) | data[2 * i + 2]));
                        break;
 
@@ -216,7 +216,7 @@ static void spaceball_connect(struct serio *serio, struct serio_dev *dev)
                return;
        memset(spaceball, 0, sizeof(struct spaceball));
 
-       spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);    
+       spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
        switch (id) {
                case SPACEBALL_4000FLX:
@@ -224,7 +224,7 @@ static void spaceball_connect(struct serio *serio, struct serio_dev *dev)
                        spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_9);
                        spaceball->dev.keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
                default:
-                       spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) 
+                       spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
                                | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8);
                case SPACEBALL_3003C:
                        spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
@@ -251,7 +251,7 @@ static void spaceball_connect(struct serio *serio, struct serio_dev *dev)
        spaceball->dev.id.vendor = SERIO_SPACEBALL;
        spaceball->dev.id.product = id;
        spaceball->dev.id.version = 0x0100;
-       
+
        serio->private = spaceball;
 
        if (serio_open(serio, dev)) {
index 593dcac..00da66c 100644 (file)
@@ -2,7 +2,7 @@
  * $Id: spaceorb.c,v 1.15 2002/01/22 20:29:19 vojtech Exp $
  *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
- * 
+ *
  *  Based on the work of:
  *     David Thompson
  */
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -67,7 +67,7 @@ struct spaceorb {
 static unsigned char spaceorb_xor[] = "SpaceWare";
 
 static unsigned char *spaceorb_errors[] = { "EEPROM storing 0 failed", "Receive queue overflow", "Transmit queue timeout",
-               "Bad packet", "Power brown-out", "EEPROM checksum error", "Hardware fault" }; 
+               "Bad packet", "Power brown-out", "EEPROM checksum error", "Hardware fault" };
 
 /*
  * spaceorb_process_packet() decodes packets the driver receives from the
@@ -99,7 +99,7 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r
 
                case 'D':                               /* Ball + button data */
                        if (spaceorb->idx != 12) return;
-                       for (i = 0; i < 9; i++) spaceorb->data[i+2] ^= spaceorb_xor[i]; 
+                       for (i = 0; i < 9; i++) spaceorb->data[i+2] ^= spaceorb_xor[i];
                        axes[0] = ( data[2]      << 3) | (data[ 3] >> 4);
                        axes[1] = ((data[3] & 0x0f) << 6) | (data[ 4] >> 1);
                        axes[2] = ((data[4] & 0x01) << 9) | (data[ 5] << 2) | (data[4] >> 5);
@@ -174,7 +174,7 @@ static void spaceorb_connect(struct serio *serio, struct serio_dev *dev)
                return;
        memset(spaceorb, 0, sizeof(struct spaceorb));
 
-       spaceorb->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);     
+       spaceorb->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
        for (i = 0; i < 6; i++)
                set_bit(spaceorb_buttons[i], spaceorb->dev.keybit);
@@ -198,7 +198,7 @@ static void spaceorb_connect(struct serio *serio, struct serio_dev *dev)
        spaceorb->dev.id.vendor = SERIO_SPACEORB;
        spaceorb->dev.id.product = 0x0001;
        spaceorb->dev.id.version = 0x0100;
-       
+
        serio->private = spaceorb;
 
        if (serio_open(serio, dev)) {
index f68d3ad..ce9be45 100644 (file)
@@ -147,7 +147,7 @@ static void stinger_connect(struct serio *serio, struct serio_dev *dev)
 
        memset(stinger, 0, sizeof(struct stinger));
 
-       stinger->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);      
+       stinger->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
        stinger->dev.keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | \
                                           BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | \
                                           BIT(BTN_START) | BIT(BTN_SELECT);
@@ -164,8 +164,8 @@ static void stinger_connect(struct serio *serio, struct serio_dev *dev)
        stinger->dev.id.version = 0x0100;
 
        for (i = 0; i < 2; i++) {
-               stinger->dev.absmax[ABS_X+i] =  64;     
-               stinger->dev.absmin[ABS_X+i] = -64;     
+               stinger->dev.absmax[ABS_X+i] =  64;
+               stinger->dev.absmin[ABS_X+i] = -64;
                stinger->dev.absflat[ABS_X+i] = 4;
        }
 
index 93efe75..6ed46ec 100644 (file)
@@ -4,7 +4,7 @@
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  *
  *   Based on the work of:
- *     Trystan Larey-Williams 
+ *     Trystan Larey-Williams
  */
 
 /*
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -58,7 +58,7 @@ MODULE_LICENSE("GPL");
 #define TMDC_BYTE_REV          11
 #define TMDC_BYTE_DEF          12
 
-#define TMDC_ABS               7       
+#define TMDC_ABS               7
 #define TMDC_ABS_HAT           4
 #define TMDC_BTN               16
 
@@ -104,7 +104,7 @@ struct tmdc {
        unsigned char btno[2][4];
        int used;
        int reads;
-       int bads;       
+       int bads;
        unsigned char exists;
 };
 
@@ -127,7 +127,7 @@ static int tmdc_read_packet(struct gameport *gameport, unsigned char data[2][TMD
 
        local_irq_save(flags);
        gameport_trigger(gameport);
-       
+
        w = gameport_read(gameport) >> 4;
 
        do {
@@ -148,7 +148,7 @@ static int tmdc_read_packet(struct gameport *gameport, unsigned char data[2][TMD
                                }
                                data[k][i[k]] |= (~v & 1) << (j[k]++ - 1);      /* Data bit */
                        }
-                       t[k]--; 
+                       t[k]--;
                }
        } while (t[0] > 0 || t[1] > 0);
 
@@ -175,7 +175,7 @@ static void tmdc_timer(unsigned long private)
                bad = 1;
        else
 
-       for (j = 0; j < 2; j++) 
+       for (j = 0; j < 2; j++)
                if (r & (1 << j) & tmdc->exists) {
 
                        if (data[j][TMDC_BYTE_ID] != tmdc->mode[j]) {
@@ -227,7 +227,7 @@ static int tmdc_open(struct input_dev *dev)
 {
        struct tmdc *tmdc = dev->private;
        if (!tmdc->used++)
-               mod_timer(&tmdc->timer, jiffies + TMDC_REFRESH_TIME);   
+               mod_timer(&tmdc->timer, jiffies + TMDC_REFRESH_TIME);
        return 0;
 }
 
@@ -356,7 +356,7 @@ static void tmdc_disconnect(struct gameport *gameport)
        struct tmdc *tmdc = gameport->private;
        int i;
        for (i = 0; i < 2; i++)
-               if (tmdc->exists & (1 << i)) 
+               if (tmdc->exists & (1 << i))
                        input_unregister_device(tmdc->dev + i);
        gameport_close(gameport);
        kfree(tmdc);
index 8cf86aa..123ff5f 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -65,7 +65,7 @@ __obsolete_setup("tgfx_3=");
 
 #define TGFX_TRIGGER           0x08
 #define TGFX_UP                        0x10
-#define TGFX_DOWN              0x20    
+#define TGFX_DOWN              0x20
 #define TGFX_LEFT              0x40
 #define TGFX_RIGHT             0x80
 
@@ -126,7 +126,7 @@ static int tgfx_open(struct input_dev *dev)
         if (!tgfx->used++) {
                parport_claim(tgfx->pd);
                parport_write_control(tgfx->pd->port, 0x04);
-                mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME); 
+                mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME);
        }
         return 0;
 }
@@ -173,7 +173,7 @@ static struct tgfx __init *tgfx_probe(int *config, int nargs)
        memset(tgfx, 0, sizeof(struct tgfx));
 
        tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
-               
+
        parport_put_port(pp);
 
        if (!tgfx->pd) {
@@ -210,7 +210,7 @@ static struct tgfx __init *tgfx_probe(int *config, int nargs)
                        tgfx->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
 
                        for (j = 0; j < config[i+1]; j++)
-                               set_bit(tgfx_buttons[j], tgfx->dev[i].keybit); 
+                               set_bit(tgfx_buttons[j], tgfx->dev[i].keybit);
 
                        tgfx->dev[i].absmin[ABS_X] = -1; tgfx->dev[i].absmax[ABS_X] = 1;
                        tgfx->dev[i].absmin[ABS_Y] = -1; tgfx->dev[i].absmax[ABS_Y] = 1;
@@ -225,7 +225,7 @@ static struct tgfx __init *tgfx_probe(int *config, int nargs)
                kfree(tgfx);
                return NULL;
         }
-               
+
        return tgfx;
 }
 
@@ -245,7 +245,7 @@ void __exit tgfx_exit(void)
 {
        int i, j;
 
-       for (i = 0; i < 3; i++) 
+       for (i = 0; i < 3; i++)
                if (tgfx_base[i]) {
                        for (j = 0; j < 7; j++)
                                if (tgfx_base[i]->sticks & (1 << j))
index 8a98be1..eb5c935 100644 (file)
@@ -58,6 +58,9 @@
 #include <linux/serio.h>
 #include <linux/init.h>
 
+MODULE_DESCRIPTION("Handykey Twiddler keyboard as a joystick driver");
+MODULE_LICENSE("GPL");
+
 /*
  * Constants.
  */
@@ -142,7 +145,7 @@ static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs
  * packet processing routine.
  */
 
-static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struc pt_regs *regs)
+static irqreturn_t twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
        struct twidjoy *twidjoy = serio->private;
 
@@ -153,7 +156,7 @@ static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned
        if ((data & 0x80) == 0)
                twidjoy->idx = 0;       /* this byte starts a new packet */
        else if (twidjoy->idx == 0)
-               return;                 /* wrong MSB -- ignore this byte */
+               return IRQ_HANDLED;     /* wrong MSB -- ignore this byte */
 
        if (twidjoy->idx < TWIDJOY_MAX_LENGTH)
                twidjoy->data[twidjoy->idx++] = data;
@@ -163,7 +166,7 @@ static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned
                twidjoy->idx = 0;
        }
 
-       return;
+       return IRQ_HANDLED;
 }
 
 /*
@@ -208,7 +211,7 @@ static void twidjoy_connect(struct serio *serio, struct serio_dev *dev)
        twidjoy->dev.id.product = 0x0001;
        twidjoy->dev.id.version = 0x0100;
 
-       twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);      
+       twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
        for (bp = twidjoy_buttons; bp->bitmask; bp++) {
                for (i = 0; i < bp->bitmask; i++)
@@ -218,8 +221,8 @@ static void twidjoy_connect(struct serio *serio, struct serio_dev *dev)
        twidjoy->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
 
        for (i = 0; i < 2; i++) {
-               twidjoy->dev.absmax[ABS_X+i] =  50;     
-               twidjoy->dev.absmin[ABS_X+i] = -50;     
+               twidjoy->dev.absmax[ABS_X+i] =  50;
+               twidjoy->dev.absmin[ABS_X+i] = -50;
 
                /* TODO: arndt 20010708: Are these values appropriate? */
                twidjoy->dev.absfuzz[ABS_X+i] = 4;
index 426ce2d..32ec90e 100644 (file)
 /*
  * This program is free warftware; 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -44,7 +44,7 @@ MODULE_LICENSE("GPL");
  */
 
 #define WARRIOR_MAX_LENGTH     16
-static char warrior_lengths[] = { 0, 4, 12, 3, 4, 4, 0, 0 }; 
+static char warrior_lengths[] = { 0, 4, 12, 3, 4, 4, 0, 0 };
 static char *warrior_name = "Logitech WingMan Warrior";
 
 /*
@@ -114,7 +114,7 @@ static irqreturn_t warrior_interrupt(struct serio *serio,
                warrior->data[warrior->idx++] = data;
 
        if (warrior->idx == warrior->len) {
-               if (warrior->idx) warrior_process_packet(warrior, regs);        
+               if (warrior->idx) warrior_process_packet(warrior, regs);
                warrior->idx = 0;
                warrior->len = 0;
        }
@@ -152,7 +152,7 @@ static void warrior_connect(struct serio *serio, struct serio_dev *dev)
 
        memset(warrior, 0, sizeof(struct warrior));
 
-       warrior->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);        
+       warrior->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
        warrior->dev.keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
        warrior->dev.relbit[0] = BIT(REL_DIAL);
        warrior->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y);
@@ -168,24 +168,24 @@ static void warrior_connect(struct serio *serio, struct serio_dev *dev)
        warrior->dev.id.version = 0x0100;
 
        for (i = 0; i < 2; i++) {
-               warrior->dev.absmax[ABS_X+i] = -64;     
-               warrior->dev.absmin[ABS_X+i] =  64;     
-               warrior->dev.absflat[ABS_X+i] = 8;      
+               warrior->dev.absmax[ABS_X+i] = -64;
+               warrior->dev.absmin[ABS_X+i] =  64;
+               warrior->dev.absflat[ABS_X+i] = 8;
        }
 
-       warrior->dev.absmax[ABS_THROTTLE] = -112;       
-       warrior->dev.absmin[ABS_THROTTLE] =  112;       
+       warrior->dev.absmax[ABS_THROTTLE] = -112;
+       warrior->dev.absmin[ABS_THROTTLE] =  112;
 
        for (i = 0; i < 2; i++) {
-               warrior->dev.absmax[ABS_HAT0X+i] = -1;  
-               warrior->dev.absmin[ABS_HAT0X+i] =  1;  
+               warrior->dev.absmax[ABS_HAT0X+i] = -1;
+               warrior->dev.absmin[ABS_HAT0X+i] =  1;
        }
 
        warrior->dev.private = warrior;
-       
+
        serio->private = warrior;
 
-       if (serio_open(serio, dev)) { 
+       if (serio_open(serio, dev)) {
                kfree(warrior);
                return;
        }
index 36d3282..b724190 100644 (file)
@@ -62,7 +62,7 @@ config KEYBOARD_XTKBD
          Say Y here if you want to use the old IBM PC/XT keyboard (or
          compatible) on your system. This is only possible with a
          parallel port keyboard adapter, you cannot connect it to the
-         keyboard port on a PC that runs Linux. 
+         keyboard port on a PC that runs Linux.
 
          To compile this driver as a module, choose M here: the
          module will be called xtkbd.
@@ -92,19 +92,7 @@ config KEYBOARD_AMIGA
        depends on AMIGA && INPUT && INPUT_KEYBOARD
        help
          Say Y here if you are running Linux on any AMIGA and have a keyboard
-         attached.     
+         attached.
 
          To compile this driver as a module, choose M here: the
          module will be called amikbd.
-
-config KEYBOARD_98KBD
-       tristate "NEC PC-9800 Keyboard support"
-       depends on X86_PC9800 && INPUT && INPUT_KEYBOARD
-       select SERIO
-       help
-         Say Y here if you want to use the NEC PC-9801/PC-9821 keyboard (or
-         compatible) on your system. 
-
-         To compile this driver as a module, choose M here: the
-         module will be called 98kbd.
-
index 8714404..00ec1f8 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/workqueue.h>
-#include <linux/timer.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("AT and PS/2 keyboard driver");
@@ -173,22 +172,24 @@ struct atkbd {
        unsigned char keycode[512];
        struct input_dev dev;
        struct serio *serio;
-       struct timer_list timer;
+
        char name[64];
        char phys[32];
+       unsigned short id;
+       unsigned char set;
+       unsigned int translated:1;
+       unsigned int extra:1;
+       unsigned int write:1;
+
        unsigned char cmdbuf[4];
        unsigned char cmdcnt;
-       unsigned char set;
-       unsigned char extra;
-       unsigned char release;
-       int lastkey;
        volatile signed char ack;
        unsigned char emul;
-       unsigned short id;
-       unsigned char write;
-       unsigned char translated;
-       unsigned char resend;
-       unsigned char bat_xl;
+       unsigned int resend:1;
+       unsigned int release:1;
+       unsigned int bat_xl:1;
+       unsigned int enabled:1;
+
        unsigned int last;
        unsigned long time;
 };
@@ -248,6 +249,9 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
                goto out;
        }
 
+       if (!atkbd->enabled)
+               goto out;
+
        if (atkbd->translated) {
 
                if (atkbd->emul ||
@@ -284,7 +288,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
                        atkbd_report_key(&atkbd->dev, regs, KEY_HANJA, 3);
                        goto out;
                case ATKBD_RET_ERR:
-                       printk(KERN_WARNING "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
+                       printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
                        goto out;
        }
 
@@ -300,15 +304,20 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
                case ATKBD_KEY_NULL:
                        break;
                case ATKBD_KEY_UNKNOWN:
-                       printk(KERN_WARNING "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n",
-                               atkbd->release ? "released" : "pressed",
-                               atkbd->translated ? "translated" : "raw",
-                               atkbd->set, code, serio->phys);
-                       if (atkbd->translated && atkbd->set == 2 && code == 0x7a)
-                               printk(KERN_WARNING "atkbd.c: This is an XFree86 bug. It shouldn't access"
-                                       " hardware directly.\n");
-                       else
-                               printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x <keycode>' to make it known.\n",                                          code & 0x80 ? "e0" : "", code & 0x7f);
+                       if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) {
+                               printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, "
+                                      "like XFree86, might be trying access hardware directly.\n",
+                                      data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
+                       } else {
+                               printk(KERN_WARNING "atkbd.c: Unknown key %s "
+                                      "(%s set %d, code %#x on %s).\n",
+                                      atkbd->release ? "released" : "pressed",
+                                      atkbd->translated ? "translated" : "raw",
+                                      atkbd->set, code, serio->phys);
+                               printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x <keycode>' "
+                                      "to make it known.\n",
+                                      code & 0x80 ? "e0" : "", code & 0x7f);
+                       }
                        break;
                case ATKBD_SCR_1:
                        scroll = 1 - atkbd->release * 2;
@@ -745,6 +754,8 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
                atkbd->id = 0xab00;
        }
 
+       atkbd->enabled = 1;
+
        if (atkbd->extra) {
                atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
                sprintf(atkbd->name, "AT Set 2 Extra keyboard");
@@ -809,12 +820,12 @@ static int atkbd_reconnect(struct serio *serio)
                param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0)
                         | (test_bit(LED_NUML,    atkbd->dev.led) ? 2 : 0)
                         | (test_bit(LED_CAPSL,   atkbd->dev.led) ? 4 : 0);
-               
+
                if (atkbd_probe(atkbd))
                        return -1;
                if (atkbd->set != atkbd_set_3(atkbd))
                        return -1;
-               
+
                atkbd_enable(atkbd);
 
                if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
index eb5fe4d..859ed77 100644 (file)
@@ -139,7 +139,7 @@ static int dc_kbd_connect(struct maple_device *dev)
 
        kbd->dev.name = dev->product_name;
        kbd->dev.id.bustype = BUS_MAPLE;
-       
+
        input_register_device(&kbd->dev);
 
        maple_getcond_callback(dev, dc_kbd_callback, 1, MAPLE_FUNC_KEYBOARD);
index d2f7036..1bb8a57 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -148,7 +148,7 @@ static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int c
                case EV_LED:
 
                        sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
-                       sunkbd->serio->write(sunkbd->serio, 
+                       sunkbd->serio->write(sunkbd->serio,
                                (!!test_bit(LED_CAPSL, dev->led) << 3) | (!!test_bit(LED_SCROLLL, dev->led) << 2) |
                                (!!test_bit(LED_COMPOSE, dev->led) << 1) | !!test_bit(LED_NUML, dev->led));
                        return 0;
@@ -160,7 +160,7 @@ static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int c
                                case SND_CLICK:
                                        sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - value);
                                        return 0;
-       
+
                                case SND_BELL:
                                        sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - value);
                                        return 0;
@@ -210,7 +210,7 @@ static void sunkbd_reinit(void *data)
        wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
 
        sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
-       sunkbd->serio->write(sunkbd->serio, 
+       sunkbd->serio->write(sunkbd->serio,
                (!!test_bit(LED_CAPSL, sunkbd->dev.led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev.led) << 2) |
                (!!test_bit(LED_COMPOSE, sunkbd->dev.led) << 1) | !!test_bit(LED_NUML, sunkbd->dev.led));
        sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev.snd));
@@ -231,7 +231,7 @@ static void sunkbd_connect(struct serio *serio, struct serio_dev *dev)
 
        if ((serio->type & SERIO_PROTO) && (serio->type & SERIO_PROTO) != SERIO_SUNKBD)
                return;
-       
+
        if (!(sunkbd = kmalloc(sizeof(struct sunkbd), GFP_KERNEL)))
                return;
 
index 78847c6..56adfa1 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -43,7 +43,7 @@ MODULE_LICENSE("GPL");
 #define XTKBD_KEY      0x7f
 #define XTKBD_RELEASE  0x80
 
-static unsigned char xtkbd_keycode[256] = {     
+static unsigned char xtkbd_keycode[256] = {
          0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
         16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
         32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
@@ -98,7 +98,7 @@ void xtkbd_connect(struct serio *serio, struct serio_dev *dev)
                return;
 
        memset(xtkbd, 0, sizeof(struct xtkbd));
-       
+
        xtkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
 
        xtkbd->serio = serio;
index d31aaff..d3e5d84 100644 (file)
@@ -40,10 +40,6 @@ config INPUT_M68K_BEEP
        tristate "M68k Beeper support"
        depends on M68K && INPUT && INPUT_MISC
 
-config INPUT_98SPKR
-       tristate "PC-9800 Speaker support"
-       depends on X86_PC9800 && INPUT && INPUT_MISC
-
 config INPUT_UINPUT
        tristate "User level driver support"
        depends on INPUT && INPUT_MISC
index f06600f..830d1c3 100644 (file)
@@ -41,11 +41,11 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
                case SND_BELL: if (value) value = 1000;
                case SND_TONE: break;
                default: return -1;
-       } 
+       }
 
        if (value > 20 && value < 32767)
                count = PIT_TICK_RATE / value;
-       
+
        spin_lock_irqsave(&i8253_beep_lock, flags);
 
        if (count) {
index 6c5c08d..6d793ad 100644 (file)
@@ -53,11 +53,11 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in
                case SND_BELL: if (value) value = 1000;
                case SND_TONE: break;
                default: return -1;
-       } 
+       }
 
        if (value > 20 && value < 32767)
                count = 1193182 / value;
-       
+
        spin_lock_irqsave(&beep_lock, flags);
 
        /* EBUS speaker only has on/off state, the frequency does not
@@ -108,11 +108,11 @@ static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int
                case SND_BELL: if (value) value = 1000;
                case SND_TONE: break;
                default: return -1;
-       } 
+       }
 
        if (value > 20 && value < 32767)
                count = 1193182 / value;
-       
+
        spin_lock_irqsave(&beep_lock, flags);
 
        if (count) {
index cc8c05b..b86acf0 100644 (file)
@@ -18,7 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
- * 
+ *
  * Changes/Revisions:
  *     0.1     20/06/2002
  *             - first public version
@@ -68,7 +68,7 @@ static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *eff
 static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
 {
        return 0;
-}                                      
+}
 
 static int uinput_create_device(struct uinput_device *udev)
 {
@@ -123,7 +123,7 @@ static int uinput_open(struct inode *inode, struct file *file)
        memset(newinput, 0, sizeof(struct input_dev));
 
        newdev->dev = newinput;
-       
+
        file->private_data = newdev;
 
        return 0;
@@ -137,16 +137,16 @@ static int uinput_validate_absbits(struct input_dev *dev)
 {
        unsigned int cnt;
        int retval = 0;
-       
+
        for (cnt = 0; cnt < ABS_MAX; cnt++) {
-               if (!test_bit(cnt, dev->absbit)) 
+               if (!test_bit(cnt, dev->absbit))
                        continue;
-               
+
                if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */
                    (dev->absmax[cnt] <= dev->absmin[cnt])) {
-                       printk(KERN_DEBUG 
+                       printk(KERN_DEBUG
                                "%s: invalid abs[%02x] min:%d max:%d\n",
-                               UINPUT_NAME, cnt, 
+                               UINPUT_NAME, cnt,
                                dev->absmin[cnt], dev->absmax[cnt]);
                        retval = -EINVAL;
                        break;
@@ -154,7 +154,7 @@ static int uinput_validate_absbits(struct input_dev *dev)
 
                if ((dev->absflat[cnt] < dev->absmin[cnt]) ||
                    (dev->absflat[cnt] > dev->absmax[cnt])) {
-                       printk(KERN_DEBUG 
+                       printk(KERN_DEBUG
                                "%s: absflat[%02x] out of range: %d "
                                "(min:%d/max:%d)\n",
                                UINPUT_NAME, cnt, dev->absflat[cnt],
@@ -166,7 +166,7 @@ static int uinput_validate_absbits(struct input_dev *dev)
        return retval;
 }
 
-static int uinput_alloc_device(struct file *file, const char *buffer, size_t count)
+static int uinput_alloc_device(struct file *file, const char __user *buffer, size_t count)
 {
        struct uinput_user_dev  *user_dev;
        struct input_dev        *dev;
@@ -190,7 +190,7 @@ static int uinput_alloc_device(struct file *file, const char *buffer, size_t cou
                goto exit;
        }
 
-       if (NULL != dev->name) 
+       if (NULL != dev->name)
                kfree(dev->name);
 
        size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
@@ -226,10 +226,10 @@ exit:
        return retval;
 }
 
-static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
        struct uinput_device    *udev = file->private_data;
-       
+
        if (test_bit(UIST_CREATED, &(udev->state))) {
                struct input_event      ev;
 
@@ -243,11 +243,11 @@ static ssize_t uinput_write(struct file *file, const char *buffer, size_t count,
        return count;
 }
 
-static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
        struct uinput_device *udev = file->private_data;
        int retval = 0;
-       
+
        if (!test_bit(UIST_CREATED, &(udev->state)))
                return -ENODEV;
 
@@ -255,16 +255,16 @@ static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t
                return -EAGAIN;
 
        retval = wait_event_interruptible(udev->waitq,
-                       (udev->head != udev->tail) || 
+                       (udev->head != udev->tail) ||
                        !test_bit(UIST_CREATED, &(udev->state)));
-       
+
        if (retval)
                return retval;
 
        if (!test_bit(UIST_CREATED, &(udev->state)))
                return -ENODEV;
 
-       while ((udev->head != udev->tail) && 
+       while ((udev->head != udev->tail) &&
            (retval + sizeof(struct input_event) <= count)) {
                if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
                    sizeof(struct input_event))) return -EFAULT;
@@ -284,7 +284,7 @@ static unsigned int uinput_poll(struct file *file, poll_table *wait)
        if (udev->head != udev->tail)
                return POLLIN | POLLRDNORM;
 
-       return 0;                       
+       return 0;
 }
 
 static int uinput_burn_device(struct uinput_device *udev)
@@ -318,7 +318,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                case UI_DEV_CREATE:
                        retval = uinput_create_device(udev);
                        break;
-                       
+
                case UI_DEV_DESTROY:
                        retval = uinput_destroy_device(udev);
                        break;
@@ -330,7 +330,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        }
                        set_bit(arg, udev->dev->evbit);
                        break;
-                       
+
                case UI_SET_KEYBIT:
                        if (arg > KEY_MAX) {
                                retval = -EINVAL;
@@ -338,7 +338,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        }
                        set_bit(arg, udev->dev->keybit);
                        break;
-                       
+
                case UI_SET_RELBIT:
                        if (arg > REL_MAX) {
                                retval = -EINVAL;
@@ -346,7 +346,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        }
                        set_bit(arg, udev->dev->relbit);
                        break;
-                       
+
                case UI_SET_ABSBIT:
                        if (arg > ABS_MAX) {
                                retval = -EINVAL;
@@ -354,7 +354,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        }
                        set_bit(arg, udev->dev->absbit);
                        break;
-                       
+
                case UI_SET_MSCBIT:
                        if (arg > MSC_MAX) {
                                retval = -EINVAL;
@@ -362,7 +362,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        }
                        set_bit(arg, udev->dev->mscbit);
                        break;
-                       
+
                case UI_SET_LEDBIT:
                        if (arg > LED_MAX) {
                                retval = -EINVAL;
@@ -370,7 +370,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        }
                        set_bit(arg, udev->dev->ledbit);
                        break;
-                       
+
                case UI_SET_SNDBIT:
                        if (arg > SND_MAX) {
                                retval = -EINVAL;
@@ -378,7 +378,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        }
                        set_bit(arg, udev->dev->sndbit);
                        break;
-                       
+
                case UI_SET_FFBIT:
                        if (arg > FF_MAX) {
                                retval = -EINVAL;
@@ -386,7 +386,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        }
                        set_bit(arg, udev->dev->ffbit);
                        break;
-                       
+
                default:
                        retval = -EFAULT;
        }
index 17db090..1274cb6 100644 (file)
@@ -130,14 +130,3 @@ config MOUSE_VSXXXAA
          described in the source file). This driver should, in theory,
          also work with the digitizer DEC produced, but it isn't tested
          with that (I don't have the hardware yet).
-
-config MOUSE_PC9800
-       tristate "NEC PC-9800 busmouse"
-       depends on X86_PC9800 && INPUT && INPUT_MOUSE && ISA
-       help
-         Say Y here if you have NEC PC-9801/PC-9821 computer and want its
-         native mouse supported.
-
-         To compile this driver as a module, choose M here: the
-         module will be called 98busmouse.
-
index 57987f3..c030c08 100644 (file)
@@ -10,7 +10,6 @@ obj-$(CONFIG_MOUSE_INPORT)    += inport.o
 obj-$(CONFIG_MOUSE_LOGIBM)     += logibm.o
 obj-$(CONFIG_MOUSE_MAPLE)      += maplemouse.o
 obj-$(CONFIG_MOUSE_PC110PAD)   += pc110pad.o
-obj-$(CONFIG_MOUSE_PC9800)     += 98busmouse.o
 obj-$(CONFIG_MOUSE_PS2)                += psmouse.o
 obj-$(CONFIG_MOUSE_SERIAL)     += sermouse.o
 obj-$(CONFIG_MOUSE_VSXXXAA)    += vsxxxaa.o
index 846b5e8..0063af0 100644 (file)
 #include "psmouse.h"
 #include "logips2pp.h"
 
+/* Logitech mouse types */
+#define PS2PP_KIND_WHEEL       1
+#define PS2PP_KIND_MX          2
+#define PS2PP_KIND_TP3         3
+
+/* Logitech mouse features */
+#define PS2PP_WHEEL            0x01
+#define PS2PP_HWHEEL           0x02
+#define PS2PP_SIDE_BTN         0x04
+#define PS2PP_EXTRA_BTN                0x08
+#define PS2PP_TASK_BTN         0x10
+#define PS2PP_NAV_BTN          0x20
+
+struct ps2pp_info {
+       const int model;
+       unsigned const int kind;
+       unsigned const int features;
+};
+
 /*
  * Process a PS2++ or PS2T++ packet.
  */
@@ -63,7 +82,6 @@ void ps2pp_process_packet(struct psmouse *psmouse)
                packet[0] &= 0x0f;
                packet[1] = 0;
                packet[2] = 0;
-
        }
 }
 
@@ -76,18 +94,9 @@ void ps2pp_process_packet(struct psmouse *psmouse)
 
 static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command)
 {
-       unsigned char d;
-       int i;
-
-       if (psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11))
+       if (psmouse_sliced_command(psmouse, command))
                return -1;
 
-       for (i = 6; i >= 0; i -= 2) {
-               d = (command >> i) & 3;
-               if(psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
-                       return -1;
-       }
-
        if (psmouse_command(psmouse, param, PSMOUSE_CMD_POLL))
                return -1;
 
@@ -99,7 +108,7 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha
  * enabled if we do nothing to it. Of course I put this in because I want it
  * disabled :P
  * 1 - enabled (if previously disabled, also default)
- * 0/2 - disabled 
+ * 0/2 - disabled
  */
 
 static void ps2pp_set_smartscroll(struct psmouse *psmouse)
@@ -113,14 +122,11 @@ static void ps2pp_set_smartscroll(struct psmouse *psmouse)
        psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
        psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
 
-       if (psmouse_smartscroll == 1) 
-               param[0] = 1;
-       else
-       if (psmouse_smartscroll > 2)
-               return;
-
-       /* else leave param[0] == 0 to disable */
-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+       if (psmouse_smartscroll < 2) {
+               /* 0 - disabled, 1 - enabled */
+               param[0] = psmouse_smartscroll;
+               psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+       }
 }
 
 /*
@@ -138,133 +144,167 @@ void ps2pp_set_800dpi(struct psmouse *psmouse)
        psmouse_command(psmouse, &param, PSMOUSE_CMD_SETRES);
 }
 
+static struct ps2pp_info *get_model_info(unsigned char model)
+{
+       static struct ps2pp_info ps2pp_list[] = {
+               { 12,   0,                      PS2PP_SIDE_BTN},
+               { 13,   0,                      0 },
+               { 40,   0,                      PS2PP_SIDE_BTN },
+               { 41,   0,                      PS2PP_SIDE_BTN },
+               { 42,   0,                      PS2PP_SIDE_BTN },
+               { 43,   0,                      PS2PP_SIDE_BTN },
+               { 50,   0,                      0 },
+               { 51,   0,                      0 },
+               { 52,   PS2PP_KIND_WHEEL,       PS2PP_SIDE_BTN | PS2PP_WHEEL },
+               { 53,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
+               { 61,   PS2PP_KIND_MX,
+                               PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
+                               PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },      /* MX700 */
+               { 73,   0,                      PS2PP_SIDE_BTN },
+               { 75,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
+               { 76,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
+               { 80,   PS2PP_KIND_WHEEL,       PS2PP_SIDE_BTN | PS2PP_WHEEL },
+               { 81,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
+               { 83,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
+               { 88,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
+               { 96,   0,                      0 },
+               { 97,   PS2PP_KIND_TP3,         PS2PP_WHEEL | PS2PP_HWHEEL },
+               { 100,  PS2PP_KIND_MX,
+                               PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
+                               PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },      /* MX510 */
+               { 112,  PS2PP_KIND_MX,
+                               PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
+                               PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },      /* MX500 */
+               { 114,  PS2PP_KIND_MX,
+                               PS2PP_WHEEL | PS2PP_SIDE_BTN |
+                               PS2PP_TASK_BTN | PS2PP_EXTRA_BTN },     /* M310 */
+               { }
+       };
+       int i;
+
+       for (i = 0; ps2pp_list[i].model; i++)
+               if (model == ps2pp_list[i].model)
+                       return &ps2pp_list[i];
+       return NULL;
+}
+
 /*
- * Detect the exact model and features of a PS2++ or PS2T++ Logitech mouse or
- * touchpad.
+ * Set up input device's properties based on the detected mouse model.
  */
 
-static int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param)
+static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info)
 {
-       int i;
-       static struct _logips2_list {
-               const int model;
-               unsigned const int features;
-       } logips2pp_list [] = {
-               { 12,   PS2PP_4BTN},
-               { 13,   0 },
-               { 40,   PS2PP_4BTN },
-               { 41,   PS2PP_4BTN },
-               { 42,   PS2PP_4BTN },
-               { 43,   PS2PP_4BTN },
-               { 50,   0 },
-               { 51,   0 },
-               { 52,   PS2PP_4BTN | PS2PP_WHEEL },
-               { 53,   PS2PP_WHEEL },
-               { 61,   PS2PP_WHEEL | PS2PP_MX },       /* MX700 */
-               { 73,   PS2PP_4BTN },
-               { 75,   PS2PP_WHEEL },
-               { 76,   PS2PP_WHEEL },
-               { 80,   PS2PP_4BTN | PS2PP_WHEEL },
-               { 81,   PS2PP_WHEEL },
-               { 83,   PS2PP_WHEEL },
-               { 88,   PS2PP_WHEEL },
-               { 96,   0 },
-               { 97,   0 },
-               { 100 , PS2PP_WHEEL | PS2PP_MX },       /* MX510 */
-               { 112 , PS2PP_WHEEL | PS2PP_MX },       /* MX500 */
-               { 114 , PS2PP_WHEEL | PS2PP_MX | PS2PP_MX310 }, /* MX310 */
-               { }
-       };
+       if (model_info->features & PS2PP_SIDE_BTN)
+               set_bit(BTN_SIDE, psmouse->dev.keybit);
+
+       if (model_info->features & PS2PP_EXTRA_BTN)
+               set_bit(BTN_EXTRA, psmouse->dev.keybit);
 
-       psmouse->vendor = "Logitech";
-       psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
+       if (model_info->features & PS2PP_TASK_BTN)
+               set_bit(BTN_TASK, psmouse->dev.keybit);
 
-       if (param[1] < 3)
-               clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
-       if (param[1] < 2)
-               clear_bit(BTN_RIGHT, psmouse->dev.keybit);
+       if (model_info->features & PS2PP_NAV_BTN) {
+               set_bit(BTN_FORWARD, psmouse->dev.keybit);
+               set_bit(BTN_BACK, psmouse->dev.keybit);
+       }
 
-       psmouse->type = PSMOUSE_PS2;
+       if (model_info->features & PS2PP_WHEEL)
+               set_bit(REL_WHEEL, psmouse->dev.relbit);
 
-       for (i = 0; logips2pp_list[i].model; i++){
-               if (logips2pp_list[i].model == psmouse->model){
-                       psmouse->type = PSMOUSE_PS2PP;
-                       if (logips2pp_list[i].features & PS2PP_4BTN)
-                               set_bit(BTN_SIDE, psmouse->dev.keybit);
+       if (model_info->features & PS2PP_HWHEEL)
+               set_bit(REL_HWHEEL, psmouse->dev.relbit);
 
-                       if (logips2pp_list[i].features & PS2PP_WHEEL){
-                               set_bit(REL_WHEEL, psmouse->dev.relbit);
-                               psmouse->name = "Wheel Mouse";
-                       }
-                       if (logips2pp_list[i].features & PS2PP_MX) {
-                               set_bit(BTN_SIDE, psmouse->dev.keybit);
-                               set_bit(BTN_EXTRA, psmouse->dev.keybit);
-                               set_bit(BTN_TASK, psmouse->dev.keybit);
-                               if (!(logips2pp_list[i].features & PS2PP_MX310)){
-                                       set_bit(BTN_BACK, psmouse->dev.keybit);
-                                       set_bit(BTN_FORWARD, psmouse->dev.keybit);
-                               }
-                               psmouse->name = "MX Mouse";
-                       }
+       switch (model_info->kind) {
+               case PS2PP_KIND_WHEEL:
+                       psmouse->name = "Wheel Mouse";
+                       break;
+
+               case PS2PP_KIND_MX:
+                       psmouse->name = "MX Mouse";
+                       break;
+
+               case PS2PP_KIND_TP3:
+                       psmouse->name = "TouchPad 3";
                        break;
-               }
        }
+}
+
+
 /*
- * Do Logitech PS2++ / PS2T++ magic init.
+ * Logitech magic init. Detect whether the mouse is a Logitech one
+ * and its exact model and try turning on extended protocol for ones
+ * that support it.
  */
-       if (psmouse->type == PSMOUSE_PS2PP) {
 
-               if (psmouse->model == 97) { /* TouchPad 3 */
+int ps2pp_init(struct psmouse *psmouse, int set_properties)
+{
+       unsigned char param[4];
+       unsigned char protocol = PSMOUSE_PS2;
+       unsigned char model, buttons;
+       struct ps2pp_info *model_info;
+
+       param[0] = 0;
+       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+       psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+       psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+       psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+       param[1] = 0;
+       psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+
+       if (param[1] != 0) {
+               model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
+               buttons = param[1];
+               model_info = get_model_info(model);
 
-                       set_bit(REL_WHEEL, psmouse->dev.relbit);
-                       set_bit(REL_HWHEEL, psmouse->dev.relbit);
+/*
+ * Do Logitech PS2++ / PS2T++ magic init.
+ */
+               if (model == 97) { /* Touch Pad 3 */
 
-                       param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; /* Unprotect RAM */
+                       /* Unprotect RAM */
+                       param[0] = 0x11; param[1] = 0x04; param[2] = 0x68;
                        psmouse_command(psmouse, param, 0x30d1);
-                       param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; /* Enable features */
+                       /* Enable features */
+                       param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b;
                        psmouse_command(psmouse, param, 0x30d1);
-                       param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; /* Enable PS2++ */
+                       /* Enable PS2++ */
+                       param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3;
                        psmouse_command(psmouse, param, 0x30d1);
 
                        param[0] = 0;
                        if (!psmouse_command(psmouse, param, 0x13d1) &&
-                               param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
-                               psmouse->name = "TouchPad 3";
-                               return PSMOUSE_PS2TPP;
+                           param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
+                               protocol = PSMOUSE_PS2TPP;
                        }
 
-               } else {
+               } else if (get_model_info(model) != NULL) {
 
                        param[0] = param[1] = param[2] = 0;
                        ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */
                        ps2pp_cmd(psmouse, param, 0xDB);
 
-                       if ((param[0] & 0x78) == 0x48 && (param[1] & 0xf3) == 0xc2 &&
-                               (param[2] & 3) == ((param[1] >> 2) & 3)) {
-                                       ps2pp_set_smartscroll(psmouse);
-                                       return PSMOUSE_PS2PP;
+                       if ((param[0] & 0x78) == 0x48 &&
+                           (param[1] & 0xf3) == 0xc2 &&
+                           (param[2] & 0x03) == ((param[1] >> 2) & 3)) {
+                               ps2pp_set_smartscroll(psmouse);
+                               protocol = PSMOUSE_PS2PP;
                        }
                }
-       }
 
-       return 0;
-}
+               if (set_properties) {
+                       psmouse->vendor = "Logitech";
+                       psmouse->model = model;
 
-/*
- * Logitech magic init.
- */
-int ps2pp_detect(struct psmouse *psmouse)
-{
-       unsigned char param[4];
+                       if (buttons < 3)
+                               clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
+                       if (buttons < 2)
+                               clear_bit(BTN_RIGHT, psmouse->dev.keybit);
 
-       param[0] = 0;
-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-       psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
-       psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
-       psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
-       param[1] = 0;
-       psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+                       if (model_info)
+                               ps2pp_set_model_properties(psmouse, model_info);
+               }
+       }
 
-       return param[1] != 0 ? ps2pp_detect_model(psmouse, param) : 0;
+       return protocol;
 }
 
index d5e05de..959743a 100644 (file)
 #ifndef _LOGIPS2PP_H
 #define _LOGIPS2PP_H
 
-#define PS2PP_4BTN     0x01
-#define PS2PP_WHEEL    0x02
-#define PS2PP_MX       0x04
-#define PS2PP_MX310    0x08
-
-struct psmouse;
 void ps2pp_process_packet(struct psmouse *psmouse);
 void ps2pp_set_800dpi(struct psmouse *psmouse);
-int ps2pp_detect(struct psmouse *psmouse);
+int ps2pp_init(struct psmouse *psmouse, int set_properties);
+
 #endif
index 3d4a300..0b38267 100644 (file)
@@ -43,9 +43,9 @@ int psmouse_smartscroll = 1;
 module_param_named(smartscroll, psmouse_smartscroll, bool, 0);
 MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
 
-unsigned int psmouse_resetafter;
+static unsigned int psmouse_resetafter;
 module_param_named(resetafter, psmouse_resetafter, uint, 0);
-MODULE_PARM_DESC(resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never).");
+MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
 
 __obsolete_setup("psmouse_noext");
 __obsolete_setup("psmouse_resolution=");
@@ -56,15 +56,22 @@ __obsolete_setup("psmouse_rate=");
 static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};
 
 /*
- * psmouse_process_packet() analyzes the PS/2 mouse packet contents and
- * reports relevant events to the input module.
+ * psmouse_process_byte() analyzes the PS/2 data stream and reports
+ * relevant events to the input module once full packet has arrived.
  */
 
-static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
+static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
 {
        struct input_dev *dev = &psmouse->dev;
        unsigned char *packet = psmouse->packet;
 
+       if (psmouse->pktcnt < 3 + (psmouse->type >= PSMOUSE_GENPS))
+               return PSMOUSE_GOOD_DATA;
+
+/*
+ * Full packet accumulated, process it
+ */
+
        input_regs(dev, regs);
 
 /*
@@ -112,6 +119,8 @@ static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs
        input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
 
        input_sync(dev);
+
+       return PSMOUSE_FULL_PACKET;
 }
 
 /*
@@ -123,6 +132,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
                unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
        struct psmouse *psmouse = serio->private;
+       psmouse_ret_t rc;
 
        if (psmouse->state == PSMOUSE_IGNORE)
                goto out;
@@ -180,7 +190,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
                if (psmouse->pktcnt == 2) {
                        if (psmouse->packet[1] == PSMOUSE_RET_ID) {
                                psmouse->state = PSMOUSE_IGNORE;
-                               serio_rescan(serio);
+                               serio_reconnect(serio);
                                goto out;
                        }
                        if (psmouse->type == PSMOUSE_SYNAPTICS) {
@@ -193,19 +203,32 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
                }
        }
 
-       if (psmouse->type == PSMOUSE_SYNAPTICS) {
-               /*
-                * The synaptics driver has its own resync logic,
-                * so it needs to receive all bytes one at a time.
-                */
-               synaptics_process_byte(psmouse, regs);
-               goto out;
-       }
+       rc = psmouse->protocol_handler(psmouse, regs);
 
-       if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) {
-               psmouse_process_packet(psmouse, regs);
-               psmouse->pktcnt = 0;
-               goto out;
+       switch (rc) {
+               case PSMOUSE_BAD_DATA:
+                       printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",
+                               psmouse->name, psmouse->phys, psmouse->pktcnt);
+                       psmouse->pktcnt = 0;
+
+                       if (++psmouse->out_of_sync == psmouse_resetafter) {
+                               psmouse->state = PSMOUSE_IGNORE;
+                               printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
+                               serio_reconnect(psmouse->serio);
+                       }
+                       break;
+
+               case PSMOUSE_FULL_PACKET:
+                       psmouse->pktcnt = 0;
+                       if (psmouse->out_of_sync) {
+                               psmouse->out_of_sync = 0;
+                               printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",
+                                       psmouse->name, psmouse->phys);
+                       }
+                       break;
+
+               case PSMOUSE_GOOD_DATA:
+                       break;
        }
 out:
        return IRQ_HANDLED;
@@ -288,6 +311,30 @@ int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command)
 }
 
 
+/*
+ * psmouse_sliced_command() sends an extended PS/2 command to the mouse
+ * using sliced syntax, understood by advanced devices, such as Logitech
+ * or Synaptics touchpads. The command is encoded as:
+ * 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
+ * is the command.
+ */
+int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command)
+{
+       int i;
+
+       if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
+               return -1;
+
+       for (i = 6; i >= 0; i -= 2) {
+               unsigned char d = (command >> i) & 3;
+               if (psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
+                       return -1;
+       }
+
+       return 0;
+}
+
+
 /*
  * psmouse_reset() resets the mouse into power-on state.
  */
@@ -363,31 +410,31 @@ static int im_explorer_detect(struct psmouse *psmouse)
  * the mouse may have.
  */
 
-static int psmouse_extensions(struct psmouse *psmouse)
+static int psmouse_extensions(struct psmouse *psmouse,
+                             unsigned int max_proto, int set_properties)
 {
        int synaptics_hardware = 0;
 
-       psmouse->vendor = "Generic";
-       psmouse->name = "Mouse";
-       psmouse->model = 0;
-
 /*
  * Try Synaptics TouchPad
  */
-       if (psmouse_max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) {
+       if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) {
                synaptics_hardware = 1;
-               psmouse->vendor = "Synaptics";
-               psmouse->name = "TouchPad";
 
-               if (psmouse_max_proto > PSMOUSE_IMEX) {
-                       if (synaptics_init(psmouse) == 0)
+               if (set_properties) {
+                       psmouse->vendor = "Synaptics";
+                       psmouse->name = "TouchPad";
+               }
+
+               if (max_proto > PSMOUSE_IMEX) {
+                       if (!set_properties || synaptics_init(psmouse) == 0)
                                return PSMOUSE_SYNAPTICS;
 /*
  * Some Synaptics touchpads can emulate extended protocols (like IMPS/2).
  * Unfortunately Logitech/Genius probes confuse some firmware versions so
  * we'll have to skip them.
  */
-                       psmouse_max_proto = PSMOUSE_IMEX;
+                       max_proto = PSMOUSE_IMEX;
                }
 /*
  * Make sure that touchpad is in relative mode, gestures (taps) are enabled
@@ -395,35 +442,46 @@ static int psmouse_extensions(struct psmouse *psmouse)
                synaptics_reset(psmouse);
        }
 
-       if (psmouse_max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) {
-               set_bit(BTN_EXTRA, psmouse->dev.keybit);
-               set_bit(BTN_SIDE, psmouse->dev.keybit);
-               set_bit(REL_WHEEL, psmouse->dev.relbit);
+       if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) {
+
+               if (set_properties) {
+                       set_bit(BTN_EXTRA, psmouse->dev.keybit);
+                       set_bit(BTN_SIDE, psmouse->dev.keybit);
+                       set_bit(REL_WHEEL, psmouse->dev.relbit);
+                       psmouse->vendor = "Genius";
+                       psmouse->name = "Wheel Mouse";
+               }
 
-               psmouse->vendor = "Genius";
-               psmouse->name = "Wheel Mouse";
                return PSMOUSE_GENPS;
        }
 
-       if (psmouse_max_proto > PSMOUSE_IMEX) {
-               int type = ps2pp_detect(psmouse);
-               if (type)
+       if (max_proto > PSMOUSE_IMEX) {
+               int type = ps2pp_init(psmouse, set_properties);
+               if (type > PSMOUSE_PS2)
                        return type;
        }
 
-       if (psmouse_max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) {
-               set_bit(REL_WHEEL, psmouse->dev.relbit);
+       if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse)) {
 
-               if (psmouse_max_proto >= PSMOUSE_IMEX &&
-                                       im_explorer_detect(psmouse)) {
+               if (set_properties) {
+                       set_bit(REL_WHEEL, psmouse->dev.relbit);
                        set_bit(BTN_SIDE, psmouse->dev.keybit);
                        set_bit(BTN_EXTRA, psmouse->dev.keybit);
+                       if (!psmouse->name)
+                               psmouse->name = "Explorer Mouse";
+               }
+
+               return PSMOUSE_IMEX;
+       }
+
+       if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) {
 
-                       psmouse->name = "Explorer Mouse";
-                       return PSMOUSE_IMEX;
+               if (set_properties) {
+                       set_bit(REL_WHEEL, psmouse->dev.relbit);
+                       if (!psmouse->name)
+                               psmouse->name = "Wheel Mouse";
                }
 
-               psmouse->name = "Wheel Mouse";
                return PSMOUSE_IMPS;
        }
 
@@ -473,12 +531,7 @@ static int psmouse_probe(struct psmouse *psmouse)
        if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS))
                printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", psmouse->serio->phys);
 
-/*
- * And here we try to determine if it has any extensions over the
- * basic PS/2 3-button mouse.
- */
-
-       return psmouse->type = psmouse_extensions(psmouse);
+       return 0;
 }
 
 /*
@@ -616,7 +669,6 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
        psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
        psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
        psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
-
        psmouse->state = PSMOUSE_CMD_MODE;
        psmouse->serio = serio;
        psmouse->dev.private = psmouse;
@@ -628,13 +680,21 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
                return;
        }
 
-       if (psmouse_probe(psmouse) <= 0) {
+       if (psmouse_probe(psmouse) < 0) {
                serio_close(serio);
                kfree(psmouse);
                serio->private = NULL;
                return;
        }
 
+       psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);
+       if (!psmouse->vendor)
+               psmouse->vendor = "Generic";
+       if (!psmouse->name)
+               psmouse->name = "Mouse";
+       if (!psmouse->protocol_handler)
+               psmouse->protocol_handler = psmouse_process_byte;
+
        sprintf(psmouse->devname, "%s %s %s",
                psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);
        sprintf(psmouse->phys, "%s/input0",
@@ -668,27 +728,24 @@ static int psmouse_reconnect(struct serio *serio)
 {
        struct psmouse *psmouse = serio->private;
        struct serio_dev *dev = serio->dev;
-       int old_type;
 
        if (!dev || !psmouse) {
                printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n");
                return -1;
        }
 
-       old_type = psmouse->type;
-
        psmouse->state = PSMOUSE_CMD_MODE;
-       psmouse->type = psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = 0;
+       psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = psmouse->out_of_sync = 0;
        if (psmouse->reconnect) {
               if (psmouse->reconnect(psmouse))
                        return -1;
-       } else if (psmouse_probe(psmouse) != old_type)
+       } else if (psmouse_probe(psmouse) < 0 ||
+                  psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0))
                return -1;
 
        /* ok, the device type (and capabilities) match the old one,
         * we can continue using it, complete intialization
         */
-       psmouse->type = old_type;
        psmouse_initialize(psmouse);
 
        if (psmouse->ptport) {
index e54841a..47fbc48 100644 (file)
 #define PSMOUSE_ACTIVATED      1
 #define PSMOUSE_IGNORE         2
 
+/* psmouse protocol handler return codes */
+typedef enum {
+       PSMOUSE_BAD_DATA,
+       PSMOUSE_GOOD_DATA,
+       PSMOUSE_FULL_PACKET
+} psmouse_ret_t;
+
 struct psmouse;
 
 struct psmouse_ptport {
@@ -45,6 +52,7 @@ struct psmouse {
        unsigned char type;
        unsigned char model;
        unsigned long last;
+       unsigned long out_of_sync;
        unsigned char state;
        char acking;
        volatile char ack;
@@ -52,6 +60,7 @@ struct psmouse {
        char devname[64];
        char phys[32];
 
+       psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs); 
        int (*reconnect)(struct psmouse *psmouse);
        void (*disconnect)(struct psmouse *psmouse);
 };
@@ -65,10 +74,10 @@ struct psmouse {
 #define PSMOUSE_SYNAPTICS      7
 
 int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
+int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
 int psmouse_reset(struct psmouse *psmouse);
 
 extern int psmouse_smartscroll;
 extern unsigned int psmouse_rate;
-extern unsigned int psmouse_resetafter;
 
 #endif /* _PSMOUSE_H */
index a182ce7..2bd152f 100644 (file)
  *     Synaptics communications functions
  ****************************************************************************/
 
-/*
- * Use the Synaptics extended ps/2 syntax to write a special command byte.
- * special command: 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
- *                  is the command. A 0xF3 or 0xE9 must follow (see synaptics_send_cmd
- *                  and synaptics_mode_cmd)
- */
-static int synaptics_special_cmd(struct psmouse *psmouse, unsigned char command)
-{
-       int i;
-
-       if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
-               return -1;
-
-       for (i = 6; i >= 0; i -= 2) {
-               unsigned char d = (command >> i) & 3;
-               if (psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
-                       return -1;
-       }
-
-       return 0;
-}
-
 /*
  * Send a command to the synpatics touchpad by special commands
  */
 static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param)
 {
-       if (synaptics_special_cmd(psmouse, c))
+       if (psmouse_sliced_command(psmouse, c))
                return -1;
        if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO))
                return -1;
@@ -84,7 +62,7 @@ static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode)
 {
        unsigned char param[1];
 
-       if (synaptics_special_cmd(psmouse, mode))
+       if (psmouse_sliced_command(psmouse, mode))
                return -1;
        param[0] = SYN_PS_SET_MODE2;
        if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE))
@@ -118,17 +96,31 @@ static int synaptics_capability(struct psmouse *psmouse)
 
        if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap))
                return -1;
-       priv->capabilities = (cap[0]<<16) | (cap[1]<<8) | cap[2];
+       priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2];
        priv->ext_cap = 0;
        if (!SYN_CAP_VALID(priv->capabilities))
                return -1;
 
-       if (SYN_EXT_CAP_REQUESTS(priv->capabilities)) {
+       /*
+        * Unless capExtended is set the rest of the flags should be ignored
+        */
+       if (!SYN_CAP_EXTENDED(priv->capabilities))
+               priv->capabilities = 0;
+
+       if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) {
                if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) {
                        printk(KERN_ERR "Synaptics claims to have extended capabilities,"
                               " but I'm not able to read them.");
-               } else
-                       priv->ext_cap = (cap[0]<<16) | (cap[1]<<8) | cap[2];
+               } else {
+                       priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2];
+
+                       /*
+                        * if nExtBtn is greater than 8 it should be considered
+                        * invalid and treated as 0
+                        */
+                       if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 8)
+                               priv->ext_cap &= 0xff0fff;
+               }
        }
        return 0;
 }
@@ -167,11 +159,12 @@ static void print_ident(struct synaptics_data *priv)
 
        if (SYN_CAP_EXTENDED(priv->capabilities)) {
                printk(KERN_INFO " Touchpad has extended capability bits\n");
-               if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
-                   SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) <= 8)
+               if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
                        printk(KERN_INFO " -> %d multi-buttons, i.e. besides standard buttons\n",
                               (int)(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)));
-               else if (SYN_CAP_FOUR_BUTTON(priv->capabilities))
+               if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
+                       printk(KERN_INFO " -> middle button\n");
+               if (SYN_CAP_FOUR_BUTTON(priv->capabilities))
                        printk(KERN_INFO " -> four buttons\n");
                if (SYN_CAP_MULTIFINGER(priv->capabilities))
                        printk(KERN_INFO " -> multifinger detection\n");
@@ -219,21 +212,12 @@ static int synaptics_set_mode(struct psmouse *psmouse, int mode)
 /*****************************************************************************
  *     Synaptics pass-through PS/2 port support
  ****************************************************************************/
-static int synaptics_pt_open(struct serio *port)
-{
-       return 0;
-}
-
-static void synaptics_pt_close(struct serio *port)
-{
-}
-
 static int synaptics_pt_write(struct serio *port, unsigned char c)
 {
        struct psmouse *parent = port->driver;
        char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
 
-       if (synaptics_special_cmd(parent, c))
+       if (psmouse_sliced_command(parent, c))
                return -1;
        if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE))
                return -1;
@@ -289,165 +273,11 @@ static void synaptics_pt_create(struct psmouse *psmouse)
        port->serio.name = "Synaptics pass-through";
        port->serio.phys = "synaptics-pt/serio0";
        port->serio.write = synaptics_pt_write;
-       port->serio.open = synaptics_pt_open;
-       port->serio.close = synaptics_pt_close;
        port->serio.driver = psmouse;
 
        port->activate = synaptics_pt_activate;
 }
 
-/*****************************************************************************
- *     Driver initialization/cleanup functions
- ****************************************************************************/
-
-static inline void set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat)
-{
-       dev->absmin[axis] = min;
-       dev->absmax[axis] = max;
-       dev->absfuzz[axis] = fuzz;
-       dev->absflat[axis] = flat;
-
-       set_bit(axis, dev->absbit);
-}
-
-static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
-{
-       set_bit(EV_ABS, dev->evbit);
-       set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
-       set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
-       set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
-       set_bit(ABS_TOOL_WIDTH, dev->absbit);
-
-       set_bit(EV_KEY, dev->evbit);
-       set_bit(BTN_TOUCH, dev->keybit);
-       set_bit(BTN_TOOL_FINGER, dev->keybit);
-       set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
-       set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
-
-       set_bit(BTN_LEFT, dev->keybit);
-       set_bit(BTN_RIGHT, dev->keybit);
-       set_bit(BTN_FORWARD, dev->keybit);
-       set_bit(BTN_BACK, dev->keybit);
-       if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) {
-               switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
-               default:
-                       /*
-                        * if nExtBtn is greater than 8 it should be considered
-                        * invalid and treated as 0
-                        */
-                       break;
-               case 8:
-                       set_bit(BTN_7, dev->keybit);
-                       set_bit(BTN_6, dev->keybit);
-               case 6:
-                       set_bit(BTN_5, dev->keybit);
-                       set_bit(BTN_4, dev->keybit);
-               case 4:
-                       set_bit(BTN_3, dev->keybit);
-                       set_bit(BTN_2, dev->keybit);
-               case 2:
-                       set_bit(BTN_1, dev->keybit);
-                       set_bit(BTN_0, dev->keybit);
-                       break;
-               }
-       }
-
-       clear_bit(EV_REL, dev->evbit);
-       clear_bit(REL_X, dev->relbit);
-       clear_bit(REL_Y, dev->relbit);
-}
-
-void synaptics_reset(struct psmouse *psmouse)
-{
-       /* reset touchpad back to relative mode, gestures enabled */
-       synaptics_mode_cmd(psmouse, 0);
-}
-
-static void synaptics_disconnect(struct psmouse *psmouse)
-{
-       synaptics_reset(psmouse);
-       kfree(psmouse->private);
-}
-
-static int synaptics_reconnect(struct psmouse *psmouse)
-{
-       struct synaptics_data *priv = psmouse->private;
-       struct synaptics_data old_priv = *priv;
-
-       if (!synaptics_detect(psmouse))
-               return -1;
-
-       if (synaptics_query_hardware(psmouse)) {
-               printk(KERN_ERR "Unable to query Synaptics hardware.\n");
-               return -1;
-       }
-
-       if (old_priv.identity != priv->identity ||
-           old_priv.model_id != priv->model_id ||
-           old_priv.capabilities != priv->capabilities ||
-           old_priv.ext_cap != priv->ext_cap)
-               return -1;
-
-       if (synaptics_set_mode(psmouse, 0)) {
-               printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
-               return -1;
-       }
-
-       return 0;
-}
-
-int synaptics_detect(struct psmouse *psmouse)
-{
-       unsigned char param[4];
-
-       param[0] = 0;
-
-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-       psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
-
-       return param[1] == 0x47;
-}
-
-int synaptics_init(struct psmouse *psmouse)
-{
-       struct synaptics_data *priv;
-
-       psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL);
-       if (!priv)
-               return -1;
-       memset(priv, 0, sizeof(struct synaptics_data));
-
-       if (synaptics_query_hardware(psmouse)) {
-               printk(KERN_ERR "Unable to query Synaptics hardware.\n");
-               goto init_fail;
-       }
-
-       if (synaptics_set_mode(psmouse, 0)) {
-               printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
-               goto init_fail;
-       }
-
-       priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
-
-       if (SYN_CAP_EXTENDED(priv->capabilities) && SYN_CAP_PASS_THROUGH(priv->capabilities))
-                       synaptics_pt_create(psmouse);
-
-       print_ident(priv);
-       set_input_params(&psmouse->dev, priv);
-
-       psmouse->disconnect = synaptics_disconnect;
-       psmouse->reconnect = synaptics_reconnect;
-
-       return 0;
-
- init_fail:
-       kfree(priv);
-       return -1;
-}
-
 /*****************************************************************************
  *     Functions to interpret the absolute mode packets
  ****************************************************************************/
@@ -471,17 +301,17 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data
 
                hw->left  = (buf[0] & 0x01) ? 1 : 0;
                hw->right = (buf[0] & 0x02) ? 1 : 0;
-               if (SYN_CAP_EXTENDED(priv->capabilities) &&
-                   (SYN_CAP_FOUR_BUTTON(priv->capabilities))) {
-                       hw->up = ((buf[3] & 0x01)) ? 1 : 0;
-                       if (hw->left)
-                               hw->up = !hw->up;
-                       hw->down = ((buf[3] & 0x02)) ? 1 : 0;
-                       if (hw->right)
-                               hw->down = !hw->down;
+
+               if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
+                       hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
+
+               if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
+                       hw->up   = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
+                       hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
                }
+
                if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
-                   ((buf[3] & 2) ? !hw->right : hw->right)) {
+                   ((buf[0] ^ buf[3]) & 0x02)) {
                        switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
                        default:
                                /*
@@ -490,17 +320,17 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data
                                 */
                                break;
                        case 8:
-                               hw->b7 = ((buf[5] & 0x08)) ? 1 : 0;
-                               hw->b6 = ((buf[4] & 0x08)) ? 1 : 0;
+                               hw->ext_buttons |= ((buf[5] & 0x08)) ? 0x80 : 0;
+                               hw->ext_buttons |= ((buf[4] & 0x08)) ? 0x40 : 0;
                        case 6:
-                               hw->b5 = ((buf[5] & 0x04)) ? 1 : 0;
-                               hw->b4 = ((buf[4] & 0x04)) ? 1 : 0;
+                               hw->ext_buttons |= ((buf[5] & 0x04)) ? 0x20 : 0;
+                               hw->ext_buttons |= ((buf[4] & 0x04)) ? 0x10 : 0;
                        case 4:
-                               hw->b3 = ((buf[5] & 0x02)) ? 1 : 0;
-                               hw->b2 = ((buf[4] & 0x02)) ? 1 : 0;
+                               hw->ext_buttons |= ((buf[5] & 0x02)) ? 0x08 : 0;
+                               hw->ext_buttons |= ((buf[4] & 0x02)) ? 0x04 : 0;
                        case 2:
-                               hw->b1 = ((buf[5] & 0x01)) ? 1 : 0;
-                               hw->b0 = ((buf[4] & 0x01)) ? 1 : 0;
+                               hw->ext_buttons |= ((buf[5] & 0x01)) ? 0x02 : 0;
+                               hw->ext_buttons |= ((buf[4] & 0x01)) ? 0x01 : 0;
                        }
                }
        } else {
@@ -525,6 +355,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
        struct synaptics_hw_state hw;
        int num_fingers;
        int finger_width;
+       int i;
 
        synaptics_parse_hw_state(psmouse->packet, priv, &hw);
 
@@ -570,32 +401,20 @@ static void synaptics_process_packet(struct psmouse *psmouse)
        input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
        input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
 
-       input_report_key(dev, BTN_LEFT,    hw.left);
-       input_report_key(dev, BTN_RIGHT,   hw.right);
-       input_report_key(dev, BTN_FORWARD, hw.up);
-       input_report_key(dev, BTN_BACK,    hw.down);
-       if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
-               switch(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
-               default:
-                       /*
-                        * if nExtBtn is greater than 8 it should be considered
-                        * invalid and treated as 0
-                        */
-                       break;
-               case 8:
-                       input_report_key(dev, BTN_7,       hw.b7);
-                       input_report_key(dev, BTN_6,       hw.b6);
-               case 6:
-                       input_report_key(dev, BTN_5,       hw.b5);
-                       input_report_key(dev, BTN_4,       hw.b4);
-               case 4:
-                       input_report_key(dev, BTN_3,       hw.b3);
-                       input_report_key(dev, BTN_2,       hw.b2);
-               case 2:
-                       input_report_key(dev, BTN_1,       hw.b1);
-                       input_report_key(dev, BTN_0,       hw.b0);
-                       break;
-               }
+       input_report_key(dev, BTN_LEFT, hw.left);
+       input_report_key(dev, BTN_RIGHT, hw.right);
+
+       if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
+               input_report_key(dev, BTN_MIDDLE, hw.middle);
+
+       if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
+               input_report_key(dev, BTN_FORWARD, hw.up);
+               input_report_key(dev, BTN_BACK, hw.down);
+       }
+
+       for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
+               input_report_key(dev, BTN_0 + i, hw.ext_buttons & (1 << i));
+
        input_sync(dev);
 }
 
@@ -607,6 +426,9 @@ static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned cha
        static unsigned char oldabs_mask[]      = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
        static unsigned char oldabs_rslt[]      = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
 
+       if (idx < 0 || idx > 4)
+               return 0;
+
        switch (pkt_type) {
                case SYN_NEWABS:
                case SYN_NEWABS_RELAXED:
@@ -637,7 +459,7 @@ static unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse)
        return SYN_NEWABS_STRICT;
 }
 
-void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
 {
        struct input_dev *dev = &psmouse->dev;
        struct synaptics_data *priv = psmouse->private;
@@ -645,11 +467,6 @@ void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
        input_regs(dev, regs);
 
        if (psmouse->pktcnt >= 6) { /* Full packet received */
-               if (priv->out_of_sync) {
-                       priv->out_of_sync = 0;
-                       printk(KERN_NOTICE "Synaptics driver resynced.\n");
-               }
-
                if (unlikely(priv->pkt_type == SYN_NEWABS))
                        priv->pkt_type = synaptics_detect_pkt_type(psmouse);
 
@@ -657,16 +474,142 @@ void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
                        synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet);
                else
                        synaptics_process_packet(psmouse);
-               psmouse->pktcnt = 0;
-
-       } else if (psmouse->pktcnt &&
-                  !synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type)) {
-               printk(KERN_WARNING "Synaptics driver lost sync at byte %d\n", psmouse->pktcnt);
-               psmouse->pktcnt = 0;
-               if (++priv->out_of_sync == psmouse_resetafter) {
-                       psmouse->state = PSMOUSE_IGNORE;
-                       printk(KERN_NOTICE "synaptics: issuing reconnect request\n");
-                       serio_reconnect(psmouse->serio);
-               }
+
+               return PSMOUSE_FULL_PACKET;
+       }
+
+       return synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type) ?
+               PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;
+}
+
+/*****************************************************************************
+ *     Driver initialization/cleanup functions
+ ****************************************************************************/
+static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
+{
+       int i;
+
+       set_bit(EV_ABS, dev->evbit);
+       input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
+       input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
+       input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
+       set_bit(ABS_TOOL_WIDTH, dev->absbit);
+
+       set_bit(EV_KEY, dev->evbit);
+       set_bit(BTN_TOUCH, dev->keybit);
+       set_bit(BTN_TOOL_FINGER, dev->keybit);
+       set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
+       set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
+
+       set_bit(BTN_LEFT, dev->keybit);
+       set_bit(BTN_RIGHT, dev->keybit);
+
+       if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
+               set_bit(BTN_MIDDLE, dev->keybit);
+
+       if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
+               set_bit(BTN_FORWARD, dev->keybit);
+               set_bit(BTN_BACK, dev->keybit);
+       }
+
+       for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
+               set_bit(BTN_0 + i, dev->keybit);
+
+       clear_bit(EV_REL, dev->evbit);
+       clear_bit(REL_X, dev->relbit);
+       clear_bit(REL_Y, dev->relbit);
+}
+
+void synaptics_reset(struct psmouse *psmouse)
+{
+       /* reset touchpad back to relative mode, gestures enabled */
+       synaptics_mode_cmd(psmouse, 0);
+}
+
+static void synaptics_disconnect(struct psmouse *psmouse)
+{
+       synaptics_reset(psmouse);
+       kfree(psmouse->private);
+}
+
+static int synaptics_reconnect(struct psmouse *psmouse)
+{
+       struct synaptics_data *priv = psmouse->private;
+       struct synaptics_data old_priv = *priv;
+
+       if (!synaptics_detect(psmouse))
+               return -1;
+
+       if (synaptics_query_hardware(psmouse)) {
+               printk(KERN_ERR "Unable to query Synaptics hardware.\n");
+               return -1;
+       }
+
+       if (old_priv.identity != priv->identity ||
+           old_priv.model_id != priv->model_id ||
+           old_priv.capabilities != priv->capabilities ||
+           old_priv.ext_cap != priv->ext_cap)
+               return -1;
+
+       if (synaptics_set_mode(psmouse, 0)) {
+               printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+int synaptics_detect(struct psmouse *psmouse)
+{
+       unsigned char param[4];
+
+       param[0] = 0;
+
+       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+       psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+
+       return param[1] == 0x47;
+}
+
+int synaptics_init(struct psmouse *psmouse)
+{
+       struct synaptics_data *priv;
+
+       psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL);
+       if (!priv)
+               return -1;
+       memset(priv, 0, sizeof(struct synaptics_data));
+
+       if (synaptics_query_hardware(psmouse)) {
+               printk(KERN_ERR "Unable to query Synaptics hardware.\n");
+               goto init_fail;
+       }
+
+       if (synaptics_set_mode(psmouse, 0)) {
+               printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
+               goto init_fail;
        }
+
+       priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
+
+       if (SYN_CAP_PASS_THROUGH(priv->capabilities))
+               synaptics_pt_create(psmouse);
+
+       print_ident(priv);
+       set_input_params(&psmouse->dev, priv);
+
+       psmouse->protocol_handler = synaptics_process_byte;
+       psmouse->disconnect = synaptics_disconnect;
+       psmouse->reconnect = synaptics_reconnect;
+
+       return 0;
+
+ init_fail:
+       kfree(priv);
+       return -1;
 }
+
+
index 69764de..eb64431 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef _SYNAPTICS_H
 #define _SYNAPTICS_H
 
-extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
 extern int synaptics_detect(struct psmouse *psmouse);
 extern int synaptics_init(struct psmouse *psmouse);
 extern void synaptics_reset(struct psmouse *psmouse);
@@ -44,13 +43,14 @@ extern void synaptics_reset(struct psmouse *psmouse);
 
 /* synaptics capability bits */
 #define SYN_CAP_EXTENDED(c)            ((c) & (1 << 23))
+#define SYN_CAP_MIDDLE_BUTTON(c)       ((c) & (1 << 18))
 #define SYN_CAP_PASS_THROUGH(c)                ((c) & (1 << 7))
 #define SYN_CAP_SLEEP(c)               ((c) & (1 << 4))
 #define SYN_CAP_FOUR_BUTTON(c)         ((c) & (1 << 3))
 #define SYN_CAP_MULTIFINGER(c)         ((c) & (1 << 1))
 #define SYN_CAP_PALMDETECT(c)          ((c) & (1 << 0))
 #define SYN_CAP_VALID(c)               ((((c) & 0x00ff00) >> 8) == 0x47)
-#define SYN_EXT_CAP_REQUESTS(c)                ((((c) & 0x700000) >> 20) == 1)
+#define SYN_EXT_CAP_REQUESTS(c)                (((c) & 0x700000) >> 20)
 #define SYN_CAP_MULTI_BUTTON_NO(ec)    (((ec) & 0x00f000) >> 12)
 
 /* synaptics modes query bits */
@@ -86,18 +86,12 @@ struct synaptics_hw_state {
        int y;
        int z;
        int w;
-       int left;
-       int right;
-       int up;
-       int down;
-       int b0;
-       int b1;
-       int b2;
-       int b3;
-       int b4;
-       int b5;
-       int b6;
-       int b7;
+       unsigned int left:1;
+       unsigned int right:1;
+       unsigned int middle:1;
+       unsigned int up:1;
+       unsigned int down:1;
+       unsigned char ext_buttons;
 };
 
 struct synaptics_data {
@@ -108,7 +102,6 @@ struct synaptics_data {
        unsigned long int identity;             /* Identification */
 
        /* Data for normal processing */
-       unsigned int out_of_sync;               /* # of packets out of sync */
        int old_w;                              /* Previous w value */
        unsigned char pkt_type;                 /* packet type - old, new, etc */
 };
index 5482e86..f266b7e 100644 (file)
@@ -2,6 +2,7 @@
  * Input driver to ExplorerPS/2 device driver module.
  *
  * Copyright (c) 1999-2002 Vojtech Pavlik
+ * Copyright (c) 2004      Dmitry Torokhov
  *
  * 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
@@ -47,15 +48,24 @@ static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y;
 module_param(yres, uint, 0);
 MODULE_PARM_DESC(yres, "Vertical screen resolution");
 
+struct mousedev_motion {
+       int dx, dy, dz;
+};
+
 struct mousedev {
        int exist;
        int open;
        int minor;
-       int misc;
        char name[16];
        wait_queue_head_t wait;
        struct list_head list;
        struct input_handle handle;
+
+       struct mousedev_motion packet;
+       unsigned long buttons;
+       unsigned int pkt_count;
+       int old_x[4], old_y[4];
+       unsigned int touch;
 };
 
 struct mousedev_list {
@@ -63,13 +73,10 @@ struct mousedev_list {
        struct mousedev *mousedev;
        struct list_head node;
        int dx, dy, dz;
-       int old_x[4], old_y[4];
        unsigned long buttons;
        signed char ps2[6];
        unsigned char ready, buffer, bufsiz;
        unsigned char mode, imexseq, impsseq;
-       unsigned int pkt_count;
-       unsigned char touch;
 };
 
 #define MOUSEDEV_SEQ_LEN       6
@@ -82,135 +89,157 @@ static struct input_handler mousedev_handler;
 static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
 static struct mousedev mousedev_mix;
 
-#define fx(i)  (list->old_x[(list->pkt_count - (i)) & 03])
-#define fy(i)  (list->old_y[(list->pkt_count - (i)) & 03])
+#define fx(i)  (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
+#define fy(i)  (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
 
-static void mousedev_abs_event(struct input_handle *handle, struct mousedev_list *list, unsigned int code, int value)
+static void mousedev_touchpad_event(struct mousedev *mousedev, unsigned int code, int value)
 {
-       int size;
-       int touchpad;
+       if (mousedev->touch) {
+               switch (code) {
+                       case ABS_X:
+                               fx(0) = value;
+                               if (mousedev->pkt_count >= 2)
+                                       mousedev->packet.dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
+                               break;
 
-       /* Ignore joysticks */
-       if (test_bit(BTN_TRIGGER, handle->dev->keybit))
-               return;
+                       case ABS_Y:
+                               fy(0) = value;
+                               if (mousedev->pkt_count >= 2)
+                                       mousedev->packet.dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
+                               break;
+               }
+       }
+}
 
-       touchpad = test_bit(BTN_TOOL_FINGER, handle->dev->keybit);
+static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value)
+{
+       int size;
 
        switch (code) {
                case ABS_X:
-                       if (touchpad) {
-                               if (list->touch) {
-                                       fx(0) = value;
-                                       if (list->pkt_count >= 2)
-                                               list->dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
-                               }
-                       } else {
-                               size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
-                               if (size == 0) size = xres;
-                               list->dx += (value * xres - list->old_x[0]) / size;
-                               list->old_x[0] += list->dx * size;
-                       }
+                       size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
+                       if (size == 0) size = xres;
+                       mousedev->packet.dx = (value * xres - mousedev->old_x[0]) / size;
+                       mousedev->old_x[0] = mousedev->packet.dx * size;
                        break;
+
                case ABS_Y:
-                       if (touchpad) {
-                               if (list->touch) {
-                                       fy(0) = value;
-                                       if (list->pkt_count >= 2)
-                                               list->dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
-                               }
-                       } else {
-                               size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
-                               if (size == 0) size = yres;
-                               list->dy -= (value * yres - list->old_y[0]) / size;
-                               list->old_y[0] -= list->dy * size;
-                       }
+                       size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
+                       if (size == 0) size = yres;
+                       mousedev->packet.dy = (value * yres - mousedev->old_y[0]) / size;
+                       mousedev->old_y[0] = mousedev->packet.dy * size;
                        break;
        }
 }
 
-static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
+static void mousedev_rel_event(struct mousedev *mousedev, unsigned int code, int value)
+{
+       switch (code) {
+               case REL_X:     mousedev->packet.dx += value; break;
+               case REL_Y:     mousedev->packet.dy -= value; break;
+               case REL_WHEEL: mousedev->packet.dz -= value; break;
+       }
+}
+
+static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int value)
+{
+       int index;
+
+       switch (code) {
+               case BTN_TOUCH:
+               case BTN_0:
+               case BTN_FORWARD:
+               case BTN_LEFT:          index = 0; break;
+               case BTN_STYLUS:
+               case BTN_1:
+               case BTN_RIGHT:         index = 1; break;
+               case BTN_2:
+               case BTN_STYLUS2:
+               case BTN_MIDDLE:        index = 2; break;
+               case BTN_3:
+               case BTN_BACK:
+               case BTN_SIDE:          index = 3; break;
+               case BTN_4:
+               case BTN_EXTRA:         index = 4; break;
+               default:                return;
+       }
+
+       if (value) {
+               set_bit(index, &mousedev->buttons);
+               set_bit(index, &mousedev_mix.buttons);
+       } else {
+               clear_bit(index, &mousedev->buttons);
+               clear_bit(index, &mousedev_mix.buttons);
+       }
+}
+
+static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_motion *packet)
 {
-       struct mousedev *mousedevs[3] = { handle->private, &mousedev_mix, NULL };
-       struct mousedev **mousedev = mousedevs;
        struct mousedev_list *list;
-       int index, wake;
-
-       while (*mousedev) {
-
-               wake = 0;
-
-               list_for_each_entry(list, &(*mousedev)->list, node)
-                       switch (type) {
-                               case EV_ABS:
-                                       mousedev_abs_event(handle, list, code, value);
-                                       break;
-
-                               case EV_REL:
-                                       switch (code) {
-                                               case REL_X:     list->dx += value; break;
-                                               case REL_Y:     list->dy -= value; break;
-                                               case REL_WHEEL: if (list->mode) list->dz -= value; break;
-                                       }
-                                       break;
-
-                               case EV_KEY:
-                                       if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
-                                               /* Handle touchpad data */
-                                               list->touch = value;
-                                               if (!list->touch)
-                                                       list->pkt_count = 0;
-                                               break;
-                                       }
-
-                                       switch (code) {
-                                               case BTN_TOUCH:
-                                               case BTN_0:
-                                               case BTN_FORWARD:
-                                               case BTN_LEFT:   index = 0; break;
-                                               case BTN_4:
-                                               case BTN_EXTRA:  if (list->mode == 2) { index = 4; break; }
-                                               case BTN_STYLUS:
-                                               case BTN_1:
-                                               case BTN_RIGHT:  index = 1; break;
-                                               case BTN_3:
-                                               case BTN_BACK:
-                                               case BTN_SIDE:   if (list->mode == 2) { index = 3; break; }
-                                               case BTN_2:
-                                               case BTN_STYLUS2:
-                                               case BTN_MIDDLE: index = 2; break;      
-                                               default: return;
-                                       }
-                                       switch (value) {
-                                               case 0: clear_bit(index, &list->buttons); break;
-                                               case 1: set_bit(index, &list->buttons); break;
-                                               case 2: return;
-                                       }
-                                       break;
-
-                               case EV_SYN:
-                                       switch (code) {
-                                               case SYN_REPORT:
-                                                       if (list->touch) {
-                                                               list->pkt_count++;
-                                                               /* Input system eats duplicate events,
-                                                                * but we need all of them to do correct
-                                                                * averaging so apply present one forward
-                                                                */
-                                                               fx(0) = fx(1);
-                                                               fy(0) = fy(1);
-                                                       }
-
-                                                       list->ready = 1;
-                                                       kill_fasync(&list->fasync, SIGIO, POLL_IN);
-                                                       wake = 1;
-                                                       break;
-                                       }
+
+       list_for_each_entry(list, &mousedev->list, node) {
+               list->dx += packet->dx;
+               list->dy += packet->dy;
+               list->dz += packet->dz;
+               list->buttons = mousedev->buttons;
+               list->ready = 1;
+               kill_fasync(&list->fasync, SIGIO, POLL_IN);
+       }
+
+       wake_up_interruptible(&mousedev->wait);
+}
+
+static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
+{
+       struct mousedev *mousedev = handle->private;
+
+       switch (type) {
+               case EV_ABS:
+                       /* Ignore joysticks */
+                       if (test_bit(BTN_TRIGGER, handle->dev->keybit))
+                               return;
+
+                       if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
+                               mousedev_touchpad_event(mousedev, code, value);
+                       else
+                               mousedev_abs_event(handle->dev, mousedev, code, value);
+
+                       break;
+
+               case EV_REL:
+                       mousedev_rel_event(mousedev, code, value);
+                       break;
+
+               case EV_KEY:
+                       if (value != 2) {
+                               if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
+                                       /* Handle touchpad data */
+                                       mousedev->touch = value;
+                                       if (!mousedev->touch)
+                                               mousedev->pkt_count = 0;
+                               }
+                               else
+                                       mousedev_key_event(mousedev, code, value);
                        }
+                       break;
+
+               case EV_SYN:
+                       if (code == SYN_REPORT) {
+                               if (mousedev->touch) {
+                                       mousedev->pkt_count++;
+                                       /* Input system eats duplicate events, but we need all of them
+                                        * to do correct averaging so apply present one forward
+                                        */
+                                       fx(0) = fx(1);
+                                       fy(0) = fy(1);
+                               }
 
-               if (wake)
-                       wake_up_interruptible(&((*mousedev)->wait));
+                               mousedev_notify_readers(mousedev, &mousedev->packet);
+                               mousedev_notify_readers(&mousedev_mix, &mousedev->packet);
 
-               mousedev++;
+                               memset(&mousedev->packet, 0, sizeof(struct mousedev_motion));
+                       }
+                       break;
        }
 }
 
@@ -267,7 +296,7 @@ static int mousedev_release(struct inode * inode, struct file * file)
                                mousedev_free(list->mousedev);
                }
        }
-       
+
        kfree(list);
        return 0;
 }
@@ -301,11 +330,11 @@ static int mousedev_open(struct inode * inode, struct file * file)
                if (list->mousedev->minor == MOUSEDEV_MIX) {
                        list_for_each_entry(handle, &mousedev_handler.h_list, h_node) {
                                mousedev = handle->private;
-                               if (!mousedev->open && mousedev->exist) 
+                               if (!mousedev->open && mousedev->exist)
                                        input_open_device(handle);
                        }
-               } else 
-                       if (!mousedev_mix.open && list->mousedev->exist)        
+               } else
+                       if (!mousedev_mix.open && list->mousedev->exist)
                                input_open_device(&list->mousedev->handle);
        }
 
@@ -326,8 +355,10 @@ static void mousedev_packet(struct mousedev_list *list, unsigned char off)
                list->dz -= list->ps2[off + 3];
                list->ps2[off + 3] = (list->ps2[off + 3] & 0x0f) | ((list->buttons & 0x18) << 1);
                list->bufsiz++;
+       } else {
+               list->ps2[off] |= ((list->buttons & 0x10) >> 3) | ((list->buttons & 0x08) >> 1);
        }
-       
+
        if (list->mode == 1) {
                list->ps2[off + 3] = (list->dz > 127 ? 127 : (list->dz < -127 ? -127 : list->dz));
                list->dz -= list->ps2[off + 3];
@@ -391,9 +422,9 @@ static ssize_t mousedev_write(struct file * file, const char __user * buffer, si
                                list->impsseq = 0;
                                list->imexseq = 0;
                                list->mode = 0;
-                               list->ps2[0] = 0xaa;
-                               list->ps2[1] = 0x00;
-                               list->bufsiz = 2;
+                               list->ps2[1] = 0xaa;
+                               list->ps2[2] = 0x00;
+                               list->bufsiz = 3;
                                break;
                }
 
@@ -403,7 +434,7 @@ static ssize_t mousedev_write(struct file * file, const char __user * buffer, si
        kill_fasync(&list->fasync, SIGIO, POLL_IN);
 
        wake_up_interruptible(&list->mousedev->wait);
-               
+
        return count;
 }
 
@@ -431,7 +462,7 @@ static ssize_t mousedev_read(struct file * file, char __user * buffer, size_t co
        if (copy_to_user(buffer, list->ps2 + list->bufsiz - list->buffer - count, count))
                return -EFAULT;
 
-       return count;   
+       return count;
 }
 
 /* No kernel lock - fine */
@@ -487,7 +518,7 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru
 
        devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
                        S_IFCHR|S_IRUGO|S_IWUSR, "input/mouse%d", minor);
-       class_simple_device_add(input_class, 
+       class_simple_device_add(input_class,
                                MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
                                dev->dev, "mouse%d", minor);
 
@@ -538,7 +569,7 @@ static struct input_device_id mousedev_ids[] = {
 };
 
 MODULE_DEVICE_TABLE(input, mousedev_ids);
-       
+
 static struct input_handler mousedev_handler = {
        .event =        mousedev_event,
        .connect =      mousedev_connect,
@@ -553,6 +584,7 @@ static struct input_handler mousedev_handler = {
 static struct miscdevice psaux_mouse = {
        PSMOUSE_MINOR, "psaux", &mousedev_fops
 };
+static int psaux_registered;
 #endif
 
 static int __init mousedev_init(void)
@@ -572,7 +604,7 @@ static int __init mousedev_init(void)
                                NULL, "mice");
 
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
-       if (!(mousedev_mix.misc = !misc_register(&psaux_mouse)))
+       if (!(psaux_registered = !misc_register(&psaux_mouse)))
                printk(KERN_WARNING "mice: could not misc_register the device\n");
 #endif
 
@@ -584,7 +616,7 @@ static int __init mousedev_init(void)
 static void __exit mousedev_exit(void)
 {
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
-       if (mousedev_mix.misc)
+       if (psaux_registered)
                misc_deregister(&psaux_mouse);
 #endif
        devfs_remove("input/mice");
index 552dcd8..f7469b5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * $Id: power.c,v 1.10 2001/09/25 09:17:15 vojtech Exp $
  *
- *  Copyright (c) 2001 "Crazy" James Simmons  
+ *  Copyright (c) 2001 "Crazy" James Simmons
  *
  *  Input driver Power Management.
  *
@@ -51,7 +51,7 @@ static void suspend_button_task_handler(void *data)
 
 static DECLARE_WORK(suspend_button_task, suspend_button_task_handler, NULL);
 
-static void power_event(struct input_handle *handle, unsigned int type, 
+static void power_event(struct input_handle *handle, unsigned int type,
                        unsigned int code, int down)
 {
        struct input_dev *dev = handle->dev;
@@ -73,7 +73,7 @@ static void power_event(struct input_handle *handle, unsigned int type,
                        case KEY_POWER:
                                /* Hum power down the machine. */
                                break;
-                       default:        
+                       default:
                                return;
                }
        } else {
@@ -83,9 +83,9 @@ static void power_event(struct input_handle *handle, unsigned int type,
                                /* This is risky. See pm.h for details. */
                                if (dev->state != PM_RESUME)
                                        dev->state = PM_RESUME;
-                               else 
-                                       dev->state = PM_SUSPEND;        
-                               pm_send(dev->pm_dev, dev->state, dev);  
+                               else
+                                       dev->state = PM_SUSPEND;
+                               pm_send(dev->pm_dev, dev->state, dev);
                                break;
                        case KEY_POWER:
                                /* Turn the input device off completely ? */
@@ -97,14 +97,14 @@ static void power_event(struct input_handle *handle, unsigned int type,
        return;
 }
 
-static struct input_handle *power_connect(struct input_handler *handler, 
-                                         struct input_dev *dev, 
+static struct input_handle *power_connect(struct input_handler *handler,
+                                         struct input_dev *dev,
                                          struct input_device_id *id)
 {
        struct input_handle *handle;
 
        if (!test_bit(EV_KEY, dev->evbit) || !test_bit(EV_PWR, dev->evbit))
-               return NULL;    
+               return NULL;
 
        if (!test_bit(KEY_SUSPEND, dev->keybit) || (!test_bit(KEY_POWER, dev->keybit)))
                return NULL;
@@ -133,21 +133,21 @@ static struct input_device_id power_ids[] = {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
                .evbit = { BIT(EV_KEY) },
                .keybit = { [LONG(KEY_SUSPEND)] = BIT(KEY_SUSPEND) }
-       },      
+       },
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
                .evbit = { BIT(EV_KEY) },
                .keybit = { [LONG(KEY_POWER)] = BIT(KEY_POWER) }
-       },      
+       },
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
                .evbit = { BIT(EV_PWR) },
-       },      
+       },
        { },    /* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE(input, power_ids);
-       
+
 static struct input_handler power_handler = {
        .event =        power_event,
        .connect =      power_connect,
@@ -172,3 +172,4 @@ module_exit(power_exit);
 
 MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
 MODULE_DESCRIPTION("Input Power Management driver");
+MODULE_LICENSE("GPL");
index fb810fa..cd74954 100644 (file)
@@ -97,16 +97,6 @@ config SERIO_SA1111
        tristate "Intel SA1111 keyboard controller"
        depends on SA1111 && SERIO
 
-config SERIO_98KBD
-       tristate "NEC PC-9800 keyboard controller"
-       depends on X86_PC9800 && SERIO
-       help
-         Say Y here if you have the NEC PC-9801/PC-9821 and want to use its
-         standard keyboard connected to its keyboard controller.
-
-         To compile this driver as a module, choose M here: the
-         module will be called 98kbd-io.
-
 config SERIO_GSCPS2
        tristate "HP GSC PS/2 keyboard and PS/2 mouse controller"
        depends on GSC && SERIO
index df61839..6a780c1 100644 (file)
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/err.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/hardware/amba.h>
 #include <asm/hardware/amba_kmi.h>
+#include <asm/hardware/clock.h>
 
 #define KMI_BASE       (kmi->base)
 
 struct amba_kmi_port {
        struct serio            io;
-       struct amba_kmi_port    *next;
+       struct clk              *clk;
        unsigned char           *base;
        unsigned int            irq;
        unsigned int            divisor;
@@ -67,21 +69,38 @@ static int amba_kmi_write(struct serio *io, unsigned char val)
 static int amba_kmi_open(struct serio *io)
 {
        struct amba_kmi_port *kmi = io->driver;
+       unsigned int divisor;
        int ret;
 
-       writeb(kmi->divisor, KMICLKDIV);
+       ret = clk_use(kmi->clk);
+       if (ret)
+               goto out;
+
+       ret = clk_enable(kmi->clk);
+       if (ret)
+               goto clk_unuse;
+
+       divisor = clk_get_rate(kmi->clk) / 8000000 - 1;
+       writeb(divisor, KMICLKDIV);
        writeb(KMICR_EN, KMICR);
 
        ret = request_irq(kmi->irq, amba_kmi_int, 0, "kmi-pl050", kmi);
        if (ret) {
                printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq);
                writeb(0, KMICR);
-               return ret;
+               goto clk_disable;
        }
 
        writeb(KMICR_EN | KMICR_RXINTREN, KMICR);
 
        return 0;
+
+ clk_disable:
+       clk_disable(kmi->clk);
+ clk_unuse:
+       clk_unuse(kmi->clk);
+ out:
+       return ret;
 }
 
 static void amba_kmi_close(struct serio *io)
@@ -91,6 +110,8 @@ static void amba_kmi_close(struct serio *io)
        writeb(0, KMICR);
 
        free_irq(kmi->irq, kmi);
+       clk_disable(kmi->clk);
+       clk_unuse(kmi->clk);
 }
 
 static int amba_kmi_probe(struct amba_device *dev, void *id)
@@ -124,14 +145,20 @@ static int amba_kmi_probe(struct amba_device *dev, void *id)
                goto out;
        }
 
-       kmi->irq        = dev->irq[0];
-       kmi->divisor    = 24 / 8 - 1;
+       kmi->clk = clk_get(&dev->dev, "KMIREFCLK");
+       if (IS_ERR(kmi->clk)) {
+               ret = PTR_ERR(kmi->clk);
+               goto unmap;
+       }
 
+       kmi->irq = dev->irq[0];
        amba_set_drvdata(dev, kmi);
 
        serio_register_port(&kmi->io);
        return 0;
 
+ unmap:
+       iounmap(kmi->base);
  out:
        kfree(kmi);
        amba_release_regions(dev);
@@ -145,6 +172,7 @@ static int amba_kmi_remove(struct amba_device *dev)
        amba_set_drvdata(dev, NULL);
 
        serio_unregister_port(&kmi->io);
+       clk_put(kmi->clk);
        iounmap(kmi->base);
        kfree(kmi);
        amba_release_regions(dev);
index b7fc99e..2234ff3 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
index 6f6bf42..48a0ad5 100644 (file)
@@ -16,7 +16,7 @@
  * 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.
- * 
+ *
  * TODO:
  * - Dino testing (did HP ever shipped a machine on which this port
  *                 was usable/enabled ?)
@@ -44,7 +44,7 @@ MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
 
 #define PFX "gscps2.c: "
 
-/* 
+/*
  * Driver constants
  */
 
@@ -222,7 +222,7 @@ static LIST_HEAD(ps2port_list);
 /**
  * gscps2_interrupt() - Interruption service routine
  *
- * This function reads received PS/2 bytes and processes them on 
+ * This function reads received PS/2 bytes and processes them on
  * all interfaces.
  * The problematic part here is, that the keyboard and mouse PS/2 port
  * share the same interrupt and it's not possible to send data if any
@@ -240,9 +240,9 @@ static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs)
          unsigned long flags;
          spin_lock_irqsave(&ps2port->lock, flags);
 
-         while ( (ps2port->buffer[ps2port->append].str = 
+         while ( (ps2port->buffer[ps2port->append].str =
                   gscps2_readb_status(ps2port->addr)) & GSC_STAT_RBNE ) {
-               ps2port->buffer[ps2port->append].data = 
+               ps2port->buffer[ps2port->append].data =
                                gscps2_readb_input(ps2port->addr);
                ps2port->append = ((ps2port->append+1) & BUFFER_SIZE);
          }
@@ -349,7 +349,7 @@ static int __init gscps2_probe(struct parisc_device *dev)
 
        if (!dev->irq)
                return -ENODEV;
-       
+
        /* Offset for DINO PS/2. Works with LASI even */
        if (dev->id.sversion == 0x96)
                hpa += GSC_DINO_OFFSET;
@@ -368,7 +368,7 @@ static int __init gscps2_probe(struct parisc_device *dev)
        gscps2_reset(ps2port);
        ps2port->id = readb(ps2port->addr+GSC_ID) & 0x0f;
        snprintf(ps2port->name, sizeof(ps2port->name)-1, "%s %s",
-               gscps2_serio_port.name, 
+               gscps2_serio_port.name,
                (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse" );
 
        memcpy(&ps2port->port, &gscps2_serio_port, sizeof(gscps2_serio_port));
@@ -401,9 +401,9 @@ static int __init gscps2_probe(struct parisc_device *dev)
                ps2port->port.phys);
 
        serio_register_port(&ps2port->port);
-       
+
        return 0;
-       
+
 fail:
        free_irq(dev->irq, ps2port);
 
@@ -430,7 +430,7 @@ static int __devexit gscps2_remove(struct parisc_device *dev)
        list_del(&ps2port->node);
        iounmap(ps2port->addr);
 #if 0
-       release_mem_region(dev->hpa, GSC_STATUS + 4); 
+       release_mem_region(dev->hpa, GSC_STATUS + 4);
 #endif
        dev_set_drvdata(&dev->dev, NULL);
        kfree(ps2port);
@@ -441,7 +441,7 @@ static int __devexit gscps2_remove(struct parisc_device *dev)
 static struct parisc_device_id gscps2_device_tbl[] = {
        { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */
 #ifdef DINO_TESTED
-       { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */ 
+       { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */
 #endif
        { 0, }  /* 0 terminated list */
 };
index efe3c28..e9d8dab 100644 (file)
@@ -150,7 +150,7 @@ static int i8042_flush(void)
  */
 
 static int i8042_command(unsigned char *param, int command)
-{ 
+{
        unsigned long flags;
        int retval = 0, i = 0;
 
@@ -161,7 +161,7 @@ static int i8042_command(unsigned char *param, int command)
                dbg("%02x -> i8042 (command)", command & 0xff);
                i8042_write_command(command & 0xff);
        }
-       
+
        if (!retval)
                for (i = 0; i < ((command >> 12) & 0xf); i++) {
                        if ((retval = i8042_wait_write())) break;
@@ -172,7 +172,7 @@ static int i8042_command(unsigned char *param, int command)
        if (!retval)
                for (i = 0; i < ((command >> 8) & 0xf); i++) {
                        if ((retval = i8042_wait_read())) break;
-                       if (i8042_read_status() & I8042_STR_AUXDATA) 
+                       if (i8042_read_status() & I8042_STR_AUXDATA)
                                param[i] = ~i8042_read_data();
                        else
                                param[i] = i8042_read_data();
@@ -415,17 +415,17 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                } else dfl = 0;
 
                dbg("%02x <- i8042 (interrupt, aux%d, %d%s%s)",
-                       data, (str >> 6), irq, 
+                       data, (str >> 6), irq,
                        dfl & SERIO_PARITY ? ", bad parity" : "",
                        dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
                serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl, regs);
-               
+
                goto irq_ret;
        }
 
        dbg("%02x <- i8042 (interrupt, %s, %d%s%s)",
-               data, (str & I8042_STR_AUXDATA) ? "aux" : "kbd", irq, 
+               data, (str & I8042_STR_AUXDATA) ? "aux" : "kbd", irq,
                dfl & SERIO_PARITY ? ", bad parity" : "",
                dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
@@ -474,8 +474,17 @@ static int i8042_enable_mux_mode(struct i8042_values *values, unsigned char *mux
        if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xa9)
                return -1;
        param = 0xa4;
-       if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b)
+       if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b) {
+
+/*
+ * Do another loop test with the 0x5a value. Doing anything else upsets
+ * Profusion/ServerWorks OSB4 chipsets.
+ */
+
+               param = 0x5a;
+               i8042_command(&param, I8042_CMD_AUX_LOOP);
                return -1;
+       }
 
        if (mux_version)
                *mux_version = ~param;
@@ -530,10 +539,10 @@ static int __init i8042_check_mux(struct i8042_values *values)
 
        if (i8042_enable_mux_mode(values, &mux_version))
                return -1;
-       
+
        /* Workaround for broken chips which seem to support MUX, but in reality don't. */
-       /* They all report version 12.10 */
-       if (mux_version == 0xCA)
+       /* They all report version 10.12 */
+       if (mux_version == 0xAC)
                return -1;
 
        printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
@@ -598,7 +607,7 @@ static int __init i8042_check_aux(struct i8042_values *values)
 /*
  * Bit assignment test - filters out PS/2 i8042's in AT mode
  */
-       
+
        if (i8042_command(&param, I8042_CMD_AUX_DISABLE))
                return -1;
        if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (~param & I8042_CTR_AUXDIS)) {
@@ -609,7 +618,7 @@ static int __init i8042_check_aux(struct i8042_values *values)
        if (i8042_command(&param, I8042_CMD_AUX_ENABLE))
                return -1;
        if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS))
-               return -1;      
+               return -1;
 
 /*
  * Disable the interface.
@@ -639,7 +648,7 @@ static int __init i8042_port_register(struct i8042_values *values, struct serio
        if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
                printk(KERN_WARNING "i8042.c: Can't write CTR while registering.\n");
                values->exists = 0;
-               return -1; 
+               return -1;
        }
 
        printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
@@ -868,7 +877,7 @@ static int i8042_controller_resume(void)
 static int i8042_notify_sys(struct notifier_block *this, unsigned long code,
                            void *unused)
 {
-        if (code==SYS_DOWN || code==SYS_HALT) 
+        if (code == SYS_DOWN || code == SYS_HALT)
                i8042_controller_cleanup();
         return NOTIFY_DONE;
 }
@@ -997,19 +1006,18 @@ void __exit i8042_exit(void)
                sysdev_class_unregister(&kbc_sysclass);
        }
 
-       del_timer_sync(&i8042_timer);
-
        i8042_controller_cleanup();
-       
+
        if (i8042_kbd_values.exists)
                serio_unregister_port(&i8042_kbd_port);
 
        if (i8042_aux_values.exists)
                serio_unregister_port(&i8042_aux_port);
-       
+
        for (i = 0; i < 4; i++)
                if (i8042_mux_values[i].exists)
                        serio_unregister_port(i8042_mux_port + i);
+       del_timer_sync(&i8042_timer);
 
        i8042_platform_exit();
 }
index 1df2dd1..5f25b21 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -86,20 +86,9 @@ static int parkbd_write(struct serio *port, unsigned char c)
        return 0;
 }
 
-static int parkbd_open(struct serio *port)
-{
-       return 0;
-}
-
-static void parkbd_close(struct serio *port)
-{
-}
-
 static struct serio parkbd_port =
 {
        .write  = parkbd_write,
-       .open   = parkbd_open,
-       .close  = parkbd_close,
        .name   = parkbd_name,
        .phys   = parkbd_phys,
 };
@@ -115,7 +104,7 @@ static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        parkbd_writing = 0;
                        parkbd_writelines(3);
                        return;
-               }       
+               }
 
                parkbd_writelines(((parkbd_buffer >> parkbd_counter++) & 1) | 2);
 
@@ -131,7 +120,7 @@ static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                if ((parkbd_counter == parkbd_mode + 10) || time_after(jiffies, parkbd_last + HZ/100)) {
                        parkbd_counter = 0;
                        parkbd_buffer = 0;
-               }       
+               }
 
                parkbd_buffer |= (parkbd_readlines() >> 1) << parkbd_counter++;
 
index 021763a..7f4a262 100644 (file)
@@ -4,7 +4,7 @@
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *
  *  Based on the work of:
- *     Richard Zidlicky <Richard.Zidlicky@stud.informatik.uni-erlangen.de>     
+ *     Richard Zidlicky <Richard.Zidlicky@stud.informatik.uni-erlangen.de>
  */
 
 /*
@@ -47,23 +47,12 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
 MODULE_LICENSE("GPL");
 
-
-static int q40kbd_open(struct serio *port)
-{
-       return 0;
-}
-static void q40kbd_close(struct serio *port)
-{
-}
-
 static struct serio q40kbd_port =
 {
        .type   = SERIO_8042,
        .name   = "Q40 kbd port",
        .phys   = "Q40",
        .write  = NULL,
-       .open   = q40kbd_open,
-       .close  = q40kbd_close,
 };
 
 static irqreturn_t q40kbd_interrupt(int irq, void *dev_id,
index bcd1aa8..a2e4be7 100644 (file)
@@ -98,7 +98,7 @@ static int rpckbd_open(struct serio *port)
 static void rpckbd_close(struct serio *port)
 {
        free_irq(IRQ_KEYBOARDRX, port);
-       free_irq(IRQ_KEYBOARDTX, port); 
+       free_irq(IRQ_KEYBOARDTX, port);
 }
 
 static struct serio rpckbd_port =
index 13d21bf..6f00319 100644 (file)
 /*
  * 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
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -108,7 +108,7 @@ void serio_handle_events(void)
        struct serio_event *event;
 
        list_for_each_safe(node, next, &serio_event_list) {
-               event = container_of(node, struct serio_event, node);   
+               event = container_of(node, struct serio_event, node);
 
                down(&serio_sem);
                if (event->serio == NULL)
@@ -152,7 +152,7 @@ static int serio_thread(void *nothing)
 
        do {
                serio_handle_events();
-               wait_event_interruptible(serio_wait, !list_empty(&serio_event_list)); 
+               wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
                if (current->flags & PF_FREEZE)
                        refrigerator(PF_FREEZE);
        } while (!signal_pending(current));
@@ -293,7 +293,7 @@ void serio_unregister_device(struct serio_dev *dev)
 int serio_open(struct serio *serio, struct serio_dev *dev)
 {
        serio->dev = dev;
-       if (serio->open(serio)) {
+       if (serio->open && serio->open(serio)) {
                serio->dev = NULL;
                return -1;
        }
@@ -303,7 +303,8 @@ int serio_open(struct serio *serio, struct serio_dev *dev)
 /* called from serio_dev->connect/disconnect methods under serio_sem */
 void serio_close(struct serio *serio)
 {
-       serio->close(serio);
+       if (serio->close)
+               serio->close(serio);
        serio->dev = NULL;
 }
 
index 716fe7d..19e2692 100644 (file)
@@ -48,11 +48,6 @@ static int serport_serio_write(struct serio *serio, unsigned char data)
        return -(serport->tty->driver->write(serport->tty, 0, &data, 1) != 1);
 }
 
-static int serport_serio_open(struct serio *serio)
-{
-        return 0;
-}
-
 static void serport_serio_close(struct serio *serio)
 {
        struct serport *serport = serio->driver;
@@ -87,7 +82,6 @@ static int serport_ldisc_open(struct tty_struct *tty)
 
        serport->serio.type = SERIO_RS232;
        serport->serio.write = serport_serio_write;
-       serport->serio.open = serport_serio_open;
        serport->serio.close = serport_serio_close;
        serport->serio.driver = serport;
 
@@ -135,7 +129,7 @@ static int serport_ldisc_room(struct tty_struct *tty)
 }
 
 /*
- * serport_ldisc_read() just waits indefinitely if everything goes well. 
+ * serport_ldisc_read() just waits indefinitely if everything goes well.
  * However, when the serio driver closes the serio port, it finishes,
  * returning 0 characters.
  */
@@ -165,7 +159,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u
 static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg)
 {
        struct serport *serport = (struct serport*) tty->disc_data;
-       
+
        if (cmd == SPIOCSTYPE)
                return get_user(serport->serio.type, (unsigned long __user *) arg);
 
index 9aec2e1..7759149 100644 (file)
@@ -124,12 +124,10 @@ static void gunze_connect(struct serio *serio, struct serio_dev *dev)
        memset(gunze, 0, sizeof(struct gunze));
 
        init_input_dev(&gunze->dev);
-       gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);        
-       gunze->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+       gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
        gunze->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
-       gunze->dev.absmin[ABS_X] = 96;   gunze->dev.absmin[ABS_Y] = 72;
-       gunze->dev.absmax[ABS_X] = 4000; gunze->dev.absmax[ABS_Y] = 3000;
+       input_set_abs_params(&gunze->dev, ABS_X, 96, 4000, 0, 0);
+       input_set_abs_params(&gunze->dev, ABS_Y, 72, 3000, 0, 0);
 
        gunze->serio = serio;
        serio->private = gunze;
index 2f2855a..7b4c16d 100644 (file)
@@ -1,11 +1,11 @@
 /*
  * $Id: h3600_ts_input.c,v 1.4 2002/01/23 06:39:37 jsimmons Exp $
  *
- *  Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com 
+ *  Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com
  *
- *  Sponsored by Transvirtual Technology. 
- * 
- *  Derived from the code in h3600_ts.[ch] by Charles Flynn  
+ *  Sponsored by Transvirtual Technology.
+ *
+ *  Derived from the code in h3600_ts.[ch] by Charles Flynn
  */
 
 /*
 #include <asm/arch/hardware.h>
 #include <asm/arch/irqs.h>
 
+MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
+MODULE_DESCRIPTION("H3600 touchscreen driver");
+MODULE_LICENSE("GPL");
+
 /*
  * Definitions & global arrays.
  */
@@ -75,7 +79,7 @@
 #define MAX_ID                  14
 
 #define H3600_MAX_LENGTH 16
-#define H3600_KEY 0xf 
+#define H3600_KEY 0xf
 
 #define H3600_SCANCODE_RECORD  1        /* 1 -> record button */
 #define H3600_SCANCODE_CALENDAR 2       /* 2 -> calendar */
@@ -103,7 +107,7 @@ struct h3600_dev {
        char phys[32];
 };
 
-static void action_button_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t action_button_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
         int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1;
        struct input_dev *dev = (struct input_dev *) dev_id;
@@ -111,21 +115,25 @@ static void action_button_handler(int irq, void *dev_id, struct pt_regs *regs)
        input_regs(dev, regs);
        input_report_key(dev, KEY_ENTER, down);
        input_sync(dev);
+
+       return IRQ_HANDLED;
 }
 
-static void npower_button_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t npower_button_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
         int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1;
        struct input_dev *dev = (struct input_dev *) dev_id;
 
-       /* 
-        * This interrupt is only called when we release the key. So we have 
+       /*
+        * This interrupt is only called when we release the key. So we have
         * to fake a key press.
-        */     
+        */
        input_regs(dev, regs);
        input_report_key(dev, KEY_SUSPEND, 1);
-       input_report_key(dev, KEY_SUSPEND, down);       
+       input_report_key(dev, KEY_SUSPEND, down);
        input_sync(dev);
+
+       return IRQ_HANDLED;
 }
 
 #ifdef CONFIG_PM
@@ -141,21 +149,21 @@ enum flite_pwr {
  * h3600_flite_power: enables or disables power to frontlight, using last bright */
 unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr)
 {
-       unsigned char brightness = ((pwr==FLITE_PWR_OFF) ? 0:flite_brightness);
+       unsigned char brightness = (pwr == FLITE_PWR_OFF) ? 0 : flite_brightness;
        struct h3600_dev *ts = dev->private;
 
-       /* Must be in this order */     
+       /* Must be in this order */
                ts->serio->write(ts->serio, 1);
        ts->serio->write(ts->serio, pwr);
-       ts->serio->write(ts->serio, brightness); 
+       ts->serio->write(ts->serio, brightness);
        return 0;
 }
 
 static int suspended = 0;
-static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req, 
+static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
                                void *data)
 {
-       struct input_dev *dev = (struct input_dev *) data;      
+       struct input_dev *dev = (struct input_dev *) data;
 
         switch (req) {
         case PM_SUSPEND: /* enter D1-D3 */
@@ -183,7 +191,7 @@ static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
 /*
  * This function translates the native event packets to linux input event
  * packets. Some packets coming from serial are not touchscreen related. In
- * this case we send them off to be processed elsewhere. 
+ * this case we send them off to be processed elsewhere.
  */
 static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
 {
@@ -206,7 +214,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
                 Note: This is true for non interrupt generated key events.
                 */
                 case KEYBD_ID:
-                       down = (ts->buf[0] & 0x80) ? 0 : 1; 
+                       down = (ts->buf[0] & 0x80) ? 0 : 1;
 
                        switch (ts->buf[0] & 0x7f) {
                                case H3600_SCANCODE_RECORD:
@@ -218,7 +226,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
                                case H3600_SCANCODE_CONTACTS:
                                        key = KEY_PROG2;
                                         break;
-                               case H3600_SCANCODE_Q:        
+                               case H3600_SCANCODE_Q:
                                        key = KEY_Q;
                                         break;
                                case H3600_SCANCODE_START:
@@ -237,9 +245,9 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
                                        key = KEY_DOWN;
                                         break;
                                default:
-                                       key = 0;        
-                       }       
-                        if (key) 
+                                       key = 0;
+                       }
+                        if (key)
                                input_report_key(dev, key, down);
                         break;
                 /*
@@ -251,13 +259,13 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
                  *       byte 0    1       2       3
                  */
                 case TOUCHS_ID:
-                       if (!touched) { 
+                       if (!touched) {
                                input_report_key(dev, BTN_TOUCH, 1);
                                touched = 1;
-                       }                       
+                       }
 
                        if (ts->len) {
-                               unsigned short x, y;                            
+                               unsigned short x, y;
 
                                x = ts->buf[0]; x <<= 8; x += ts->buf[1];
                                 y = ts->buf[2]; y <<= 8; y += ts->buf[3];
@@ -267,7 +275,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
                        } else {
                                input_report_key(dev, BTN_TOUCH, 0);
                                touched = 0;
-                       }       
+                       }
                         break;
                default:
                        /* Send a non input event elsewhere */
@@ -280,7 +288,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
 /*
  * h3600ts_event() handles events from the input module.
  */
-static int h3600ts_event(struct input_dev *dev, unsigned int type, 
+static int h3600ts_event(struct input_dev *dev, unsigned int type,
                         unsigned int code, int value)
 {
        struct h3600_dev *ts = dev->private;
@@ -290,7 +298,7 @@ static int h3600ts_event(struct input_dev *dev, unsigned int type,
                //      ts->serio->write(ts->serio, SOME_CMD);
                        return 0;
                }
-       }                                       
+       }
        return -1;
 }
 
@@ -317,19 +325,19 @@ static int state;
 #define STATE_DATA      2       /* state where we decode data */
 #define STATE_EOF       3       /* state where we decode checksum or EOF */
 
-static void h3600ts_interrupt(struct serio *serio, unsigned char data,
-                              unsigned int flags)
+static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data,
+                                     unsigned int flags, struct pt_regs *regs)
 {
         struct h3600_dev *ts = serio->private;
 
        /*
-         * We have a new frame coming in. 
+         * We have a new frame coming in.
          */
        switch (state) {
                case STATE_SOF:
                        if (data == CHAR_SOF)
-                               state = STATE_ID;       
-                       return;
+                               state = STATE_ID;
+                       break;
                case STATE_ID:
                        ts->event = (data & 0xf0) >> 4;
                        ts->len = (data & 0xf);
@@ -339,23 +347,25 @@ static void h3600ts_interrupt(struct serio *serio, unsigned char data,
                                break;
                        }
                        ts->chksum = data;
-                       state=(ts->len > 0 ) ? STATE_DATA : STATE_EOF;
+                       state = (ts->len > 0) ? STATE_DATA : STATE_EOF;
                        break;
                case STATE_DATA:
                        ts->chksum += data;
                        ts->buf[ts->idx]= data;
-                       if(++ts->idx == ts->len) 
+                       if(++ts->idx == ts->len)
                                state = STATE_EOF;
                        break;
                case STATE_EOF:
                        state = STATE_SOF;
-                       if (data == CHAR_EOF || data == ts->chksum )
-                               h3600ts_process_packet(ts);
+                       if (data == CHAR_EOF || data == ts->chksum)
+                               h3600ts_process_packet(ts, regs);
                        break;
                default:
                        printk("Error3\n");
                        break;
        }
+
+       return IRQ_HANDLED;
 }
 
 /*
@@ -378,11 +388,11 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
        init_input_dev(&ts->dev);
 
        /* Device specific stuff */
-        set_GPIO_IRQ_edge( GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES );
-        set_GPIO_IRQ_edge( GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE );
+        set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES);
+        set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE);
 
         if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler,
-                       SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,     
+                       SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
                        "h3600_action", &ts->dev)) {
                printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
                kfree(ts);
@@ -390,24 +400,19 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
        }
 
         if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
-                       SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, 
+                       SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
                        "h3600_suspend", &ts->dev)) {
                free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
                printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
                kfree(ts);
                return;
        }
+
        /* Now we have things going we setup our input device */
        ts->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
-       ts->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-       ts->dev.ledbit[0] = BIT(LED_SLEEP); 
-
-       ts->dev.absmin[ABS_X] = 60;   ts->dev.absmin[ABS_Y] = 35;
-       ts->dev.absmax[ABS_X] = 985; ts->dev.absmax[ABS_Y] = 1024;
-       ts->dev.absfuzz[ABS_X] = 0; ts->dev.absfuzz[ABS_Y] = 0;
-
-       ts->serio = serio;
-       serio->private = ts;
+       ts->dev.ledbit[0] = BIT(LED_SLEEP);
+       input_set_abs_params(&ts->dev, ABS_X, 60, 985, 0, 0);
+       input_set_abs_params(&ts->dev, ABS_Y, 35, 1024, 0, 0);
 
        set_bit(KEY_RECORD, ts->dev.keybit);
        set_bit(KEY_Q, ts->dev.keybit);
@@ -422,6 +427,9 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
        ts->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
        ts->dev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND);
 
+       ts->serio = serio;
+       serio->private = ts;
+
        sprintf(ts->phys, "%s/input0", serio->phys);
 
                ts->dev.event = h3600ts_event;
@@ -442,7 +450,7 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
 
        //h3600_flite_control(1, 25);     /* default brightness */
 #ifdef CONFIG_PM
-       ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT, 
+       ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT,
                                        h3600ts_pm_callback);
        printk("registered pm callback\n");
 #endif
@@ -458,7 +466,7 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
 static void h3600ts_disconnect(struct serio *serio)
 {
        struct h3600_dev *ts = serio->private;
-       
+
         free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
         free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev);
        input_unregister_device(&ts->dev);
index 7958ae8..ac072d3 100644 (file)
@@ -151,7 +151,7 @@ static int tsdev_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t tsdev_read(struct file *file, char *buffer, size_t count,
+static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count,
                          loff_t * ppos)
 {
        struct tsdev_list *list = file->private_data;
index 5fd47f6..8b5822c 100644 (file)
@@ -104,9 +104,12 @@ reset_netjet_s(struct IsdnCardState *cs)
        cs->hw.njet.ctrl_reg = 0xff;  /* Reset On */
        byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
        mdelay(10);
-       cs->hw.njet.ctrl_reg = 0x00;  /* Reset Off and status read clear */
        /* now edge triggered for TJ320 GE 13/07/00 */
        /* see comment in IRQ function */
+       if (cs->subtyp) /* TJ320 */
+               cs->hw.njet.ctrl_reg = 0x40;  /* Reset Off and status read clear */
+       else
+               cs->hw.njet.ctrl_reg = 0x00;  /* Reset Off and status read clear */
        byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
        mdelay(10);
        cs->hw.njet.auxd = 0;
@@ -151,7 +154,7 @@ static struct pci_dev *dev_netjet __initdata = NULL;
 int __init
 setup_netjet_s(struct IsdnCard *card)
 {
-       int bytecnt;
+       int bytecnt,cfg;
        struct IsdnCardState *cs = card->cs;
        char tmp[64];
 
@@ -183,6 +186,15 @@ setup_netjet_s(struct IsdnCard *card)
                                printk(KERN_WARNING "NETjet-S: No IO-Adr for PCI card found\n");
                                return(0);
                        }
+                       /* the TJ300 and TJ320 must be detected, the IRQ handling is different
+                        * unfortunatly the chips use the same device ID, but the TJ320 has
+                        * the bit20 in status PCI cfg register set
+                        */
+                       pci_read_config_dword(dev_netjet, 0x04, &cfg);
+                       if (cfg & 0x00100000)
+                               cs->subtyp = 1; /* TJ320 */
+                       else
+                               cs->subtyp = 0; /* TJ300 */
                        /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG www.formula-n.com */
                        if ((dev_netjet->subsystem_vendor == 0x55) &&
                                (dev_netjet->subsystem_device == 0x02)) {
@@ -240,8 +252,8 @@ setup_netjet_s(struct IsdnCard *card)
        bytecnt = 256;
 
        printk(KERN_INFO
-               "NETjet-S: PCI card configured at %#lx IRQ %d\n",
-               cs->hw.njet.base, cs->irq);
+               "NETjet-S: %s card configured at %#lx IRQ %d\n",
+               cs->subtyp ? "TJ320" : "TJ300", cs->hw.njet.base, cs->irq);
        if (!request_region(cs->hw.njet.base, bytecnt, "netjet-s isdn")) {
                printk(KERN_WARNING
                       "HiSax: %s config port %#lx-%#lx already in use\n",
index daec603..1b95f60 100644 (file)
@@ -386,7 +386,7 @@ isdn_all_eaz(int di, int ch)
  * Begin of a CAPI like LL<->HL interface, currently used only for 
  * supplementary service (CAPI 2.0 part III)
  */
-#include <linux/isdn//capicmd.h>
+#include <linux/isdn/capicmd.h>
 
 int
 isdn_capi_rec_hl_msg(capi_msg *cm) {
index b9ae866..87261d3 100644 (file)
@@ -180,5 +180,25 @@ config DM_CRYPT
 
          If unsure, say N.
 
+config DM_SNAPSHOT
+       tristate "Snapshot target (EXPERIMENTAL)"
+       depends on BLK_DEV_DM && EXPERIMENTAL
+       ---help---
+         Allow volume managers to take writeable snapshots of a device.
+
+config DM_MIRROR
+       tristate "Mirror target (EXPERIMENTAL)"
+       depends on BLK_DEV_DM && EXPERIMENTAL
+       ---help---
+         Allow volume managers to mirror logical volumes, also
+         needed for live data migration tools such as 'pvmove'.
+
+config DM_ZERO
+       tristate "Zero target (EXPERIMENTAL)"
+       depends on BLK_DEV_DM && EXPERIMENTAL
+       ---help---
+         A target that discards writes, and returns all zeroes for
+         reads.  Useful in some recovery situations.
+
 endmenu
 
index 7b04d63..0a87c9e 100644 (file)
@@ -3,13 +3,17 @@
 #
 
 dm-mod-objs    := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
-                  dm-ioctl.o
+                  dm-ioctl.o dm-io.o kcopyd.o
+dm-snapshot-objs := dm-snap.o dm-exception-store.o
+dm-mirror-objs := dm-log.o dm-raid1.o
 raid6-objs     := raid6main.o raid6algos.o raid6recov.o raid6tables.o \
                   raid6int1.o raid6int2.o raid6int4.o \
                   raid6int8.o raid6int16.o raid6int32.o \
                   raid6mmx.o raid6sse1.o raid6sse2.o
 host-progs     := mktables
 
+CFLAGS_raid6int8.o += -O2
+
 # Note: link order is important.  All raid personalities
 # and xor.o must come before md.o, as they each initialise 
 # themselves, and md.o may use the personalities when it 
@@ -24,6 +28,9 @@ obj-$(CONFIG_MD_MULTIPATH)    += multipath.o
 obj-$(CONFIG_BLK_DEV_MD)       += md.o
 obj-$(CONFIG_BLK_DEV_DM)       += dm-mod.o
 obj-$(CONFIG_DM_CRYPT)         += dm-crypt.o
+obj-$(CONFIG_DM_SNAPSHOT)      += dm-snapshot.o
+obj-$(CONFIG_DM_MIRROR)                += dm-mirror.o
+obj-$(CONFIG_DM_ZERO)          += dm-zero.o
 
 quiet_cmd_unroll = UNROLL  $@
       cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \
index 0d508c0..e1703f7 100644 (file)
@@ -417,9 +417,9 @@ static int list_devices(struct dm_ioctl *param, size_t param_size)
        return 0;
 }
 
-static void list_version_get_needed(struct target_type *tt, void *param)
+static void list_version_get_needed(struct target_type *tt, void *needed_param)
 {
-    int *needed = param;
+    size_t *needed = needed_param;
 
     *needed += strlen(tt->name);
     *needed += sizeof(tt->version);
@@ -1133,7 +1133,7 @@ static ioctl_fn lookup_ioctl(unsigned int cmd)
  * As well as checking the version compatibility this always
  * copies the kernel interface version out.
  */
-static int check_version(unsigned int cmd, struct dm_ioctl *user)
+static int check_version(unsigned int cmd, struct dm_ioctl __user *user)
 {
        uint32_t version[3];
        int r = 0;
@@ -1168,7 +1168,7 @@ static void free_params(struct dm_ioctl *param)
        vfree(param);
 }
 
-static int copy_params(struct dm_ioctl *user, struct dm_ioctl **param)
+static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param)
 {
        struct dm_ioctl tmp, *dmi;
 
@@ -1225,7 +1225,7 @@ static int ctl_ioctl(struct inode *inode, struct file *file,
        int r = 0;
        unsigned int cmd;
        struct dm_ioctl *param;
-       struct dm_ioctl *user = (struct dm_ioctl *) u;
+       struct dm_ioctl __user *user = (struct dm_ioctl __user *) u;
        ioctl_fn fn = NULL;
        size_t param_size;
 
index 14cabe5..d189f85 100644 (file)
@@ -400,7 +400,7 @@ static int upgrade_mode(struct dm_dev *dd, int new_mode)
        struct dm_dev dd_copy;
        dev_t dev = dd->bdev->bd_dev;
 
-       memcpy(&dd_copy, dd, sizeof(dd_copy));
+       dd_copy = *dd;
 
        dd->mode |= new_mode;
        dd->bdev = NULL;
@@ -408,7 +408,7 @@ static int upgrade_mode(struct dm_dev *dd, int new_mode)
        if (!r)
                close_dev(&dd_copy);
        else
-               memcpy(dd, &dd_copy, sizeof(dd_copy));
+               *dd = dd_copy;
 
        return r;
 }
index 03381e0..80a1901 100644 (file)
@@ -394,7 +394,7 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector,
        struct bio_vec *bv = bio->bi_io_vec + idx;
 
        clone = bio_alloc(GFP_NOIO, 1);
-       memcpy(clone->bi_io_vec, bv, sizeof(*bv));
+       *clone->bi_io_vec = *bv;
 
        clone->bi_sector = sector;
        clone->bi_bdev = bio->bi_bdev;
index 7992b21..77cd6e9 100644 (file)
@@ -1934,7 +1934,7 @@ static int autostart_array(dev_t startdev)
 }
 
 
-static int get_version(void * arg)
+static int get_version(void __user * arg)
 {
        mdu_version_t ver;
 
@@ -1948,7 +1948,7 @@ static int get_version(void * arg)
        return 0;
 }
 
-static int get_array_info(mddev_t * mddev, void * arg)
+static int get_array_info(mddev_t * mddev, void __user * arg)
 {
        mdu_array_info_t info;
        int nr,working,active,failed,spare;
@@ -1998,7 +1998,7 @@ static int get_array_info(mddev_t * mddev, void * arg)
        return 0;
 }
 
-static int get_disk_info(mddev_t * mddev, void * arg)
+static int get_disk_info(mddev_t * mddev, void __user * arg)
 {
        mdu_disk_info_t info;
        unsigned int nr;
@@ -2251,7 +2251,12 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
                return -EINVAL;
        }
 
-       rdev->sb_offset = calc_dev_sboffset(rdev->bdev);
+       if (mddev->persistent)
+               rdev->sb_offset = calc_dev_sboffset(rdev->bdev);
+       else
+               rdev->sb_offset =
+                       rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
+
        size = calc_dev_size(rdev, mddev->chunk_size);
        rdev->size = size;
 
@@ -2372,6 +2377,103 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
        return 0;
 }
 
+/*
+ * update_array_info is used to change the configuration of an
+ * on-line array.
+ * The version, ctime,level,size,raid_disks,not_persistent, layout,chunk_size
+ * fields in the info are checked against the array.
+ * Any differences that cannot be handled will cause an error.
+ * Normally, only one change can be managed at a time.
+ */
+static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
+{
+       int rv = 0;
+       int cnt = 0;
+
+       if (mddev->major_version != info->major_version ||
+           mddev->minor_version != info->minor_version ||
+/*         mddev->patch_version != info->patch_version || */
+           mddev->ctime         != info->ctime         ||
+           mddev->level         != info->level         ||
+           mddev->layout        != info->layout        ||
+           !mddev->persistent   != info->not_persistent||
+           mddev->chunk_size    != info->chunk_size    )
+               return -EINVAL;
+       /* Check there is only one change */
+       if (mddev->size != info->size) cnt++;
+       if (mddev->raid_disks != info->raid_disks) cnt++;
+       if (cnt == 0) return 0;
+       if (cnt > 1) return -EINVAL;
+
+       if (mddev->size != info->size) {
+               mdk_rdev_t * rdev;
+               struct list_head *tmp;
+               if (mddev->pers->resize == NULL)
+                       return -EINVAL;
+               /* The "size" is the amount of each device that is used.
+                * This can only make sense for arrays with redundancy.
+                * linear and raid0 always use whatever space is available
+                * We can only consider changing the size of no resync
+                * or reconstruction is happening, and if the new size
+                * is acceptable. It must fit before the sb_offset or,
+                * if that is <data_offset, it must fit before the
+                * size of each device.
+                * If size is zero, we find the largest size that fits.
+                */
+               if (mddev->sync_thread)
+                       return -EBUSY;
+               ITERATE_RDEV(mddev,rdev,tmp) {
+                       sector_t avail;
+                       int fit = (info->size == 0);
+                       if (rdev->sb_offset > rdev->data_offset)
+                               avail = (rdev->sb_offset*2) - rdev->data_offset;
+                       else
+                               avail = get_capacity(rdev->bdev->bd_disk)
+                                       - rdev->data_offset;
+                       if (fit && (info->size == 0 || info->size > avail/2))
+                               info->size = avail/2;
+                       if (avail < ((sector_t)info->size << 1))
+                               return -ENOSPC;
+               }
+               rv = mddev->pers->resize(mddev, (sector_t)info->size *2);
+               if (!rv) {
+                       struct block_device *bdev;
+
+                       bdev = bdget_disk(mddev->gendisk, 0);
+                       if (bdev) {
+                               down(&bdev->bd_inode->i_sem);
+                               i_size_write(bdev->bd_inode, mddev->array_size << 10);
+                               up(&bdev->bd_inode->i_sem);
+                               bdput(bdev);
+                       }
+               }
+       }
+       if (mddev->raid_disks    != info->raid_disks) {
+               /* change the number of raid disks */
+               if (mddev->pers->reshape == NULL)
+                       return -EINVAL;
+               if (info->raid_disks <= 0 ||
+                   info->raid_disks >= mddev->max_disks)
+                       return -EINVAL;
+               if (mddev->sync_thread)
+                       return -EBUSY;
+               rv = mddev->pers->reshape(mddev, info->raid_disks);
+               if (!rv) {
+                       struct block_device *bdev;
+
+                       bdev = bdget_disk(mddev->gendisk, 0);
+                       if (bdev) {
+                               down(&bdev->bd_inode->i_sem);
+                               i_size_write(bdev->bd_inode, mddev->array_size << 10);
+                               up(&bdev->bd_inode->i_sem);
+                               bdput(bdev);
+                       }
+               }
+       }
+       md_update_sb(mddev);
+       return rv;
+}
+
 static int set_disk_faulty(mddev_t *mddev, dev_t dev)
 {
        mdk_rdev_t *rdev;
@@ -2389,7 +2491,8 @@ static int md_ioctl(struct inode *inode, struct file *file,
 {
        char b[BDEVNAME_SIZE];
        int err = 0;
-       struct hd_geometry *loc = (struct hd_geometry *) arg;
+       void __user *argp = (void __user *)arg;
+       struct hd_geometry __user *loc = argp;
        mddev_t *mddev = NULL;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -2402,7 +2505,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
        switch (cmd)
        {
                case RAID_VERSION:
-                       err = get_version((void *)arg);
+                       err = get_version(argp);
                        goto done;
 
                case PRINT_RAID_DEBUG:
@@ -2463,33 +2566,41 @@ static int md_ioctl(struct inode *inode, struct file *file,
        switch (cmd)
        {
                case SET_ARRAY_INFO:
-
-                       if (!list_empty(&mddev->disks)) {
-                               printk(KERN_WARNING 
-                                       "md: array %s already has disks!\n",
-                                       mdname(mddev));
-                               err = -EBUSY;
-                               goto abort_unlock;
-                       }
-                       if (mddev->raid_disks) {
-                               printk(KERN_WARNING 
-                                       "md: array %s already initialised!\n",
-                                       mdname(mddev));
-                               err = -EBUSY;
-                               goto abort_unlock;
-                       }
                        {
                                mdu_array_info_t info;
                                if (!arg)
                                        memset(&info, 0, sizeof(info));
-                               else if (copy_from_user(&info, (void*)arg, sizeof(info))) {
+                               else if (copy_from_user(&info, argp, sizeof(info))) {
                                        err = -EFAULT;
                                        goto abort_unlock;
                                }
+                               if (mddev->pers) {
+                                       err = update_array_info(mddev, &info);
+                                       if (err) {
+                                               printk(KERN_WARNING "md: couldn't update"
+                                                      " array info. %d\n", err);
+                                               goto abort_unlock;
+                                       }
+                                       goto done_unlock;
+                               }
+                               if (!list_empty(&mddev->disks)) {
+                                       printk(KERN_WARNING
+                                              "md: array %s already has disks!\n",
+                                              mdname(mddev));
+                                       err = -EBUSY;
+                                       goto abort_unlock;
+                               }
+                               if (mddev->raid_disks) {
+                                       printk(KERN_WARNING
+                                              "md: array %s already initialised!\n",
+                                              mdname(mddev));
+                                       err = -EBUSY;
+                                       goto abort_unlock;
+                               }
                                err = set_array_info(mddev, &info);
                                if (err) {
                                        printk(KERN_WARNING "md: couldn't set"
-                                               " array info. %d\n", err);
+                                              " array info. %d\n", err);
                                        goto abort_unlock;
                                }
                        }
@@ -2513,11 +2624,11 @@ static int md_ioctl(struct inode *inode, struct file *file,
        switch (cmd)
        {
                case GET_ARRAY_INFO:
-                       err = get_array_info(mddev, (void *)arg);
+                       err = get_array_info(mddev, argp);
                        goto done_unlock;
 
                case GET_DISK_INFO:
-                       err = get_disk_info(mddev, (void *)arg);
+                       err = get_disk_info(mddev, argp);
                        goto done_unlock;
 
                case RESTART_ARRAY_RW:
@@ -2543,18 +2654,18 @@ static int md_ioctl(struct inode *inode, struct file *file,
                                err = -EINVAL;
                                goto abort_unlock;
                        }
-                       err = put_user (2, (char *) &loc->heads);
+                       err = put_user (2, (char __user *) &loc->heads);
                        if (err)
                                goto abort_unlock;
-                       err = put_user (4, (char *) &loc->sectors);
+                       err = put_user (4, (char __user *) &loc->sectors);
                        if (err)
                                goto abort_unlock;
                        err = put_user(get_capacity(mddev->gendisk)/8,
-                                               (short *) &loc->cylinders);
+                                       (short __user *) &loc->cylinders);
                        if (err)
                                goto abort_unlock;
                        err = put_user (get_start_sect(inode->i_bdev),
-                                               (long *) &loc->start);
+                                               (long __user *) &loc->start);
                        goto done_unlock;
        }
 
@@ -2573,7 +2684,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
                case ADD_NEW_DISK:
                {
                        mdu_disk_info_t info;
-                       if (copy_from_user(&info, (void*)arg, sizeof(info)))
+                       if (copy_from_user(&info, argp, sizeof(info)))
                                err = -EFAULT;
                        else
                                err = add_new_disk(mddev, &info);
@@ -3278,7 +3389,7 @@ static void md_do_sync(mddev_t *mddev)
                j += sectors;
                if (j>1) mddev->curr_resync = j;
 
-               if (last_check + window > j)
+               if (last_check + window > j || j == max_sectors)
                        continue;
 
                last_check = j;
@@ -3444,8 +3555,8 @@ void md_check_recovery(mddev_t *mddev)
                        if (rdev->raid_disk >= 0 &&
                            rdev->faulty &&
                            atomic_read(&rdev->nr_pending)==0) {
-                               mddev->pers->hot_remove_disk(mddev, rdev->raid_disk);
-                               rdev->raid_disk = -1;
+                               if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0)
+                                       rdev->raid_disk = -1;
                        }
                        if (!rdev->faulty && rdev->raid_disk >= 0 && !rdev->in_sync)
                                spares++;
index 8f675d1..3d87901 100644 (file)
@@ -54,9 +54,8 @@ static void mp_pool_free(void *mpb, void *data)
        kfree(mpb);
 }
 
-static int multipath_map (mddev_t *mddev, mdk_rdev_t **rdevp)
+static int multipath_map (multipath_conf_t *conf)
 {
-       multipath_conf_t *conf = mddev_to_conf(mddev);
        int i, disks = conf->raid_disks;
 
        /*
@@ -68,10 +67,9 @@ static int multipath_map (mddev_t *mddev, mdk_rdev_t **rdevp)
        for (i = 0; i < disks; i++) {
                mdk_rdev_t *rdev = conf->multipaths[i].rdev;
                if (rdev && rdev->in_sync) {
-                       *rdevp = rdev;
                        atomic_inc(&rdev->nr_pending);
                        spin_unlock_irq(&conf->device_lock);
-                       return 0;
+                       return i;
                }
        }
        spin_unlock_irq(&conf->device_lock);
@@ -133,25 +131,7 @@ int multipath_end_request(struct bio *bio, unsigned int bytes_done, int error)
                       (unsigned long long)bio->bi_sector);
                multipath_reschedule_retry(mp_bh);
        }
-       atomic_dec(&rdev->nr_pending);
-       return 0;
-}
-
-/*
- * This routine returns the disk from which the requested read should
- * be done.
- */
-
-static int multipath_read_balance (multipath_conf_t *conf)
-{
-       int disk;
-
-       for (disk = 0; disk < conf->raid_disks; disk++) {
-               mdk_rdev_t *rdev = conf->multipaths[disk].rdev;
-               if (rdev && rdev->in_sync)
-                       return disk;
-       }
-       BUG();
+       rdev_dec_pending(rdev, conf->mddev);
        return 0;
 }
 
@@ -204,14 +184,14 @@ static int multipath_make_request (request_queue_t *q, struct bio * bio)
                disk_stat_inc(mddev->gendisk, reads);
                disk_stat_add(mddev->gendisk, read_sectors, bio_sectors(bio));
        }
-       /*
-        * read balancing logic:
-        */
-       spin_lock_irq(&conf->device_lock);
-       mp_bh->path = multipath_read_balance(conf);
+
+       mp_bh->path = multipath_map(conf);
+       if (mp_bh->path < 0) {
+               bio_endio(bio, bio->bi_size, -EIO);
+               mempool_free(mp_bh, conf->pool);
+               return 0;
+       }
        multipath = conf->multipaths + mp_bh->path;
-       atomic_inc(&multipath->rdev->nr_pending);
-       spin_unlock_irq(&conf->device_lock);
 
        mp_bh->bio = *bio;
        mp_bh->bio.bi_bdev = multipath->rdev->bdev;
@@ -375,7 +355,7 @@ static void multipathd (mddev_t *mddev)
        struct multipath_bh *mp_bh;
        struct bio *bio;
        unsigned long flags;
-       mdk_rdev_t *rdev;
+       multipath_conf_t *conf = mddev_to_conf(mddev);
 
        md_check_recovery(mddev);
        for (;;) {
@@ -391,8 +371,7 @@ static void multipathd (mddev_t *mddev)
                bio = &mp_bh->bio;
                bio->bi_sector = mp_bh->master_bio->bi_sector;
                
-               rdev = NULL;
-               if (multipath_map (mddev, &rdev)<0) {
+               if ((mp_bh->path = multipath_map (conf))<0) {
                        printk(KERN_ALERT "multipath: %s: unrecoverable IO read"
                                " error for block %llu\n",
                                bdevname(bio->bi_bdev,b),
@@ -403,7 +382,7 @@ static void multipathd (mddev_t *mddev)
                                " to another IO path\n",
                                bdevname(bio->bi_bdev,b),
                                (unsigned long long)bio->bi_sector);
-                       bio->bi_bdev = rdev->bdev;
+                       bio->bi_bdev = conf->multipaths[mp_bh->path].rdev->bdev;
                        generic_make_request(bio);
                }
        }
index c600b1b..d271b8e 100644 (file)
@@ -42,16 +42,17 @@ static void unplug_slaves(mddev_t *mddev);
 
 static void * r1bio_pool_alloc(int gfp_flags, void *data)
 {
-       mddev_t *mddev = data;
+       struct pool_info *pi = data;
        r1bio_t *r1_bio;
 
        /* allocate a r1bio with room for raid_disks entries in the bios array */
-       r1_bio = kmalloc(sizeof(r1bio_t) + sizeof(struct bio*)*mddev->raid_disks,
+       r1_bio = kmalloc(sizeof(r1bio_t) + sizeof(struct bio*)*pi->raid_disks,
                         gfp_flags);
        if (r1_bio)
-               memset(r1_bio, 0, sizeof(*r1_bio) + sizeof(struct bio*)*mddev->raid_disks);
+               memset(r1_bio, 0, sizeof(*r1_bio) +
+                              sizeof(struct bio*) * pi->raid_disks);
        else
-               unplug_slaves(mddev);
+               unplug_slaves(pi->mddev);
 
        return r1_bio;
 }
@@ -69,22 +70,22 @@ static void r1bio_pool_free(void *r1_bio, void *data)
 
 static void * r1buf_pool_alloc(int gfp_flags, void *data)
 {
-       conf_t *conf = data;
+       struct pool_info *pi = data;
        struct page *page;
        r1bio_t *r1_bio;
        struct bio *bio;
        int i, j;
 
-       r1_bio = r1bio_pool_alloc(gfp_flags, conf->mddev);
+       r1_bio = r1bio_pool_alloc(gfp_flags, pi);
        if (!r1_bio) {
-               unplug_slaves(conf->mddev);
+               unplug_slaves(pi->mddev);
                return NULL;
        }
 
        /*
         * Allocate bios : 1 for reading, n-1 for writing
         */
-       for (j = conf->raid_disks ; j-- ; ) {
+       for (j = pi->raid_disks ; j-- ; ) {
                bio = bio_alloc(gfp_flags, RESYNC_PAGES);
                if (!bio)
                        goto out_free_bio;
@@ -111,16 +112,16 @@ out_free_pages:
        for ( ; i > 0 ; i--)
                __free_page(bio->bi_io_vec[i-1].bv_page);
 out_free_bio:
-       while ( ++j < conf->raid_disks )
+       while ( ++j < pi->raid_disks )
                bio_put(r1_bio->bios[j]);
-       r1bio_pool_free(r1_bio, conf->mddev);
+       r1bio_pool_free(r1_bio, data);
        return NULL;
 }
 
 static void r1buf_pool_free(void *__r1_bio, void *data)
 {
+       struct pool_info *pi = data;
        int i;
-       conf_t *conf = data;
        r1bio_t *r1bio = __r1_bio;
        struct bio *bio = r1bio->bios[0];
 
@@ -128,10 +129,10 @@ static void r1buf_pool_free(void *__r1_bio, void *data)
                __free_page(bio->bi_io_vec[i].bv_page);
                bio->bi_io_vec[i].bv_page = NULL;
        }
-       for (i=0 ; i < conf->raid_disks; i++)
+       for (i=0 ; i < pi->raid_disks; i++)
                bio_put(r1bio->bios[i]);
 
-       r1bio_pool_free(r1bio, conf->mddev);
+       r1bio_pool_free(r1bio, data);
 }
 
 static void put_all_bios(conf_t *conf, r1bio_t *r1_bio)
@@ -296,7 +297,7 @@ static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int
                reschedule_retry(r1_bio);
        }
 
-       atomic_dec(&conf->mirrors[mirror].rdev->nr_pending);
+       rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
        return 0;
 }
 
@@ -343,7 +344,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
                raid_end_bio_io(r1_bio);
        }
 
-       atomic_dec(&conf->mirrors[mirror].rdev->nr_pending);
+       rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
        return 0;
 }
 
@@ -375,7 +376,8 @@ static int read_balance(conf_t *conf, struct bio *bio, r1bio_t *r1_bio)
         * device if no resync is going on, or below the resync window.
         * We take the first readable disk when above the resync window.
         */
-       if (!conf->mddev->in_sync && (this_sector + sectors >= conf->next_resync)) {
+       if (conf->mddev->recovery_cp < MaxSector &&
+           (this_sector + sectors >= conf->next_resync)) {
                /* make sure that disk is operational */
                new_disk = 0;
 
@@ -510,7 +512,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
        mirror_info_t *mirror;
        r1bio_t *r1_bio;
        struct bio *read_bio;
-       int i, disks = conf->raid_disks;
+       int i, disks;
 
        /*
         * Register the new request and wait if the reconstruction
@@ -570,6 +572,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
         * inc refcount on their rdev.  Record them by setting
         * bios[x] to bio
         */
+       disks = conf->raid_disks;
        spin_lock_irq(&conf->device_lock);
        for (i = 0;  i < disks; i++) {
                if (conf->mirrors[i].rdev &&
@@ -805,7 +808,7 @@ static int end_sync_read(struct bio *bio, unsigned int bytes_done, int error)
                         conf->mirrors[r1_bio->read_disk].rdev);
        else
                set_bit(R1BIO_Uptodate, &r1_bio->state);
-       atomic_dec(&conf->mirrors[r1_bio->read_disk].rdev->nr_pending);
+       rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev);
        reschedule_retry(r1_bio);
        return 0;
 }
@@ -835,7 +838,7 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error)
                md_done_sync(mddev, r1_bio->sectors, uptodate);
                put_buf(r1_bio);
        }
-       atomic_dec(&conf->mirrors[mirror].rdev->nr_pending);
+       rdev_dec_pending(conf->mirrors[mirror].rdev, mddev);
        return 0;
 }
 
@@ -953,7 +956,8 @@ static int init_resync(conf_t *conf)
        buffs = RESYNC_WINDOW / RESYNC_BLOCK_SIZE;
        if (conf->r1buf_pool)
                BUG();
-       conf->r1buf_pool = mempool_create(buffs, r1buf_pool_alloc, r1buf_pool_free, conf);
+       conf->r1buf_pool = mempool_create(buffs, r1buf_pool_alloc, r1buf_pool_free,
+                                         conf->poolinfo);
        if (!conf->r1buf_pool)
                return -ENOMEM;
        conf->next_resync = 0;
@@ -979,6 +983,7 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
        sector_t max_sector, nr_sectors;
        int disk;
        int i;
+       int write_targets = 0;
 
        if (!conf->r1buf_pool)
                if (init_resync(conf))
@@ -1055,12 +1060,24 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
                            sector_nr + RESYNC_SECTORS > mddev->recovery_cp)) {
                        bio->bi_rw = WRITE;
                        bio->bi_end_io = end_sync_write;
+                       write_targets ++;
                } else
                        continue;
                bio->bi_sector = sector_nr + conf->mirrors[i].rdev->data_offset;
                bio->bi_bdev = conf->mirrors[i].rdev->bdev;
                bio->bi_private = r1_bio;
        }
+       if (write_targets == 0) {
+               /* There is nowhere to write, so all non-sync
+                * drives must be failed - so we are finished
+                */
+               int rv = max_sector - sector_nr;
+               md_done_sync(mddev, rv, 1);
+               put_buf(r1_bio);
+               atomic_dec(&conf->mirrors[disk].rdev->nr_pending);
+               return rv;
+       }
+
        nr_sectors = 0;
        do {
                struct page *page;
@@ -1123,28 +1140,28 @@ static int run(mddev_t *mddev)
         */
        conf = kmalloc(sizeof(conf_t), GFP_KERNEL);
        mddev->private = conf;
-       if (!conf) {
-               printk(KERN_ERR "raid1: couldn't allocate memory for %s\n",
-                       mdname(mddev));
-               goto out;
-       }
+       if (!conf)
+               goto out_no_mem;
+
        memset(conf, 0, sizeof(*conf));
        conf->mirrors = kmalloc(sizeof(struct mirror_info)*mddev->raid_disks, 
                                 GFP_KERNEL);
-       if (!conf->mirrors) {
-               printk(KERN_ERR "raid1: couldn't allocate memory for %s\n",
-                      mdname(mddev));
-               goto out_free_conf;
-       }
+       if (!conf->mirrors)
+               goto out_no_mem;
+
        memset(conf->mirrors, 0, sizeof(struct mirror_info)*mddev->raid_disks);
 
+       conf->poolinfo = kmalloc(sizeof(*conf->poolinfo), GFP_KERNEL);
+       if (!conf->poolinfo)
+               goto out_no_mem;
+       conf->poolinfo->mddev = mddev;
+       conf->poolinfo->raid_disks = mddev->raid_disks;
        conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc,
-                                               r1bio_pool_free, mddev);
-       if (!conf->r1bio_pool) {
-               printk(KERN_ERR "raid1: couldn't allocate memory for %s\n", 
-                       mdname(mddev));
-               goto out_free_conf;
-       }
+                                         r1bio_pool_free,
+                                         conf->poolinfo);
+       if (!conf->r1bio_pool)
+               goto out_no_mem;
+
        mddev->queue->unplug_fn = raid1_unplug;
 
 
@@ -1230,13 +1247,21 @@ static int run(mddev_t *mddev)
 
        return 0;
 
+out_no_mem:
+       printk(KERN_ERR "raid1: couldn't allocate memory for %s\n",
+              mdname(mddev));
+
 out_free_conf:
-       if (conf->r1bio_pool)
-               mempool_destroy(conf->r1bio_pool);
-       if (conf->mirrors)
-               kfree(conf->mirrors);
-       kfree(conf);
-       mddev->private = NULL;
+       if (conf) {
+               if (conf->r1bio_pool)
+                       mempool_destroy(conf->r1bio_pool);
+               if (conf->mirrors)
+                       kfree(conf->mirrors);
+               if (conf->poolinfo)
+                       kfree(conf->poolinfo);
+               kfree(conf);
+               mddev->private = NULL;
+       }
 out:
        return -EIO;
 }
@@ -1251,11 +1276,108 @@ static int stop(mddev_t *mddev)
                mempool_destroy(conf->r1bio_pool);
        if (conf->mirrors)
                kfree(conf->mirrors);
+       if (conf->poolinfo)
+               kfree(conf->poolinfo);
        kfree(conf);
        mddev->private = NULL;
        return 0;
 }
 
+static int raid1_resize(mddev_t *mddev, sector_t sectors)
+{
+       /* no resync is happening, and there is enough space
+        * on all devices, so we can resize.
+        * We need to make sure resync covers any new space.
+        * If the array is shrinking we should possibly wait until
+        * any io in the removed space completes, but it hardly seems
+        * worth it.
+        */
+       mddev->array_size = sectors>>1;
+       set_capacity(mddev->gendisk, mddev->array_size << 1);
+       mddev->changed = 1;
+       if (mddev->array_size > mddev->size && mddev->recovery_cp == MaxSector) {
+               mddev->recovery_cp = mddev->size << 1;
+               set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+       }
+       mddev->size = mddev->array_size;
+       return 0;
+}
+
+static int raid1_reshape(mddev_t *mddev, int raid_disks)
+{
+       /* We need to:
+        * 1/ resize the r1bio_pool
+        * 2/ resize conf->mirrors
+        *
+        * We allocate a new r1bio_pool if we can.
+        * Then raise a device barrier and wait until all IO stops.
+        * Then resize conf->mirrors and swap in the new r1bio pool.
+        */
+       mempool_t *newpool, *oldpool;
+       struct pool_info *newpoolinfo;
+       mirror_info_t *newmirrors;
+       conf_t *conf = mddev_to_conf(mddev);
+
+       int d;
+
+       for (d= raid_disks; d < conf->raid_disks; d++)
+               if (conf->mirrors[d].rdev)
+                       return -EBUSY;
+
+       newpoolinfo = kmalloc(sizeof(newpoolinfo), GFP_KERNEL);
+       if (!newpoolinfo)
+               return -ENOMEM;
+       newpoolinfo->mddev = mddev;
+       newpoolinfo->raid_disks = raid_disks;
+
+       newpool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc,
+                                r1bio_pool_free, newpoolinfo);
+       if (!newpool) {
+               kfree(newpoolinfo);
+               return -ENOMEM;
+       }
+       newmirrors = kmalloc(sizeof(struct mirror_info) * raid_disks, GFP_KERNEL);
+       if (!newmirrors) {
+               kfree(newpoolinfo);
+               mempool_destroy(newpool);
+               return -ENOMEM;
+       }
+       memset(newmirrors, 0, sizeof(struct mirror_info)*raid_disks);
+
+       spin_lock_irq(&conf->resync_lock);
+       conf->barrier++;
+       wait_event_lock_irq(conf->wait_idle, !conf->nr_pending,
+                           conf->resync_lock, unplug_slaves(mddev));
+       spin_unlock_irq(&conf->resync_lock);
+
+       /* ok, everything is stopped */
+       oldpool = conf->r1bio_pool;
+       conf->r1bio_pool = newpool;
+       for (d=0; d < raid_disks && d < conf->raid_disks; d++)
+               newmirrors[d] = conf->mirrors[d];
+       kfree(conf->mirrors);
+       conf->mirrors = newmirrors;
+       kfree(conf->poolinfo);
+       conf->poolinfo = newpoolinfo;
+
+       mddev->degraded += (raid_disks - conf->raid_disks);
+       conf->raid_disks = mddev->raid_disks = raid_disks;
+
+       spin_lock_irq(&conf->resync_lock);
+       conf->barrier--;
+       spin_unlock_irq(&conf->resync_lock);
+       wake_up(&conf->wait_resume);
+       wake_up(&conf->wait_idle);
+
+
+       set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+       md_wakeup_thread(mddev->thread);
+
+       mempool_destroy(oldpool);
+       return 0;
+}
+
+
 static mdk_personality_t raid1_personality =
 {
        .name           = "raid1",
@@ -1269,6 +1391,8 @@ static mdk_personality_t raid1_personality =
        .hot_remove_disk= raid1_remove_disk,
        .spare_active   = raid1_spare_active,
        .sync_request   = sync_request,
+       .resize         = raid1_resize,
+       .reshape        = raid1_reshape,
 };
 
 static int __init raid_init(void)
index 402edd5..773f9bf 100644 (file)
@@ -395,7 +395,7 @@ static int raid5_end_read_request (struct bio * bi, unsigned int bytes_done,
                md_error(conf->mddev, conf->disks[i].rdev);
                clear_bit(R5_UPTODATE, &sh->dev[i].flags);
        }
-       atomic_dec(&conf->disks[i].rdev->nr_pending);
+       rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
 #if 0
        /* must restore b_page before unlocking buffer... */
        if (sh->bh_page[i] != bh->b_page) {
@@ -438,7 +438,7 @@ static int raid5_end_write_request (struct bio *bi, unsigned int bytes_done,
        if (!uptodate)
                md_error(conf->mddev, conf->disks[i].rdev);
 
-       atomic_dec(&conf->disks[i].rdev->nr_pending);
+       rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
        
        clear_bit(R5_LOCKED, &sh->dev[i].flags);
        set_bit(STRIPE_HANDLE, &sh->state);
@@ -1037,7 +1037,7 @@ static void handle_stripe(struct stripe_head *sh)
         * parity, or to satisfy requests
         * or to load a block that is being partially written.
         */
-       if (to_read || non_overwrite || (syncing && (uptodate+failed < disks))) {
+       if (to_read || non_overwrite || (syncing && (uptodate < disks))) {
                for (i=disks; i--;) {
                        dev = &sh->dev[i];
                        if (!test_bit(R5_LOCKED, &dev->flags) && !test_bit(R5_UPTODATE, &dev->flags) &&
@@ -1577,6 +1577,9 @@ static int run (mddev_t *mddev)
        conf->algorithm = mddev->layout;
        conf->max_nr_stripes = NR_STRIPES;
 
+       /* device size must be a multiple of chunk size */
+       mddev->size &= ~(mddev->chunk_size/1024 -1);
+
        if (!conf->chunk_size || conf->chunk_size % 4) {
                printk(KERN_ERR "raid5: invalid chunk size %d for %s\n",
                        conf->chunk_size, mdname(mddev));
@@ -1828,6 +1831,27 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
        return found;
 }
 
+static int raid5_resize(mddev_t *mddev, sector_t sectors)
+{
+       /* no resync is happening, and there is enough space
+        * on all devices, so we can resize.
+        * We need to make sure resync covers any new space.
+        * If the array is shrinking we should possibly wait until
+        * any io in the removed space completes, but it hardly seems
+        * worth it.
+        */
+       sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
+       mddev->array_size = (sectors * (mddev->raid_disks-1))>>1;
+       set_capacity(mddev->gendisk, mddev->array_size << 1);
+       mddev->changed = 1;
+       if (sectors/2  > mddev->size && mddev->recovery_cp == MaxSector) {
+               mddev->recovery_cp = mddev->size << 1;
+               set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+       }
+       mddev->size = sectors /2;
+       return 0;
+}
+
 static mdk_personality_t raid5_personality=
 {
        .name           = "raid5",
@@ -1841,6 +1865,7 @@ static mdk_personality_t raid5_personality=
        .hot_remove_disk= raid5_remove_disk,
        .spare_active   = raid5_spare_active,
        .sync_request   = sync_request,
+       .resize         = raid5_resize,
 };
 
 static int __init raid5_init (void)
index ceaec27..714dfb2 100644 (file)
@@ -414,7 +414,7 @@ static int raid6_end_read_request (struct bio * bi, unsigned int bytes_done,
                md_error(conf->mddev, conf->disks[i].rdev);
                clear_bit(R5_UPTODATE, &sh->dev[i].flags);
        }
-       atomic_dec(&conf->disks[i].rdev->nr_pending);
+       rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
 #if 0
        /* must restore b_page before unlocking buffer... */
        if (sh->bh_page[i] != bh->b_page) {
@@ -457,7 +457,7 @@ static int raid6_end_write_request (struct bio *bi, unsigned int bytes_done,
        if (!uptodate)
                md_error(conf->mddev, conf->disks[i].rdev);
 
-       atomic_dec(&conf->disks[i].rdev->nr_pending);
+       rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
 
        clear_bit(R5_LOCKED, &sh->dev[i].flags);
        set_bit(STRIPE_HANDLE, &sh->state);
@@ -1157,7 +1157,7 @@ static void handle_stripe(struct stripe_head *sh)
         * parity, or to satisfy requests
         * or to load a block that is being partially written.
         */
-       if (to_read || non_overwrite || (syncing && (uptodate+failed < disks))) {
+       if (to_read || non_overwrite || (syncing && (uptodate < disks))) {
                for (i=disks; i--;) {
                        dev = &sh->dev[i];
                        if (!test_bit(R5_LOCKED, &dev->flags) && !test_bit(R5_UPTODATE, &dev->flags) &&
@@ -1741,6 +1741,9 @@ static int run (mddev_t *mddev)
        conf->algorithm = mddev->layout;
        conf->max_nr_stripes = NR_STRIPES;
 
+       /* device size must be a multiple of chunk size */
+       mddev->size &= ~(mddev->chunk_size/1024 -1);
+
        if (conf->raid_disks < 4) {
                printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n",
                       mdname(mddev), conf->raid_disks);
@@ -1997,6 +2000,27 @@ static int raid6_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
        return found;
 }
 
+static int raid6_resize(mddev_t *mddev, sector_t sectors)
+{
+       /* no resync is happening, and there is enough space
+        * on all devices, so we can resize.
+        * We need to make sure resync covers any new space.
+        * If the array is shrinking we should possibly wait until
+        * any io in the removed space completes, but it hardly seems
+        * worth it.
+        */
+       sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
+       mddev->array_size = (sectors * (mddev->raid_disks-2))>>1;
+       set_capacity(mddev->gendisk, mddev->array_size << 1);
+       mddev->changed = 1;
+       if (sectors/2  > mddev->size && mddev->recovery_cp == MaxSector) {
+               mddev->recovery_cp = mddev->size << 1;
+               set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+       }
+       mddev->size = sectors /2;
+       return 0;
+}
+
 static mdk_personality_t raid6_personality=
 {
        .name           = "raid6",
@@ -2010,6 +2034,7 @@ static mdk_personality_t raid6_personality=
        .hot_remove_disk= raid6_remove_disk,
        .spare_active   = raid6_spare_active,
        .sync_request   = sync_request,
+       .resize         = raid6_resize,
 };
 
 static int __init raid6_init (void)
index 26995e2..a61e91a 100644 (file)
@@ -396,7 +396,7 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
        return 0;
 }
 
-static ssize_t fops_read(struct file *file, char *data, size_t count, loff_t *ppos)
+static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
 {
        struct saa7146_fh *fh = file->private_data;
 
index 02dc94d..20d86a8 100644 (file)
@@ -190,6 +190,7 @@ static int tda10045h_fwinfo_count = sizeof(tda10045h_fwinfo) / sizeof(struct fwi
 static struct fwinfo tda10046h_fwinfo[] = { {.file_size = 286720,.fw_offset = 0x3c4f9,.fw_size = 24479} };
 static int tda10046h_fwinfo_count = sizeof(tda10046h_fwinfo) / sizeof(struct fwinfo);
 
+static int errno;
 
 
 static int tda1004x_write_byte(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg, int data)
index 5933adf..53b5a0f 100644 (file)
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <asm/io.h>
-#if defined (__sparc__)
-#include <linux/timer.h>
-#endif
-
-/* Hmmm, avoid undefined spinlock_t on lk-2.2.14-5.0 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-#include <asm/spinlock.h>
-#endif
 
 #define MODULEAUTHOR "Steven J. Ralston"
 #define COPYRIGHT "Copyright (c) 2001-2004 " MODULEAUTHOR
index 37b7618..d9a4d9f 100644 (file)
@@ -2,196 +2,7 @@
 
 #ifndef FUSION_LINUX_COMPAT_H
 #define FUSION_LINUX_COMPAT_H
-/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#include <linux/version.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#ifndef rwlock_init
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
-#endif
-
-#define SET_NICE(current,x) do {(current)->nice = (x);} while (0)
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-#      if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
-               typedef unsigned int dma_addr_t;
-#      endif
-#else
-#      if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,42)
-               typedef unsigned int dma_addr_t;
-#      endif
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
-/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-/* This block snipped from lk-2.2.18/include/linux/init.h { */
-/*
- * Used for initialization calls..
- */
-typedef int (*initcall_t)(void);
-typedef void (*exitcall_t)(void);
-
-#define __init_call    __attribute__ ((unused,__section__ (".initcall.init")))
-#define __exit_call    __attribute__ ((unused,__section__ (".exitcall.exit")))
-
-extern initcall_t __initcall_start, __initcall_end;
-
-#define __initcall(fn)                                                         \
-       static initcall_t __initcall_##fn __init_call = fn
-#define __exitcall(fn)                                                         \
-       static exitcall_t __exitcall_##fn __exit_call = fn
-
-#ifdef MODULE
-/* These macros create a dummy inline: gcc 2.9x does not count alias
- as usage, hence the `unused function' warning when __init functions
- are declared static. We use the dummy __*_module_inline functions
- both to kill the warning and check the type of the init/cleanup
- function. */
-typedef int (*__init_module_func_t)(void);
-typedef void (*__cleanup_module_func_t)(void);
-#define module_init(x) \
-       int init_module(void) __attribute__((alias(#x))); \
-       static inline __init_module_func_t __init_module_inline(void) \
-       { return x; }
-#define module_exit(x) \
-       void cleanup_module(void) __attribute__((alias(#x))); \
-       static inline __cleanup_module_func_t __cleanup_module_inline(void) \
-       { return x; }
-
-#else
-#define module_init(x) __initcall(x);
-#define module_exit(x) __exitcall(x);
-#endif
-/* } block snipped from lk-2.2.18/include/linux/init.h */
-
-/* This block snipped from lk-2.2.18/include/linux/sched.h { */
-/*
- * Used prior to schedule_timeout calls..
- */
-#define __set_current_state(state_value)       do { current->state = state_value; } while (0)
-#ifdef CONFIG_SMP
-#define set_current_state(state_value)         do { __set_current_state(state_value); mb(); } while (0)
-#else
-#define set_current_state(state_value)         __set_current_state(state_value)
-#endif
-/* } block snipped from lk-2.2.18/include/linux/sched.h */
-
-/* procfs compat stuff... */
-#define proc_mkdir(x,y)                        create_proc_entry(x, S_IFDIR, y)
-
-/* MUTEX compat stuff... */
-#define DECLARE_MUTEX(name)            struct semaphore name=MUTEX
-#define DECLARE_MUTEX_LOCKED(name)     struct semaphore name=MUTEX_LOCKED
-#define init_MUTEX(x)                  *(x)=MUTEX
-#define init_MUTEX_LOCKED(x)           *(x)=MUTEX_LOCKED
-
-/* Wait queues. */
-#define DECLARE_WAIT_QUEUE_HEAD(name)  \
-       struct wait_queue * (name) = NULL
-#define DECLARE_WAITQUEUE(name, task)  \
-       struct wait_queue (name) = { (task), NULL }
-
-#if defined(__sparc__) && defined(__sparc_v9__)
-/* The sparc64 ioremap implementation is wrong in 2.2.x,
- * but fixing it would break all of the drivers which
- * workaround it.  Fixed in 2.3.x onward. -DaveM
- */
-#define ARCH_IOREMAP(base)     ((unsigned long) (base))
-#else
-#define ARCH_IOREMAP(base)     ioremap(base)
-#endif
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#else          /* LINUX_VERSION_CODE must be >= KERNEL_VERSION(2,2,18) */
-
-/* No ioremap bugs in >2.3.x kernels. */
-#define ARCH_IOREMAP(base)     ioremap(base)
-
-/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#endif         /* LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) */
-
-
-/*
- * Inclined to use:
- *   #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
- * here, but MODULE_LICENSE defined in 2.4.9-6 and 2.4.9-13
- * breaks the rule:-(
- */
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(license)
-#endif
-
-
-/* PCI/driver subsystem { */
-#define PCI_BASEADDR_FLAGS(idx)         resource[idx].flags
-#define PCI_BASEADDR_START(idx)         resource[idx].start
-#define PCI_BASEADDR_SIZE(dev,idx)      (dev)->resource[idx].end - (dev)->resource[idx].start + 1
-
-/* Compatability for the 2.3.x PCI DMA API. */
-#ifndef PCI_DMA_BIDIRECTIONAL
-/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#define PCI_DMA_BIDIRECTIONAL  0
-#define PCI_DMA_TODEVICE       1
-#define PCI_DMA_FROMDEVICE     2
-#define PCI_DMA_NONE           3
-
-#ifdef __KERNEL__
-#include <asm/page.h>
-/* Pure 2^n version of get_order */
-static __inline__ int __get_order(unsigned long size)
-{
-       int order;
-
-       size = (size-1) >> (PAGE_SHIFT-1);
-       order = -1;
-       do {
-               size >>= 1;
-               order++;
-       } while (size);
-       return order;
-}
-#endif
-
-#define pci_alloc_consistent(hwdev, size, dma_handle) \
-({     void *__ret = (void *)__get_free_pages(GFP_ATOMIC, __get_order(size)); \
-       if (__ret != NULL) { \
-               memset(__ret, 0, size); \
-               *(dma_handle) = virt_to_bus(__ret); \
-       } \
-       __ret; \
-})
-
-#define pci_free_consistent(hwdev, size, vaddr, dma_handle) \
-       free_pages((unsigned long)vaddr, __get_order(size))
-
-#define pci_map_single(hwdev, ptr, size, direction) \
-       virt_to_bus(ptr);
-
-#define pci_unmap_single(hwdev, dma_addr, size, direction) \
-       do { /* Nothing to do */ } while (0)
-
-#define pci_map_sg(hwdev, sg, nents, direction)        (nents)
-#define pci_unmap_sg(hwdev, sg, nents, direction) \
-       do { /* Nothing to do */ } while(0)
-
-#define sg_dma_address(sg)     (virt_to_bus((sg)->address))
-#define sg_dma_len(sg)         ((sg)->length)
-
-/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#endif /* PCI_DMA_BIDIRECTIONAL */
-
-
-#define mpt_work_struct work_struct
-#define MPT_INIT_WORK(_task, _func, _data) INIT_WORK(_task, _func, _data)
-#define mpt_sync_irq(_irq) synchronize_irq(_irq)
 
 /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #endif /* _LINUX_COMPAT_H */
-
index 755732c..239328a 100644 (file)
@@ -47,18 +47,13 @@ typedef signed   short  S16;
 typedef unsigned short  U16;
 
 
-#if defined(unix) || defined(__arm) || defined(ALPHA)
-
-    typedef signed   int   S32;
-    typedef unsigned int   U32;
-
-#else
-
-    typedef signed   long  S32;
-    typedef unsigned long  U32;
-
-#endif
+typedef int32_t   S32;
+typedef u_int32_t U32;
 
+/*
+ *  The only way crap below could work on big-endian boxen would be if it
+ *  wasn't used at all.
+ */
 
 typedef struct _S64
 {
index fba96eb..b2d7333 100644 (file)
@@ -1311,14 +1311,14 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        mem_phys = msize = 0;
        port = psize = 0;
        for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
-               if (pdev->PCI_BASEADDR_FLAGS(ii) & PCI_BASE_ADDRESS_SPACE_IO) {
+               if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
                        /* Get I/O space! */
-                       port = pdev->PCI_BASEADDR_START(ii);
-                       psize = PCI_BASEADDR_SIZE(pdev,ii);
+                       port = pci_resource_start(pdev, ii);
+                       psize = pci_resource_len(pdev,ii);
                } else {
                        /* Get memmap */
-                       mem_phys = pdev->PCI_BASEADDR_START(ii);
-                       msize = PCI_BASEADDR_SIZE(pdev,ii);
+                       mem_phys = pci_resource_start(pdev, ii);
+                       msize = pci_resource_len(pdev,ii);
                        break;
                }
        }
@@ -1524,7 +1524,7 @@ mptbase_remove(struct pci_dev *pdev)
        CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
 
        ioc->active = 0;
-       mpt_sync_irq(pdev->irq);
+       synchronize_irq(pdev->irq);
 
        /* Clear any lingering interrupt */
        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
@@ -3799,7 +3799,8 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
 
                /*  Prime reply FIFO...  */
                dprintk((KERN_INFO MYNAM ": %s.reply_alloc  @ %p[%p], sz=%d bytes\n",
-                               ioc->name, mem, (void *)(ulong)ioc->reply_alloc_dma, reply_buffer_sz));
+                       ioc->name, ioc->reply_alloc, 
+                       (void *)(ulong)ioc->reply_alloc_dma, reply_buffer_sz));
 
                b = (unsigned long) ioc->reply_alloc;
                b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
@@ -3812,7 +3813,8 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
        
                /*  Request FIFO - WE manage this!  */
                dprintk((KERN_INFO MYNAM ": %s.req_alloc    @ %p[%p], sz=%d bytes\n",
-                               ioc->name, mem, (void *)(ulong)ioc->req_alloc_dma, request_buffer_sz));
+                       ioc->name, ioc->req_alloc,
+                       (void *)(ulong)ioc->req_alloc_dma, request_buffer_sz));
 
                b = (unsigned long) ioc->req_alloc;
                b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
index 8b44844..d0235cb 100644 (file)
 #define MPTBASE_H_INCLUDED
 /*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#include "linux_compat.h"      /* linux-2.2.x (vs. -2.4.x) tweaks */
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
 #include "scsi3.h"             /* SCSI defines */
 
 #include "lsi/mpi_type.h"
@@ -81,8 +85,8 @@
 #define COPYRIGHT      "Copyright (c) 1999-2004 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON       "3.01.06"
-#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.01.06"
+#define MPT_LINUX_VERSION_COMMON       "3.01.07"
+#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.01.07"
 #define WHAT_MAGIC_STRING              "@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
index 434ceb1..a0e9b19 100644 (file)
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
+#include <linux/compat.h>
 
 #include <linux/kdev_t.h>      /* needed for access to Scsi_Host struct */
 #include <linux/blkdev.h>
 #include "../../scsi/scsi.h"
-#include "../../scsi/hosts.h"
+#include <scsi/scsi_host.h>
 
 #define COPYRIGHT      "Copyright (c) 1999-2004 LSI Logic Corporation"
 #define MODULEAUTHOR   "Steven J. Ralston, Noah Romer, Pamela Delaney"
 #define my_VERSION     MPT_LINUX_VERSION_COMMON
 #define MYNAM          "mptctl"
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,62)
-EXPORT_NO_SYMBOLS;
-#endif
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
@@ -144,8 +142,8 @@ static int mptctl_hp_targetinfo(unsigned long arg);
 /*
  * Private function calls.
  */
-static int mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local);
-static int mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen);
+static int mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr);
+static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen);
 static MptSge_t *kbuf_alloc_2_sgl( int bytes, u32 dir, int sge_offset, int *frags,
                struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
 static void kfree_sgl( MptSge_t *sgl, dma_addr_t sgl_dma,
@@ -545,38 +543,6 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
        return 1;
 }
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *  struct file_operations functionality.
- *  Members:
- *     llseek, write, read, ioctl, open, release
- */
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)
-static loff_t
-mptctl_llseek(struct file *file, loff_t offset, int origin)
-{
-       return -ESPIPE;
-}
-#define no_llseek mptctl_llseek
-#endif
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static ssize_t
-mptctl_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
-{
-       printk(KERN_ERR MYNAM ": ioctl WRITE not yet supported\n");
-       return 0;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static ssize_t
-mptctl_read(struct file *file, char *buf, size_t count, loff_t *ptr)
-{
-       printk(KERN_ERR MYNAM ": ioctl READ not yet supported\n");
-       return 0;
-}
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  MPT ioctl handler
@@ -586,7 +552,7 @@ mptctl_read(struct file *file, char *buf, size_t count, loff_t *ptr)
 static int
 mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
-       mpt_ioctl_header        *uhdr = (mpt_ioctl_header *) arg;
+       mpt_ioctl_header __user *uhdr = (void __user *) arg;
        mpt_ioctl_header         khdr;
        int iocnum;
        unsigned iocnumX;
@@ -599,7 +565,7 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
        if (copy_from_user(&khdr, uhdr, sizeof(khdr))) {
                printk(KERN_ERR "%s::mptctl_ioctl() @%d - "
                                "Unable to copy mpt_ioctl_header data @ %p\n",
-                               __FILE__, __LINE__, (void*)uhdr);
+                               __FILE__, __LINE__, uhdr);
                return -EFAULT;
        }
        ret = -ENXIO;                           /* (-6) No such device or address */
@@ -671,7 +637,7 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
 
 static int mptctl_do_reset(unsigned long arg)
 {
-       struct mpt_ioctl_diag_reset *urinfo = (struct mpt_ioctl_diag_reset *) arg;
+       struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;
        struct mpt_ioctl_diag_reset krinfo;
        MPT_ADAPTER             *iocp;
 
@@ -680,7 +646,7 @@ static int mptctl_do_reset(unsigned long arg)
        if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
                printk(KERN_ERR "%s@%d::mptctl_do_reset - "
                                "Unable to copy mpt_ioctl_diag_reset struct @ %p\n",
-                               __FILE__, __LINE__, (void*)urinfo);
+                               __FILE__, __LINE__, urinfo);
                return -EFAULT;
        }
 
@@ -699,21 +665,6 @@ static int mptctl_do_reset(unsigned long arg)
        return 0;
 }
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int mptctl_open(struct inode *inode, struct file *file)
-{
-       /*
-        * Should support multiple management users
-        */
-       return 0;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int mptctl_release(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  * MPT FW download function.  Cast the arg into the mpt_fw_xfer structure.
@@ -734,14 +685,14 @@ static int mptctl_release(struct inode *inode, struct file *file)
 static int
 mptctl_fw_download(unsigned long arg)
 {
-       struct mpt_fw_xfer      *ufwdl = (struct mpt_fw_xfer *) arg;
+       struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;
        struct mpt_fw_xfer       kfwdl;
 
        dctlprintk((KERN_INFO "mptctl_fwdl called. mptctl_id = %xh\n", mptctl_id)); //tc
        if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) {
                printk(KERN_ERR "%s@%d::_ioctl_fwdl - "
                                "Unable to copy mpt_fw_xfer struct @ %p\n",
-                               __FILE__, __LINE__, (void*)ufwdl);
+                               __FILE__, __LINE__, ufwdl);
                return -EFAULT;
        }
 
@@ -763,7 +714,7 @@ mptctl_fw_download(unsigned long arg)
  *             -ENOMSG if FW upload returned bad status
  */
 static int
-mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
+mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
 {
        FWDownload_t            *dlmsg;
        MPT_FRAME_HDR           *mf;
@@ -892,7 +843,7 @@ mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
                        if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) {
                                printk(KERN_ERR "%s@%d::_ioctl_fwdl - "
                                                "Unable to copy f/w buffer hunk#%d @ %p\n",
-                                               __FILE__, __LINE__, n, (void*)ufwbuf);
+                                               __FILE__, __LINE__, n, ufwbuf);
                                goto fwdl_out;
                        }
                        fw_bytes_copied += bl->len;
@@ -1198,7 +1149,7 @@ kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTE
 static int
 mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
 {
-       struct mpt_ioctl_iocinfo *uarg = (struct mpt_ioctl_iocinfo *) arg;
+       struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;
        struct mpt_ioctl_iocinfo *karg;
        MPT_ADAPTER             *ioc;
        struct pci_dev          *pdev;
@@ -1238,7 +1189,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
        if (copy_from_user(karg, uarg, data_size)) {
                printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
                        "Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                kfree(karg);
                return -EFAULT;
        }
@@ -1278,10 +1229,8 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
        karg->pciId = pdev->device;
        pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
        karg->hwRev = revision;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
        karg->subSystemDevice = pdev->subsystem_device;
        karg->subSystemVendor = pdev->subsystem_vendor;
-#endif
 
        if (cim_rev == 1) {
                /* Get the PCI bus, device, and function numbers for the IOC
@@ -1335,10 +1284,10 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
 
        /* Copy the data from kernel memory to user memory
         */
-       if (copy_to_user((char *)arg, karg, data_size)) {
+       if (copy_to_user((char __user *)arg, karg, data_size)) {
                printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
                        "Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                kfree(karg);
                return -EFAULT;
        }
@@ -1360,7 +1309,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
 static int
 mptctl_gettargetinfo (unsigned long arg)
 {
-       struct mpt_ioctl_targetinfo *uarg = (struct mpt_ioctl_targetinfo *) arg;
+       struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
        struct mpt_ioctl_targetinfo karg;
        MPT_ADAPTER             *ioc;
        struct Scsi_Host        *sh;
@@ -1382,7 +1331,7 @@ mptctl_gettargetinfo (unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
                printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
                        "Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1500,21 +1449,21 @@ data_space_full:
 
        /* Copy part of the data from kernel memory to user memory
         */
-       if (copy_to_user((char *)arg, &karg,
+       if (copy_to_user((char __user *)arg, &karg,
                                sizeof(struct mpt_ioctl_targetinfo))) {
                printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
                        "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                kfree(pmem);
                return -EFAULT;
        }
 
        /* Copy the remaining data from kernel memory to user memory
         */
-       if (copy_to_user((char *) uarg->targetInfo, pmem, numBytes)) {
+       if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
                printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
                        "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)pdata);
+                               __FILE__, __LINE__, pdata);
                kfree(pmem);
                return -EFAULT;
        }
@@ -1535,7 +1484,7 @@ data_space_full:
 static int
 mptctl_readtest (unsigned long arg)
 {
-       struct mpt_ioctl_test   *uarg = (struct mpt_ioctl_test *) arg;
+       struct mpt_ioctl_test __user *uarg = (void __user *) arg;
        struct mpt_ioctl_test    karg;
        MPT_ADAPTER *ioc;
        int iocnum;
@@ -1544,7 +1493,7 @@ mptctl_readtest (unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
                printk(KERN_ERR "%s@%d::mptctl_readtest - "
                        "Unable to read in mpt_ioctl_test struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1571,10 +1520,10 @@ mptctl_readtest (unsigned long arg)
 
        /* Copy the data from kernel memory to user memory
         */
-       if (copy_to_user((char *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
+       if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
                printk(KERN_ERR "%s@%d::mptctl_readtest - "
                        "Unable to write out mpt_ioctl_test struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1595,7 +1544,7 @@ mptctl_readtest (unsigned long arg)
 static int
 mptctl_eventquery (unsigned long arg)
 {
-       struct mpt_ioctl_eventquery     *uarg = (struct mpt_ioctl_eventquery *) arg;
+       struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
        struct mpt_ioctl_eventquery      karg;
        MPT_ADAPTER *ioc;
        int iocnum;
@@ -1604,7 +1553,7 @@ mptctl_eventquery (unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
                printk(KERN_ERR "%s@%d::mptctl_eventquery - "
                        "Unable to read in mpt_ioctl_eventquery struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1620,10 +1569,10 @@ mptctl_eventquery (unsigned long arg)
 
        /* Copy the data from kernel memory to user memory
         */
-       if (copy_to_user((char *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
+       if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
                printk(KERN_ERR "%s@%d::mptctl_eventquery - "
                        "Unable to write out mpt_ioctl_eventquery struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
        return 0;
@@ -1633,7 +1582,7 @@ mptctl_eventquery (unsigned long arg)
 static int
 mptctl_eventenable (unsigned long arg)
 {
-       struct mpt_ioctl_eventenable    *uarg = (struct mpt_ioctl_eventenable *) arg;
+       struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
        struct mpt_ioctl_eventenable     karg;
        MPT_ADAPTER *ioc;
        int iocnum;
@@ -1642,7 +1591,7 @@ mptctl_eventenable (unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
                printk(KERN_ERR "%s@%d::mptctl_eventenable - "
                        "Unable to read in mpt_ioctl_eventenable struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1680,7 +1629,7 @@ mptctl_eventenable (unsigned long arg)
 static int
 mptctl_eventreport (unsigned long arg)
 {
-       struct mpt_ioctl_eventreport    *uarg = (struct mpt_ioctl_eventreport *) arg;
+       struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
        struct mpt_ioctl_eventreport     karg;
        MPT_ADAPTER              *ioc;
        int                      iocnum;
@@ -1690,7 +1639,7 @@ mptctl_eventreport (unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
                printk(KERN_ERR "%s@%d::mptctl_eventreport - "
                        "Unable to read in mpt_ioctl_eventreport struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1716,10 +1665,10 @@ mptctl_eventreport (unsigned long arg)
        /* Copy the data from kernel memory to user memory
         */
        numBytes = max * sizeof(MPT_IOCTL_EVENTS);
-       if (copy_to_user((char *) uarg->eventData, ioc->events, numBytes)) {
+       if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
                printk(KERN_ERR "%s@%d::mptctl_eventreport - "
                        "Unable to write out mpt_ioctl_eventreport struct @ %p\n",
-                               __FILE__, __LINE__, (void*)ioc->events);
+                               __FILE__, __LINE__, ioc->events);
                return -EFAULT;
        }
 
@@ -1730,7 +1679,7 @@ mptctl_eventreport (unsigned long arg)
 static int
 mptctl_replace_fw (unsigned long arg)
 {
-       struct mpt_ioctl_replace_fw     *uarg = (struct mpt_ioctl_replace_fw *) arg;
+       struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
        struct mpt_ioctl_replace_fw      karg;
        MPT_ADAPTER              *ioc;
        fw_image_t               **fwmem = NULL;
@@ -1744,7 +1693,7 @@ mptctl_replace_fw (unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
                printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
                        "Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1774,7 +1723,7 @@ mptctl_replace_fw (unsigned long arg)
                if (copy_from_user(fwmem[ii]->fw, uarg->newImage + offset, fwmem[ii]->size)) {
                        printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
                                "Unable to read in mpt_ioctl_replace_fw image @ %p\n",
-                                       __FILE__, __LINE__, (void*)uarg);
+                                       __FILE__, __LINE__, uarg);
 
                        mpt_free_fw_memory(ioc, fwmem);
                        return -EFAULT;
@@ -1819,7 +1768,7 @@ mptctl_replace_fw (unsigned long arg)
 static int
 mptctl_mpt_command (unsigned long arg)
 {
-       struct mpt_ioctl_command *uarg = (struct mpt_ioctl_command *) arg;
+       struct mpt_ioctl_command __user *uarg = (void __user *) arg;
        struct mpt_ioctl_command  karg;
        MPT_ADAPTER     *ioc;
        int             iocnum;
@@ -1830,7 +1779,7 @@ mptctl_mpt_command (unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
                printk(KERN_ERR "%s@%d::mptctl_mpt_command - "
                        "Unable to read in mpt_ioctl_command struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -1841,7 +1790,7 @@ mptctl_mpt_command (unsigned long arg)
                return -ENODEV;
        }
 
-       rc = mptctl_do_mpt_command (karg, (char *) &uarg->MF, 0);
+       rc = mptctl_do_mpt_command (karg, &uarg->MF);
 
        return rc;
 }
@@ -1859,7 +1808,7 @@ mptctl_mpt_command (unsigned long arg)
  *             -EPERM if SCSI I/O and target is untagged
  */
 static int
-mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
+mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
 {
        MPT_ADAPTER     *ioc;
        MPT_FRAME_HDR   *mf = NULL;
@@ -1923,23 +1872,15 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
 
        /* Copy the request frame
         * Reset the saved message context.
+        * Request frame in user space
         */
-        if (local) {
-               /* Request frame in kernel space
-                */
-               memcpy((char *)mf, (char *) mfPtr, karg.dataSgeOffset * 4);
-        } else {
-               /* Request frame in user space
-                */
-               if (copy_from_user((char *)mf, (char *) mfPtr,
-                                       karg.dataSgeOffset * 4)){
-                       printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
-                               "Unable to read MF from mpt_ioctl_command struct @ %p\n",
-                               __FILE__, __LINE__, (void*)mfPtr);
-                       rc = -EFAULT;
-                       goto done_free_mem;
-               }
-        }
+       if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
+               printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+                       "Unable to read MF from mpt_ioctl_command struct @ %p\n",
+                       __FILE__, __LINE__, mfPtr);
+               rc = -EFAULT;
+               goto done_free_mem;
+       }
        hdr->MsgContext = cpu_to_le32(msgContext);
 
 
@@ -2220,7 +2161,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
                                                "%s@%d::mptctl_do_mpt_command - Unable "
                                                "to read user data "
                                                "struct @ %p\n",
-                                               __FILE__, __LINE__,(void*)karg.dataOutBufPtr);
+                                               __FILE__, __LINE__,karg.dataOutBufPtr);
                                        rc =  -EFAULT;
                                        goto done_free_mem;
                                }
@@ -2321,12 +2262,12 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
                        }
 
                        if (sz > 0) {
-                               if (copy_to_user((char *)karg.replyFrameBufPtr,
+                               if (copy_to_user(karg.replyFrameBufPtr,
                                         &ioc->ioctl->ReplyFrame, sz)){
 
                                         printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
                                         "Unable to write out reply frame %p\n",
-                                        __FILE__, __LINE__, (void*)karg.replyFrameBufPtr);
+                                        __FILE__, __LINE__, karg.replyFrameBufPtr);
                                         rc =  -ENODATA;
                                         goto done_free_mem;
                                }
@@ -2338,11 +2279,11 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
                if (ioc->ioctl->status & MPT_IOCTL_STATUS_SENSE_VALID) {
                        sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
                        if (sz > 0) {
-                               if (copy_to_user((char *)karg.senseDataPtr, ioc->ioctl->sense, sz)) {
+                               if (copy_to_user(karg.senseDataPtr, ioc->ioctl->sense, sz)) {
                                        printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
                                        "Unable to write sense data to user %p\n",
                                        __FILE__, __LINE__,
-                                       (void*)karg.senseDataPtr);
+                                       karg.senseDataPtr);
                                        rc =  -ENODATA;
                                        goto done_free_mem;
                                }
@@ -2355,12 +2296,12 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
                if ((ioc->ioctl->status & MPT_IOCTL_STATUS_COMMAND_GOOD) &&
                                        (karg.dataInSize > 0) && (bufIn.kptr)) {
 
-                       if (copy_to_user((char *)karg.dataInBufPtr,
+                       if (copy_to_user(karg.dataInBufPtr,
                                         bufIn.kptr, karg.dataInSize)) {
                                printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
                                        "Unable to write data to user %p\n",
                                        __FILE__, __LINE__,
-                                       (void*)karg.dataInBufPtr);
+                                       karg.dataInBufPtr);
                                rc =  -ENODATA;
                        }
                }
@@ -2413,7 +2354,7 @@ done_free_mem:
 static int
 mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
 {
-       hp_host_info_t  *uarg = (hp_host_info_t *) arg;
+       hp_host_info_t  __user *uarg = (void __user *) arg;
        MPT_ADAPTER             *ioc;
        struct pci_dev          *pdev;
        char                    *pbuf;
@@ -2437,7 +2378,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
        if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
                printk(KERN_ERR "%s@%d::mptctl_hp_host_info - "
                        "Unable to read in hp_host_info struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -2455,10 +2396,8 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
 
        karg.vendor = pdev->vendor;
        karg.device = pdev->device;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
        karg.subsystem_id = pdev->subsystem_device;
        karg.subsystem_vendor = pdev->subsystem_vendor;
-#endif
        karg.devfn = pdev->devfn;
        karg.bus = pdev->bus->number;
 
@@ -2540,7 +2479,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
                break;
        }
 
-       karg.base_io_addr = pdev->PCI_BASEADDR_START(0);
+       karg.base_io_addr = pci_resource_start(pdev, 0);
 
        if ((int)ioc->chip_type <= (int) FC929)
                karg.bus_phys_width = HP_BUS_WIDTH_UNK;
@@ -2576,11 +2515,10 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
 
        /* Copy the data from kernel memory to user memory
         */
-       if (copy_to_user((char *)arg, &karg,
-                               sizeof(hp_host_info_t))) {
+       if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
                printk(KERN_ERR "%s@%d::mptctl_hpgethostinfo - "
                        "Unable to write out hp_host_info @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -2602,7 +2540,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
 static int
 mptctl_hp_targetinfo(unsigned long arg)
 {
-       hp_target_info_t        *uarg = (hp_target_info_t *) arg;
+       hp_target_info_t __user *uarg = (void __user *) arg;
        SCSIDevicePage0_t       *pg0_alloc;
        SCSIDevicePage3_t       *pg3_alloc;
        MPT_ADAPTER             *ioc;
@@ -2619,7 +2557,7 @@ mptctl_hp_targetinfo(unsigned long arg)
        if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
                printk(KERN_ERR "%s@%d::mptctl_hp_targetinfo - "
                        "Unable to read in hp_host_targetinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
        
@@ -2727,10 +2665,10 @@ mptctl_hp_targetinfo(unsigned long arg)
 
        /* Copy the data from kernel memory to user memory
         */
-       if (copy_to_user((char *)arg, &karg, sizeof(hp_target_info_t))) {
+       if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
                printk(KERN_ERR "%s@%d::mptctl_hp_target_info - "
                        "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
-                               __FILE__, __LINE__, (void*)uarg);
+                               __FILE__, __LINE__, uarg);
                return -EFAULT;
        }
 
@@ -2739,20 +2677,10 @@ mptctl_hp_targetinfo(unsigned long arg)
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)
-#define        owner_THIS_MODULE  .owner = THIS_MODULE,
-#else
-#define        owner_THIS_MODULE
-#endif
-
 static struct file_operations mptctl_fops = {
-       owner_THIS_MODULE
+       .owner =        THIS_MODULE,
        .llseek =       no_llseek,
-       .read =         mptctl_read,
-       .write =        mptctl_write,
        .ioctl =        mptctl_ioctl,
-       .open =         mptctl_open,
-       .release =      mptctl_release,
 };
 
 static struct miscdevice mptctl_miscdev = {
@@ -2800,7 +2728,7 @@ compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
 
        dctlprintk((KERN_INFO MYNAM "::compat_mptfwxfer_ioctl() called\n"));
 
-       if (copy_from_user(&kfw32, (char *)arg, sizeof(kfw32)))
+       if (copy_from_user(&kfw32, (char __user *)arg, sizeof(kfw32)))
                return -EFAULT;
 
        /* Verify intended MPT adapter */
@@ -2817,7 +2745,7 @@ compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
 
        kfw.iocnum = iocnum;
        kfw.fwlen = kfw32.fwlen;
-       kfw.bufp = (void *)(unsigned long)kfw32.bufp;
+       kfw.bufp = compat_ptr(kfw32.bufp);
 
        ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
 
@@ -2831,7 +2759,7 @@ compat_mpt_command(unsigned int fd, unsigned int cmd,
                        unsigned long arg, struct file *filp)
 {
        struct mpt_ioctl_command32 karg32;
-       struct mpt_ioctl_command32 *uarg = (struct mpt_ioctl_command32 *) arg;
+       struct mpt_ioctl_command32 __user *uarg = (struct mpt_ioctl_command32 __user *) arg;
        struct mpt_ioctl_command karg;
        MPT_ADAPTER *iocp = NULL;
        int iocnum, iocnumX;
@@ -2840,7 +2768,7 @@ compat_mpt_command(unsigned int fd, unsigned int cmd,
 
        dctlprintk((KERN_INFO MYNAM "::compat_mpt_command() called\n"));
 
-       if (copy_from_user(&karg32, (char *)arg, sizeof(karg32)))
+       if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32)))
                return -EFAULT;
 
        /* Verify intended MPT adapter */
@@ -2866,14 +2794,14 @@ compat_mpt_command(unsigned int fd, unsigned int cmd,
        karg.maxSenseBytes = karg32.maxSenseBytes;
        karg.dataSgeOffset = karg32.dataSgeOffset;
 
-       karg.replyFrameBufPtr = (char *)(unsigned long)karg32.replyFrameBufPtr;
-       karg.dataInBufPtr = (char *)(unsigned long)karg32.dataInBufPtr;
-       karg.dataOutBufPtr = (char *)(unsigned long)karg32.dataOutBufPtr;
-       karg.senseDataPtr = (char *)(unsigned long)karg32.senseDataPtr;
+       karg.replyFrameBufPtr = (char __user *)(unsigned long)karg32.replyFrameBufPtr;
+       karg.dataInBufPtr = (char __user *)(unsigned long)karg32.dataInBufPtr;
+       karg.dataOutBufPtr = (char __user *)(unsigned long)karg32.dataOutBufPtr;
+       karg.senseDataPtr = (char __user *)(unsigned long)karg32.senseDataPtr;
 
        /* Pass new structure to do_mpt_command
         */
-       ret = mptctl_do_mpt_command (karg, (char *) &uarg->MF, 0);
+       ret = mptctl_do_mpt_command (karg, &uarg->MF);
 
        up(&mptctl_syscall_sem_ioc[iocp->id]);
 
index 47ffd97..cc4ecf0 100644 (file)
 struct mpt_fw_xfer {
        unsigned int     iocnum;        /* IOC unit number */
        unsigned int     fwlen;
-       void            *bufp;          /* Pointer to firmware buffer */
+       void            __user *bufp;   /* Pointer to firmware buffer */
 };
 
 #if defined(__KERNEL__) && defined(CONFIG_COMPAT)
@@ -332,10 +332,10 @@ typedef struct mpt_ioctl_replace_fw {
 struct mpt_ioctl_command {
        mpt_ioctl_header hdr;
        int             timeout;        /* optional (seconds) */
-       char            *replyFrameBufPtr;
-       char            *dataInBufPtr;
-       char            *dataOutBufPtr;
-       char            *senseDataPtr;
+       char            __user *replyFrameBufPtr;
+       char            __user *dataInBufPtr;
+       char            __user *dataOutBufPtr;
+       char            __user *senseDataPtr;
        int             maxReplyBytes;
        int             dataInSize;
        int             dataOutSize;
index ae94f43..442f043 100644 (file)
@@ -133,7 +133,7 @@ struct mpt_lan_priv {
        u32 total_received;
        struct net_device_stats stats;  /* Per device statistics */
 
-       struct mpt_work_struct post_buckets_task;
+       struct work_struct post_buckets_task;
        unsigned long post_buckets_active;
 };
 
@@ -880,18 +880,9 @@ mpt_lan_wake_post_buckets_task(struct net_device *dev, int priority)
        
        if (test_and_set_bit(0, &priv->post_buckets_active) == 0) {
                if (priority) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41)
                        schedule_work(&priv->post_buckets_task);
-#else
-                       queue_task(&priv->post_buckets_task, &tq_immediate);
-                       mark_bh(IMMEDIATE_BH);
-#endif
                } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41)
                        schedule_delayed_work(&priv->post_buckets_task, 1);
-#else
-                       queue_task(&priv->post_buckets_task, &tq_timer);
-#endif
                        dioprintk((KERN_INFO MYNAM ": post_buckets queued on "
                                   "timer.\n"));
                }
@@ -1391,8 +1382,8 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
        priv->mpt_dev = mpt_dev;
        priv->pnum = pnum;
 
-       memset(&priv->post_buckets_task, 0, sizeof(struct mpt_work_struct));
-       MPT_INIT_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets, dev);
+       memset(&priv->post_buckets_task, 0, sizeof(struct work_struct));
+       INIT_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets, dev);
        priv->post_buckets_active = 0;
 
        dlprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n",
@@ -1566,10 +1557,6 @@ static void __exit mpt_lan_exit(void)
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,59)
-MODULE_PARM(tx_max_out_p, "i");
-MODULE_PARM(max_buckets_out, "i"); // Debug stuff. FIXME!
-#endif
 
 module_init(mpt_lan_init);
 module_exit(mpt_lan_exit);
index ce66f41..dce5ba1 100644 (file)
@@ -74,6 +74,8 @@
 #include <linux/delay.h>       /* for mdelay */
 #include <linux/interrupt.h>   /* needed for in_interrupt() proto */
 #include <linux/reboot.h>      /* notifier code */
+#include <linux/sched.h>
+#include <linux/workqueue.h>
 #include "../../scsi/scsi.h"
 #include <scsi/scsi_host.h>
 
@@ -185,7 +187,7 @@ static void mptscsih_schedule_reset(void *hd);
 static int     mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
 static int     mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
 
-static struct mpt_work_struct   mptscsih_rstTask;
+static struct work_struct   mptscsih_rstTask;
 
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 static int     mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
@@ -231,7 +233,7 @@ static int  ScsiScanDvCtx = -1; /* Used only for bus scan and dv */
 static spinlock_t dvtaskQ_lock = SPIN_LOCK_UNLOCKED;
 static int dvtaskQ_active = 0;
 static int dvtaskQ_release = 0;
-static struct mpt_work_struct  mptscsih_dvTask;
+static struct work_struct      mptscsih_dvTask;
 #endif
 
 /*
@@ -249,31 +251,7 @@ static struct mptscsih_driver_setup
 static Scsi_Cmnd *foo_to[8];
 #endif
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-/* see mptscsih.h */
-
-static struct scsi_host_template driver_template = {
-       .proc_name                      = "mptscsih",
-       .proc_info                      = x_scsi_proc_info,
-       .name                           = "MPT SCSI Host",
-       .info                           = x_scsi_info,
-       .queuecommand                   = x_scsi_queuecommand,
-       .slave_alloc                    = x_scsi_slave_alloc,
-       .slave_configure                = x_scsi_slave_configure,
-       .slave_destroy                  = x_scsi_slave_destroy,
-       .eh_abort_handler               = x_scsi_abort,
-       .eh_device_reset_handler        = x_scsi_dev_reset,
-       .eh_bus_reset_handler           = x_scsi_bus_reset,
-       .eh_host_reset_handler          = x_scsi_host_reset,
-       .bios_param                     = x_scsi_bios_param,
-       .can_queue                      = MPT_SCSI_CAN_QUEUE,
-       .this_id                        = -1,
-       .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
-       .max_sectors                    = MPT_SCSI_MAX_SECTORS,
-       .cmd_per_lun                    = MPT_SCSI_CMD_PER_LUN,
-       .use_clustering                 = ENABLE_CLUSTERING,
-};
+static struct scsi_host_template driver_template;
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -1459,7 +1437,6 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        }
                
        sh->max_lun = MPT_LAST_LUN + 1;
-       sh->max_sectors = MPT_SCSI_MAX_SECTORS;
        sh->max_channel = 0;
        sh->this_id = ioc->pfacts[0].PortSCSIID;
                
@@ -1800,8 +1777,8 @@ mptscsih_remove(struct pci_dev *pdev)
                }
 
                dprintk((MYIOC_s_INFO_FMT
-                 "Free'd ScsiLookup (%d), chain (%d) and Target (%d+%d) memory\n",
-                 hd->ioc->name, sz1, szchain, sz3, sztarget));
+                 "Free'd ScsiLookup (%d) Target (%d+%d) memory\n",
+                 hd->ioc->name, sz1, sz3, sztarget));
                dprintk(("Free'd done and free Q (%d) memory\n", szQ));
 
                /* NULL the Scsi_Host pointer
@@ -1879,9 +1856,9 @@ mptscsih_resume(struct pci_dev *pdev)
        if (!dvtaskQ_active) {
                dvtaskQ_active = 1;
                spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
-               MPT_INIT_WORK(&mptscsih_dvTask,
+               INIT_WORK(&mptscsih_dvTask,
                  mptscsih_domainValidation, (void *) hd);
-               SCHEDULE_TASK(&mptscsih_dvTask);
+               schedule_work(&mptscsih_dvTask);
        } else {
                spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
        }
@@ -1902,7 +1879,6 @@ static struct mpt_pci_driver mptscsih_driver = {
 #endif
 };
 
-
 /*  SCSI host fops start here...  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
@@ -2434,9 +2410,9 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
                                        if (!dvtaskQ_active) {
                                                dvtaskQ_active = 1;
                                                spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
-                                               MPT_INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
+                                               INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
 
-                                               SCHEDULE_TASK(&mptscsih_dvTask);
+                                               schedule_work(&mptscsih_dvTask);
                                        } else {
                                                spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
                                        }
@@ -3905,6 +3881,29 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
        return 1;               /* currently means nothing really */
 }
 
+static struct scsi_host_template driver_template = {
+       .proc_name                      = "mptscsih",
+       .proc_info                      = mptscsih_proc_info,
+       .name                           = "MPT SCSI Host",
+       .info                           = mptscsih_info,
+       .queuecommand                   = mptscsih_qcmd,
+       .slave_alloc                    = mptscsih_slave_alloc,
+       .slave_configure                = mptscsih_slave_configure,
+       .slave_destroy                  = mptscsih_slave_destroy,
+       .eh_abort_handler               = mptscsih_abort,
+       .eh_device_reset_handler        = mptscsih_dev_reset,
+       .eh_bus_reset_handler           = mptscsih_bus_reset,
+       .eh_host_reset_handler          = mptscsih_host_reset,
+       .bios_param                     = mptscsih_bios_param,
+       .can_queue                      = MPT_SCSI_CAN_QUEUE,
+       .this_id                        = -1,
+       .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
+       .max_sectors                    = 8192,
+       .cmd_per_lun                    = 7,
+       .use_clustering                 = ENABLE_CLUSTERING,
+};
+
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  Private data...
@@ -4950,8 +4949,8 @@ static void mptscsih_taskmgmt_timeout(unsigned long data)
        /* Call the reset handler. Already had a TM request
         * timeout - so issue a diagnostic reset
         */
-       MPT_INIT_WORK(&mptscsih_rstTask, mptscsih_schedule_reset, (void *)hd);
-       SCHEDULE_TASK(&mptscsih_rstTask);
+       INIT_WORK(&mptscsih_rstTask, mptscsih_schedule_reset, (void *)hd);
+       schedule_work(&mptscsih_rstTask);
        return;
 }
 
index 5ab0726..2c002b5 100644 (file)
@@ -108,75 +108,4 @@ struct mptscsih_driver_setup
         MPTSCSIH_SAF_TE,                        \
 }
 
-
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *     Various bits and pieces broke within the lk-2.4.0-testN series:-(
- *     So here are various HACKS to work around them.
- */
-
-/*
- *     tq_scheduler disappeared @ lk-2.4.0-test12
- *     (right when <linux/sched.h> newly defined TQ_ACTIVE)
- *     tq_struct reworked in 2.5.41. Include workqueue.h.
- */
-#      include <linux/sched.h>
-#      include <linux/workqueue.h>
-#define SCHEDULE_TASK(x)               \
-       if (schedule_work(x) == 0) {    \
-               /*MOD_DEC_USE_COUNT*/;  \
-       }
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#define x_scsi_info            mptscsih_info
-#define x_scsi_queuecommand    mptscsih_qcmd
-#define x_scsi_abort           mptscsih_abort
-#define x_scsi_bus_reset       mptscsih_bus_reset
-#define x_scsi_dev_reset       mptscsih_dev_reset
-#define x_scsi_host_reset      mptscsih_host_reset
-#define x_scsi_bios_param      mptscsih_bios_param
-
-#define x_scsi_slave_alloc     mptscsih_slave_alloc
-#define x_scsi_slave_configure mptscsih_slave_configure
-#define x_scsi_slave_destroy   mptscsih_slave_destroy
-#define x_scsi_proc_info       mptscsih_proc_info
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *     MPT SCSI Host / Initiator decls...
- */
-extern const char      *x_scsi_info(struct Scsi_Host *);
-extern int              x_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-extern int              x_scsi_abort(Scsi_Cmnd *);
-extern int              x_scsi_bus_reset(Scsi_Cmnd *);
-extern int              x_scsi_dev_reset(Scsi_Cmnd *);
-extern int              x_scsi_host_reset(Scsi_Cmnd *);
-extern int              x_scsi_bios_param(struct scsi_device * sdev, struct block_device *bdev,
-                               sector_t capacity, int geom[]);
-extern int              x_scsi_slave_alloc(Scsi_Device *);
-extern int              x_scsi_slave_configure(Scsi_Device *);
-extern void             x_scsi_slave_destroy(Scsi_Device *);
-extern int              x_scsi_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-/*  include/scsi/scsi.h may not be quite complete...  */
-#ifndef RESERVE_10
-#define RESERVE_10             0x56
-#endif
-#ifndef RELEASE_10
-#define RELEASE_10             0x57
-#endif
-#ifndef PERSISTENT_RESERVE_IN
-#define PERSISTENT_RESERVE_IN  0x5e
 #endif
-#ifndef PERSISTENT_RESERVE_OUT
-#define PERSISTENT_RESERVE_OUT 0x5f
-#endif
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#endif
-
index 76de2d7..63e67b3 100644 (file)
@@ -280,8 +280,8 @@ static int i2ob_send(u32 m, struct i2ob_device *dev, struct i2ob_request *ireq,
 {
        struct i2o_controller *c = dev->controller;
        int tid = dev->tid;
-       unsigned long msg;
-       unsigned long mptr;
+       void *msg;
+       void *mptr;
        u64 offset;
        struct request *req = ireq->req;
        int count = req->nr_sectors<<9;
@@ -291,7 +291,7 @@ static int i2ob_send(u32 m, struct i2ob_device *dev, struct i2ob_request *ireq,
 
        // printk(KERN_INFO "i2ob_send called\n");
        /* Map the message to a virtual address */
-       msg = c->mem_offset + m;
+       msg = c->msg_virt + m;
        
        sgnum = i2ob_build_sglist(dev, ireq);
        
@@ -479,7 +479,7 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
                /* Now flush the message by making it a NOP */
                m[0]&=0x00FFFFFF;
                m[0]|=(I2O_CMD_UTIL_NOP)<<24;
-               i2o_post_message(c, ((unsigned long)m) - c->mem_offset);
+               i2o_post_message(c, (unsigned long) m - (unsigned long) c->msg_virt);
 
                return;
        }
index f417bac..0c77a2b 100644 (file)
@@ -97,7 +97,7 @@ static void i2o_cfg_reply(struct i2o_handler *h, struct i2o_controller *c, struc
        u32 *msg = (u32 *)m;
 
        if (msg[0] & MSG_FAIL) {
-               u32 *preserved_msg = (u32*)(c->mem_offset + msg[7]);
+               u32 *preserved_msg = (u32*)(c->msg_virt + msg[7]);
 
                printk(KERN_ERR "i2o_config: IOP failed to process the msg.\n");
 
index e5afe8d..b631a62 100644 (file)
@@ -354,7 +354,7 @@ static void i2o_core_reply(struct i2o_handler *h, struct i2o_controller *c,
 
        if (msg[0] & MSG_FAIL) // Fail bit is set
        {
-               u32 *preserved_msg = (u32*)(c->mem_offset + msg[7]);
+               u32 *preserved_msg = (u32*)(c->msg_virt + msg[7]);
 
                i2o_report_status(KERN_INFO, "i2o_core", msg);
                i2o_dump_message(preserved_msg);
@@ -1794,7 +1794,7 @@ static int i2o_reset_controller(struct i2o_controller *c)
        m=i2o_wait_message(c, "AdapterReset");
        if(m==0xFFFFFFFF)       
                return -ETIMEDOUT;
-       msg=(u32 *)(c->mem_offset+m);
+       msg=(u32 *)(c->msg_virt+m);
        
        status = pci_alloc_consistent(c->pdev, 4, &status_phys);
        if(status == NULL) {
@@ -1923,7 +1923,7 @@ int i2o_status_get(struct i2o_controller *c)
        m=i2o_wait_message(c, "StatusGet");
        if(m==0xFFFFFFFF)
                return -ETIMEDOUT;      
-       msg=(u32 *)(c->mem_offset+m);
+       msg=(u32 *)(c->msg_virt+m);
 
        msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_0;
        msg[1]=I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID;
@@ -2344,7 +2344,7 @@ int i2o_init_outbound_q(struct i2o_controller *c)
        m=i2o_wait_message(c, "OutboundInit");
        if(m==0xFFFFFFFF)
                return -ETIMEDOUT;
-       msg=(u32 *)(c->mem_offset+m);
+       msg=(u32 *)(c->msg_virt+m);
 
        status = pci_alloc_consistent(c->pdev, 4, &status_phys);
        if (status==NULL) {
@@ -2618,7 +2618,7 @@ static int i2o_build_sys_table(void)
                sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
                sys_tbl->iops[count].iop_capabilities = 
                                iop->status_block->iop_capabilities;
-               sys_tbl->iops[count].inbound_low = iop->post_port;
+               sys_tbl->iops[count].inbound_low = (u32)iop->post_port;
                sys_tbl->iops[count].inbound_high = 0;  // FIXME: 64-bit support
 
                count++;
@@ -2666,7 +2666,7 @@ int i2o_post_this(struct i2o_controller *c, u32 *data, int len)
                       c->name);
                return -ETIMEDOUT;
        }
-       msg = (u32 *)(c->mem_offset + m);
+       msg = (u32 *)(c->msg_virt + m);
        memcpy_toio(msg, data, len);
        i2o_post_message(c,m);
        return 0;
@@ -3592,7 +3592,9 @@ static void i2o_pci_dispose(struct i2o_controller *c)
        I2O_IRQ_WRITE32(c,0xFFFFFFFF);
        if(c->irq > 0)
                free_irq(c->irq, c);
-       iounmap(((u8 *)c->post_port)-0x40);
+       iounmap(c->base_virt);
+       if(c->raptor)
+               iounmap(c->msg_virt);
 
 #ifdef CONFIG_MTRR
        if(c->mtrr_reg0 > 0)
@@ -3633,9 +3635,12 @@ int __init i2o_pci_install(struct pci_dev *dev)
 {
        struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller),
                                                GFP_KERNEL);
-       unsigned long mem;
-       u32 memptr = 0;
-       u32 size;
+       void *bar0_virt;
+       void *bar1_virt;
+       unsigned long bar0_phys = 0;
+       unsigned long bar1_phys = 0;
+       unsigned long bar0_size = 0;
+       unsigned long bar1_size = 0;
        
        int i;
 
@@ -3646,37 +3651,9 @@ int __init i2o_pci_install(struct pci_dev *dev)
        }
        memset(c, 0, sizeof(*c));
 
-       for(i=0; i<6; i++)
-       {
-               /* Skip I/O spaces */
-               if(!(pci_resource_flags(dev, i) & IORESOURCE_IO))
-               {
-                       memptr = pci_resource_start(dev, i);
-                       break;
-               }
-       }
-       
-       if(i==6)
-       {
-               printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n");
-               kfree(c);
-               return -EINVAL;
-       }
-       
-       size = dev->resource[i].end-dev->resource[i].start+1;   
-       /* Map the I2O controller */
-       
-       printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size);
-       mem = (unsigned long)ioremap(memptr, size);
-       if(mem==0)
-       {
-               printk(KERN_ERR "i2o: Unable to map controller.\n");
-               kfree(c);
-               return -EINVAL;
-       }
-
        c->irq = -1;
        c->dpt = 0;
+       c->raptor = 0;
        c->short_req = 0;
        c->pdev = dev;
 
@@ -3684,13 +3661,6 @@ int __init i2o_pci_install(struct pci_dev *dev)
        c->context_list_lock = SPIN_LOCK_UNLOCKED;
 #endif
 
-       c->irq_mask = mem+0x34;
-       c->post_port = mem+0x40;
-       c->reply_port = mem+0x44;
-
-       c->mem_phys = memptr;
-       c->mem_offset = mem;
-       
        /*
         *      Cards that fall apart if you hit them with large I/O
         *      loads...
@@ -3701,6 +3671,7 @@ int __init i2o_pci_install(struct pci_dev *dev)
                c->short_req = 1;
                printk(KERN_INFO "I2O: Symbios FC920 workarounds activated.\n");
        }
+
        if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE)
        {
                c->promise = 1;
@@ -3712,15 +3683,85 @@ int __init i2o_pci_install(struct pci_dev *dev)
         *      them
         */
         
-       if(dev->vendor == PCI_VENDOR_ID_DPT)
+       if(dev->vendor == PCI_VENDOR_ID_DPT) {
                c->dpt=1;
+               if(dev->device == 0xA511)
+                       c->raptor=1;
+       }
+
+       for(i=0; i<6; i++)
+       {
+               /* Skip I/O spaces */
+               if(!(pci_resource_flags(dev, i) & IORESOURCE_IO))
+               {
+                       if(!bar0_phys)
+                       {
+                               bar0_phys = pci_resource_start(dev, i);
+                               bar0_size = pci_resource_len(dev, i);
+                               if(!c->raptor)
+                                       break;
+                       }
+                       else
+                       {
+                               bar1_phys = pci_resource_start(dev, i);
+                               bar1_size = pci_resource_len(dev, i);
+                               break;
+                       }
+               }
+       }
+
+       if(i==6)
+       {
+               printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n");
+               kfree(c);
+               return -EINVAL;
+       }
+
+
+       /* Map the I2O controller */
+       if(!c->raptor)
+               printk(KERN_INFO "i2o: PCI I2O controller at %08lX size=%ld\n", bar0_phys, bar0_size);
+       else
+               printk(KERN_INFO "i2o: PCI I2O controller\n    BAR0 at 0x%08lX size=%ld\n    BAR1 at 0x%08lX size=%ld\n", bar0_phys, bar0_size, bar1_phys, bar1_size);
+
+       bar0_virt = ioremap(bar0_phys, bar0_size);
+       if(bar0_virt==0)
+       {
+               printk(KERN_ERR "i2o: Unable to map controller.\n");
+               kfree(c);
+               return -EINVAL;
+       }
+
+       if(c->raptor)
+       {
+               bar1_virt = ioremap(bar1_phys, bar1_size);
+               if(bar1_virt==0)
+               {
+                       printk(KERN_ERR "i2o: Unable to map controller.\n");
+                       kfree(c);
+                       iounmap(bar0_virt);
+                       return -EINVAL;
+               }
+       } else {
+               bar1_virt = bar0_virt;
+               bar1_phys = bar0_phys;
+               bar1_size = bar0_size;
+       }
+
+       c->irq_mask = bar0_virt+0x34;
+       c->post_port = bar0_virt+0x40;
+       c->reply_port = bar0_virt+0x44;
+
+       c->base_phys = bar0_phys;
+       c->base_virt = bar0_virt;
+       c->msg_phys = bar1_phys;
+       c->msg_virt = bar1_virt;
        
        /* 
         * Enable Write Combining MTRR for IOP's memory region
         */
 #ifdef CONFIG_MTRR
-       c->mtrr_reg0 =
-               mtrr_add(c->mem_phys, size, MTRR_TYPE_WRCOMB, 1);
+       c->mtrr_reg0 = mtrr_add(c->base_phys, bar0_size, MTRR_TYPE_WRCOMB, 1);
        /*
         * If it is an INTEL i960 I/O processor then set the first 64K to
         * Uncacheable since the region contains the Messaging unit which
@@ -3730,14 +3771,16 @@ int __init i2o_pci_install(struct pci_dev *dev)
        if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT)
        {
                printk(KERN_INFO "I2O: MTRR workaround for Intel i960 processor\n"); 
-               c->mtrr_reg1 =  mtrr_add(c->mem_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
+               c->mtrr_reg1 =  mtrr_add(c->base_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
                if(c->mtrr_reg1< 0)
                {
                        printk(KERN_INFO "i2o_pci: Error in setting MTRR_TYPE_UNCACHABLE\n");
-                       mtrr_del(c->mtrr_reg0, c->mem_phys, size);
+                       mtrr_del(c->mtrr_reg0, c->msg_phys, bar1_size);
                        c->mtrr_reg0 = -1;
                }
        }
+       if(c->raptor)
+               c->mtrr_reg1 = mtrr_add(c->msg_phys, bar1_size, MTRR_TYPE_WRCOMB, 1);
 
 #endif
 
@@ -3749,7 +3792,9 @@ int __init i2o_pci_install(struct pci_dev *dev)
        {
                printk(KERN_ERR "i2o: Unable to install controller.\n");
                kfree(c);
-               iounmap((void *)mem);
+               iounmap(bar0_virt);
+               if(c->raptor)
+                       iounmap(bar1_virt);
                return i;
        }
 
@@ -3764,7 +3809,9 @@ int __init i2o_pci_install(struct pci_dev *dev)
                                c->name, dev->irq);
                        c->irq = -1;
                        i2o_delete_controller(c);
-                       iounmap((void *)mem);
+                       iounmap(bar0_virt);
+                       if(c->raptor)
+                               iounmap(bar1_virt);
                        return -EBUSY;
                }
        }
@@ -3797,10 +3844,12 @@ int __init i2o_pci_scan(void)
 
        while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
        {
-               if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O)
+               if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O &&
+                  (dev->vendor!=PCI_VENDOR_ID_DPT || dev->device!=0xA511))
                        continue;
 
-               if((dev->class&0xFF)>1)
+               if((dev->class>>8)==PCI_CLASS_INTELLIGENT_I2O &&
+                  (dev->class&0xFF)>1)
                {
                        printk(KERN_INFO "i2o: I2O Controller found but does not support I2O 1.5 (skipping).\n");
                        continue;
index a0f99f6..ba121fc 100644 (file)
 #include <asm/atomic.h>
 #include <linux/blkdev.h>
 #include <linux/i2o.h>
-#include "../../scsi/scsi.h"
-#include "../../scsi/hosts.h"
 
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
 
 
 #define VERSION_STRING        "Version 0.1.2"
@@ -186,7 +188,7 @@ static void flush_pending(void)
 
 static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg)
 {
-       Scsi_Cmnd *current_command;
+       struct scsi_cmnd *current_command;
        spinlock_t *lock;
        u32 *m = (u32 *)msg;
        u8 as,ds,st;
@@ -230,7 +232,7 @@ static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, stru
                {
                        spin_unlock_irqrestore(&retry_lock, flags);
                        /* Create a scsi error for this */
-                       current_command = (Scsi_Cmnd *)i2o_context_list_get(m[3], c);
+                       current_command = (struct scsi_cmnd *)i2o_context_list_get(m[3], c);
                        if(!current_command)
                                return;
 
@@ -277,7 +279,7 @@ static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, stru
                return;
        }
 
-       current_command = (Scsi_Cmnd *)i2o_context_list_get(m[3], c);
+       current_command = (struct scsi_cmnd *)i2o_context_list_get(m[3], c);
        
        /*
         *      Is this a control request coming back - eg an abort ?
@@ -330,10 +332,17 @@ static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, stru
                 */             
                current_command->result = DID_OK << 16 | ds;
 
-       if (current_command->use_sg)
-               pci_unmap_sg(c->pdev, (struct scatterlist *)current_command->buffer, current_command->use_sg, scsi_to_pci_dma_dir(current_command->sc_data_direction));
-       else if (current_command->request_bufflen)
-               pci_unmap_single(c->pdev, (dma_addr_t)((long)current_command->SCp.ptr), current_command->request_bufflen, scsi_to_pci_dma_dir(current_command->sc_data_direction));
+       if (current_command->use_sg) {
+               pci_unmap_sg(c->pdev,
+                       (struct scatterlist *)current_command->buffer,
+                       current_command->use_sg,
+                       current_command->sc_data_direction);
+       } else if (current_command->request_bufflen) {
+               pci_unmap_single(c->pdev,
+                       (dma_addr_t)((long)current_command->SCp.ptr),
+                       current_command->request_bufflen,
+                       current_command->sc_data_direction);
+       }
 
        lock = current_command->device->host->host_lock;
        spin_lock_irqsave(lock, flags);
@@ -461,7 +470,7 @@ static void i2o_scsi_init(struct i2o_controller *c, struct i2o_device *d, struct
  *     scsi controller and then let the enumeration fake up the rest
  */
  
-static int i2o_scsi_detect(Scsi_Host_Template * tpnt)
+static int i2o_scsi_detect(struct scsi_host_template * tpnt)
 {
        struct Scsi_Host *shpnt = NULL;
        int i;
@@ -592,12 +601,13 @@ static const char *i2o_scsi_info(struct Scsi_Host *SChost)
  *     Locks: takes the controller lock on error path only
  */
  
-static int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
+                                void (*done) (struct scsi_cmnd *))
 {
        int i;
        int tid;
        struct i2o_controller *c;
-       Scsi_Cmnd *current_command;
+       struct scsi_cmnd *current_command;
        struct Scsi_Host *host;
        struct i2o_scsi_host *hostdata;
        u32 *msg, *mptr;
@@ -659,7 +669,7 @@ static int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
        if(m==0xFFFFFFFF)
                return 1;
 
-       msg = (u32 *)(c->mem_offset + m);
+       msg = (u32 *)(c->msg_virt + m);
        
        /*
         *      Put together a scsi execscb message
@@ -668,19 +678,14 @@ static int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
        len = SCpnt->request_bufflen;
        direction = 0x00000000;                 // SGL IN  (osm<--iop)
        
-       if(SCpnt->sc_data_direction == SCSI_DATA_NONE)
+       if (SCpnt->sc_data_direction == DMA_NONE) {
                scsidir = 0x00000000;                   // DATA NO XFER
-       else if(SCpnt->sc_data_direction == SCSI_DATA_WRITE)
-       {
-               direction=0x04000000;   // SGL OUT  (osm-->iop)
-               scsidir  =0x80000000;   // DATA OUT (iop-->dev)
-       }
-       else if(SCpnt->sc_data_direction == SCSI_DATA_READ)
-       {
-               scsidir  =0x40000000;   // DATA IN  (iop<--dev)
-       }
-       else
-       {
+       } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
+               direction = 0x04000000; // SGL OUT  (osm-->iop)
+               scsidir = 0x80000000;   // DATA OUT (iop-->dev)
+       } else if(SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
+               scsidir = 0x40000000;   // DATA IN  (iop<--dev)
+       } else {
                /* Unknown - kill the command */
                SCpnt->result = DID_NO_CONNECT << 16;
                
@@ -768,7 +773,7 @@ static int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
                len = 0;
 
                sg_count = pci_map_sg(c->pdev, sg, SCpnt->use_sg,
-                                     scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+                               SCpnt->sc_data_direction);
 
                /* FIXME: handle fail */
                if(!sg_count)
@@ -840,7 +845,7 @@ static int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
                        dma_addr = pci_map_single(c->pdev,
                                               SCpnt->request_buffer,
                                               SCpnt->request_bufflen,
-                                              scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+                                              SCpnt->sc_data_direction);
                        if(dma_addr == 0)
                                BUG();  /* How to handle ?? */
                        SCpnt->SCp.ptr = (char *)(unsigned long) dma_addr;
@@ -883,7 +888,7 @@ static int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
  *     Locks: no locks are held or needed
  */
  
-int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
+static int i2o_scsi_abort(struct scsi_cmnd * SCpnt)
 {
        struct i2o_controller *c;
        struct Scsi_Host *host;
@@ -929,14 +934,14 @@ int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
  *     Locks: called with no lock held, requires no locks.
  */
  
-static int i2o_scsi_bus_reset(Scsi_Cmnd * SCpnt)
+static int i2o_scsi_bus_reset(struct scsi_cmnd * SCpnt)
 {
        int tid;
        struct i2o_controller *c;
        struct Scsi_Host *host;
        struct i2o_scsi_host *hostdata;
        u32 m;
-       unsigned long msg;
+       void *msg;
        unsigned long timeout;
 
        
@@ -974,7 +979,7 @@ static int i2o_scsi_bus_reset(Scsi_Cmnd * SCpnt)
        while(time_before(jiffies, timeout));
        
        
-       msg = c->mem_offset + m;
+       msg = c->msg_virt + m;
        i2o_raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, msg);
        i2o_raw_writel(I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid, msg+4);
        i2o_raw_writel(scsi_context|0x80000000, msg+8);
@@ -991,32 +996,6 @@ static int i2o_scsi_bus_reset(Scsi_Cmnd * SCpnt)
        return SUCCESS;
 }
 
-/**
- *     i2o_scsi_host_reset     -       host reset callback
- *     @SCpnt: command causing the reset
- *
- *     An I2O controller can be many things at once. While we can
- *     reset a controller the potential mess from doing so is vast, and
- *     it's better to simply hold on and pray
- */
-static int i2o_scsi_host_reset(Scsi_Cmnd * SCpnt)
-{
-       return FAILED;
-}
-
-/**
- *     i2o_scsi_device_reset   -       device reset callback
- *     @SCpnt: command causing the reset
- *
- *     I2O does not (AFAIK) support doing a device reset
- */
-static int i2o_scsi_device_reset(Scsi_Cmnd * SCpnt)
-{
-       return FAILED;
-}
-
 /**
  *     i2o_scsi_bios_param     -       Invent disk geometry
  *     @sdev: scsi device 
@@ -1048,7 +1027,7 @@ MODULE_AUTHOR("Red Hat Software");
 MODULE_LICENSE("GPL");
 
 
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
        .proc_name              = "i2o_scsi",
        .name                   = "I2O SCSI Layer",
        .detect                 = i2o_scsi_detect,
@@ -1057,8 +1036,6 @@ static Scsi_Host_Template driver_template = {
        .queuecommand           = i2o_scsi_queuecommand,
        .eh_abort_handler       = i2o_scsi_abort,
        .eh_bus_reset_handler   = i2o_scsi_bus_reset,
-       .eh_device_reset_handler= i2o_scsi_device_reset,
-       .eh_host_reset_handler  = i2o_scsi_host_reset,
        .bios_param             = i2o_scsi_bios_param,
        .can_queue              = I2O_SCSI_CAN_QUEUE,
        .this_id                = 15,
index a01fe08..e604925 100644 (file)
@@ -224,12 +224,12 @@ static struct dentry *ibmasmfs_create_dir (struct super_block *sb,
        return dentry;
 }
 
-int ibmasmfs_register()
+int ibmasmfs_register(void)
 {
        return register_filesystem(&ibmasmfs_type);
 }
 
-void ibmasmfs_unregister()
+void ibmasmfs_unregister(void)
 {
        unregister_filesystem(&ibmasmfs_type);
 }
@@ -287,7 +287,7 @@ static int command_file_close(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t command_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t command_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
        struct ibmasmfs_command_data *command_data = file->private_data;
        struct command *cmd;
@@ -324,7 +324,7 @@ static ssize_t command_file_read(struct file *file, char *buf, size_t count, lof
        return len;
 }
 
-static ssize_t command_file_write(struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static ssize_t command_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset)
 {
        struct ibmasmfs_command_data *command_data = file->private_data;
        struct command *cmd;
@@ -345,7 +345,7 @@ static ssize_t command_file_write(struct file *file, const char *ubuff, size_t c
        if (!cmd)
                return -ENOMEM;
 
-       if (copy_from_user((void *)cmd->buffer, (void *)ubuff, count)) {
+       if (copy_from_user(cmd->buffer, ubuff, count)) {
                command_put(cmd);
                return -EFAULT;
        }
@@ -395,7 +395,7 @@ static int event_file_close(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t event_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
        struct ibmasmfs_event_data *event_data = file->private_data;
        struct event_reader *reader = &event_data->reader;
@@ -421,7 +421,7 @@ static ssize_t event_file_read(struct file *file, char *buf, size_t count, loff_
        return reader->data_size;
 }
 
-static ssize_t event_file_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
 {
        struct ibmasmfs_event_data *event_data = file->private_data;
 
@@ -462,7 +462,7 @@ static int r_heartbeat_file_close(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t r_heartbeat_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t r_heartbeat_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
        struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;
        unsigned long flags;
@@ -490,7 +490,7 @@ static ssize_t r_heartbeat_file_read(struct file *file, char *buf, size_t count,
        return result;
 }
 
-static ssize_t r_heartbeat_file_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+static ssize_t r_heartbeat_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
 {
        struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;
 
@@ -518,7 +518,7 @@ static int remote_settings_file_close(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t remote_settings_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t remote_settings_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
        unsigned long address = (unsigned long)file->private_data;
        unsigned char *page;
@@ -552,7 +552,7 @@ exit:
        return retval;
 }
 
-static ssize_t remote_settings_file_write(struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static ssize_t remote_settings_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset)
 {
        unsigned long address = (unsigned long)file->private_data;
        char *buff;
@@ -571,7 +571,7 @@ static ssize_t remote_settings_file_write(struct file *file, const char *ubuff,
 
        memset(buff, 0x0, count + 1);
 
-       if (copy_from_user((void *)buff, (void *)ubuff, count)) {
+       if (copy_from_user(buff, ubuff, count)) {
                kfree(buff);
                return -EFAULT;
        }
@@ -618,7 +618,7 @@ static int remote_event_file_close(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t remote_event_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t remote_event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
        struct service_processor *sp = file->private_data;
        struct remote_queue *q = &sp->remote_queue;
@@ -663,7 +663,7 @@ static struct file_operations event_fops = {
        .open =         event_file_open,
        .release =      event_file_close,
        .read =         event_file_read,
-       .write          event_file_write,
+       .write =        event_file_write,
 };
 
 static struct file_operations r_heartbeat_fops = {
index ce539ba..159ccc0 100644 (file)
 #define M29W160DT      0x22C4
 #define M29W160DB      0x2249
 #define M29W040B       0x00E3
+#define M50FW040       0x002C
+#define M50FW080       0x002D
+#define M50FW016       0x002E
 
 /* SST */
 #define SST29EE512     0x005d
@@ -1233,6 +1236,45 @@ static const struct amd_flash_info jedec_table[] = {
                .regions        = {
                        ERASEINFO(0x10000,8),
                }
+        }, {
+               .mfr_id         = MANUFACTURER_ST,
+               .dev_id         = M50FW040,
+               .name           = "ST M50FW040",
+               .uaddr          = {
+                       [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
+               },
+               .DevSize        = SIZE_512KiB,
+               .CmdSet         = P_ID_INTEL_EXT,
+               .NumEraseRegions= 1,
+               .regions        = {
+                       ERASEINFO(0x10000,8),
+               }
+        }, {
+               .mfr_id         = MANUFACTURER_ST,
+               .dev_id         = M50FW080,
+               .name           = "ST M50FW080",
+               .uaddr          = {
+                       [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
+               },
+               .DevSize        = SIZE_1MiB,
+               .CmdSet         = P_ID_INTEL_EXT,
+               .NumEraseRegions= 1,
+               .regions        = {
+                       ERASEINFO(0x10000,16),
+               }
+        }, {
+               .mfr_id         = MANUFACTURER_ST,
+               .dev_id         = M50FW016,
+               .name           = "ST M50FW016",
+               .uaddr          = {
+                       [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
+               },
+               .DevSize        = SIZE_2MiB,
+               .CmdSet         = P_ID_INTEL_EXT,
+               .NumEraseRegions= 1,
+               .regions        = {
+                       ERASEINFO(0x10000,32),
+               }
        }, {
                .mfr_id         = MANUFACTURER_TOSHIBA,
                .dev_id         = TC58FVT160,
index e0b957b..03d39d7 100644 (file)
@@ -489,5 +489,13 @@ config MTD_UCLINUX
        help
          Map driver to support image based filesystems for uClinux.
 
+config MTD_WRSBC8260
+       tristate "Map driver for WindRiver PowerQUICC II MPC82xx board"
+       depends on MTD_PARTITIONS && SBC82xx
+       help
+         Map driver for WindRiver PowerQUICC II MPC82xx board. Drives
+         all three flash regions on CS0, CS1 and CS6 if they are configured
+         correctly by the boot loader.
+
 endmenu
 
index 230c88c..929d668 100644 (file)
@@ -56,3 +56,4 @@ obj-$(CONFIG_MTD_BEECH)               += beech-mtd.o
 obj-$(CONFIG_MTD_ARCTIC)       += arctic-mtd.o
 obj-$(CONFIG_MTD_H720X)                += h720x-flash.o
 obj-$(CONFIG_MTD_IXP4XX)       += ixp4xx.o
+obj-$(CONFIG_MTD_WRSBC8260)    += wr_sbc82xx_flash.o
index c7e2546..5f7bdd8 100644 (file)
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
+#include <asm/io.h>
 #include <asm/hardware.h>
+#include <asm/arch/lubbock.h>
 
 
 #define ROM_ADDR       0x00000000
index 965c595..fd096ea 100644 (file)
@@ -275,7 +275,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
        
        /* OK, it's not open. Create cache info for it */
        mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
-       if (!mtdblks)
+       if (!mtdblk)
                return -ENOMEM;
 
        memset(mtdblk, 0, sizeof(*mtdblk));
index 3c731e1..0c99115 100644 (file)
@@ -225,7 +225,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
         *      Reserve I/O resource for exclusive use by this driver
         */
 
-       if (!request_region(ioaddr, EL1_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, EL1_IO_EXTENT, DRV_NAME))
                return -ENODEV;
 
        /*
index 66644b0..c4524de 100644 (file)
@@ -147,6 +147,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr, EL2_IO_EXTENT);
 }
 
+#ifndef MODULE
 struct net_device * __init el2_probe(int unit)
 {
        struct net_device *dev = alloc_ei_netdev();
@@ -171,6 +172,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 /* Probe for the Etherlink II card at I/O port base IOADDR,
    returning non-zero on success.  If found, set the station
@@ -182,10 +184,10 @@ el2_probe1(struct net_device *dev, int ioaddr)
     static unsigned version_printed;
     unsigned long vendor_id;
 
-    if (!request_region(ioaddr, EL2_IO_EXTENT, dev->name))
+    if (!request_region(ioaddr, EL2_IO_EXTENT, DRV_NAME))
        return -EBUSY;
 
-    if (!request_region(ioaddr + 0x400, 8, dev->name)) {
+    if (!request_region(ioaddr + 0x400, 8, DRV_NAME)) {
        retval = -EBUSY;
        goto out;
     }
index 9c81e7b..3aa8409 100644 (file)
@@ -1614,6 +1614,7 @@ out:
        return err;
 }
 
+#ifndef MODULE
 struct net_device * __init elplus_probe(int unit)
 {
        struct net_device *dev = alloc_etherdev(sizeof(elp_device));
@@ -1632,7 +1633,7 @@ struct net_device * __init elplus_probe(int unit)
        return dev;
 }
 
-#ifdef MODULE
+#else
 static struct net_device *dev_3c505[ELP_MAX_CARDS];
 static int io[ELP_MAX_CARDS];
 static int irq[ELP_MAX_CARDS];
index bfd4ad0..ca0d71d 100644 (file)
@@ -373,7 +373,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
                init_ID_done = 1;
        }
 
-       if (!request_region(ioaddr, EL16_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, EL16_IO_EXTENT, DRV_NAME))
                return -ENODEV;
 
        if ((inb(ioaddr) != '*') || (inb(ioaddr + 1) != '3') || 
@@ -392,7 +392,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
 
        irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
 
-       irqval = request_irq(irq, &el16_interrupt, 0, dev->name, dev);
+       irqval = request_irq(irq, &el16_interrupt, 0, DRV_NAME, dev);
        if (irqval) {
                printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval);
                retval = -EAGAIN;
index 707da81..3889295 100644 (file)
                v1.19b 08Nov2002 Marc Zyngier <maz@wild-wind.fr.eu.org>
                    - Introduce driver model for EISA cards.
 */
-/*
-  FIXES for PC-9800:
-  Shu Iwanaga: 3c569B(PC-9801 C-bus) support
-*/
 
 #define DRV_NAME       "3c509"
 #define DRV_VERSION    "1.19b"
@@ -265,7 +261,7 @@ static struct mca_driver el3_mca_driver = {
 };
 #endif /* CONFIG_MCA */
 
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
 static struct isapnp_device_id el3_isapnp_adapters[] __initdata = {
        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID,
                ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5090),
@@ -362,7 +358,7 @@ static void el3_common_remove (struct net_device *dev)
        if (lp->pmdev)
                pm_unregister(lp->pmdev);
 #endif
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
        if (lp->type == EL3_PNP)
                pnp_device_detach(to_pnp_dev(lp->dev));
 #endif
@@ -381,7 +377,7 @@ static int __init el3_probe(int card_idx)
        u16 phys_addr[3];
        static int current_tag;
        int err = -ENODEV;
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
        static int pnp_cards;
        struct pnp_dev *idev = NULL;
 
@@ -436,9 +432,6 @@ __again:
 no_pnp:
 #endif /* __ISAPNP__ */
 
-#ifdef CONFIG_X86_PC9800
-       id_port = 0x71d0;
-#else
        /* Select an open I/O location at 0x1*0 to do contention select. */
        for ( ; id_port < 0x200; id_port += 0x10) {
                if (!request_region(id_port, 1, "3c509"))
@@ -456,7 +449,7 @@ no_pnp:
                printk(" WARNING: No I/O port available for 3c509 activation.\n");
                return -ENODEV;
        }
-#endif /* CONFIG_X86_PC9800 */
+
        /* Next check for all ISA bus boards by sending the ID sequence to the
           ID_PORT.  We find cards past the first by setting the 'current_tag'
           on cards as they are found.  Cards with their tag set will not
@@ -487,7 +480,7 @@ no_pnp:
                phys_addr[i] = htons(id_read_eeprom(i));
        }
 
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
        if (nopnp == 0) {
                /* The ISA PnP 3c509 cards respond to the ID sequence.
                   This check is needed in order not to register them twice. */
@@ -512,19 +505,9 @@ no_pnp:
        {
                unsigned int iobase = id_read_eeprom(8);
                if_port = iobase >> 14;
-#ifdef CONFIG_X86_PC9800
-               ioaddr = 0x40d0 + ((iobase & 0x1f) << 8);
-#else
                ioaddr = 0x200 + ((iobase & 0x1f) << 4);
-#endif
        }
        irq = id_read_eeprom(9) >> 12;
-#ifdef CONFIG_X86_PC9800
-       if (irq == 7)
-               irq = 6;
-       else if (irq == 15)
-               irq = 13;
-#endif
 
        dev = alloc_etherdev(sizeof (struct el3_private));
        if (!dev)
@@ -555,11 +538,7 @@ no_pnp:
        outb(0xd0 + ++current_tag, id_port);
 
        /* Activate the adaptor at the EEPROM location. */
-#ifdef CONFIG_X86_PC9800
-       outb((ioaddr >> 8) | 0xe0, id_port);
-#else
        outb((ioaddr >> 4) | 0xe0, id_port);
-#endif
 
        EL3WINDOW(0);
        if (inw(ioaddr) != 0x6d50)
@@ -568,7 +547,7 @@ no_pnp:
        /* Free the interrupt so that some other card can use it. */
        outw(0x0f00, ioaddr + WN0_IRQ);
 
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
  found:                                                        /* PNP jumps here... */
 #endif /* __ISAPNP__ */
 
@@ -577,7 +556,7 @@ no_pnp:
        dev->irq = irq;
        dev->if_port = if_port;
        lp = netdev_priv(dev);
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
        lp->dev = &idev->dev;
 #endif
        err = el3_common_init(dev);
@@ -601,7 +580,7 @@ no_pnp:
        return 0;
 
 out1:
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
        if (idev)
                pnp_device_detach(idev);
 #endif
@@ -1315,7 +1294,7 @@ el3_netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
  */
 
 static int
-netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
+netdev_ethtool_ioctl (struct net_device *dev, void __user *useraddr)
 {
        u32 ethcmd;
        struct el3_private *lp = netdev_priv(dev);
@@ -1323,7 +1302,7 @@ netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
        /* dev_ioctl() in ../../net/core/dev.c has already checked
           capable(CAP_NET_ADMIN), so don't bother with that here.  */
 
-       if (get_user(ethcmd, (u32 *)useraddr))
+       if (get_user(ethcmd, (u32 __user *)useraddr))
                return -EFAULT;
 
        switch (ethcmd) {
@@ -1412,7 +1391,7 @@ netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 
        switch (cmd) {
        case SIOCETHTOOL:
-               rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+               rc = netdev_ethtool_ioctl(dev, rq->ifr_data);
                break;
 
        default:
@@ -1461,12 +1440,6 @@ el3_up(struct net_device *dev)
        outw(0x0001, ioaddr + 4);
 
        /* Set the IRQ line. */
-#ifdef CONFIG_X86_PC9800
-       if (dev->irq == 6)
-               dev->irq = 7;
-       else if (dev->irq == 13)
-               dev->irq = 15;
-#endif
        outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
 
        /* Set the station address in window 2 each time opened. */
@@ -1629,7 +1602,7 @@ MODULE_PARM_DESC(debug, "debug level (0-6)");
 MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
 MODULE_PARM_DESC(xcvr,"transceiver(s) (0=internal, 1=external)");
 MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt");
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
 MODULE_PARM(nopnp, "i");
 MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)");
 MODULE_DEVICE_TABLE(isapnp, el3_isapnp_adapters);
index d479223..1902f79 100644 (file)
@@ -445,7 +445,7 @@ static int __init do_elmc_probe(struct net_device *dev)
                        slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
                        continue;
                }
-               if (!request_region(dev->base_addr, ELMC_IO_EXTENT, dev->name)) {
+               if (!request_region(dev->base_addr, ELMC_IO_EXTENT, DRV_NAME)) {
                        slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
                        continue;
                }
@@ -585,6 +585,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr, ELMC_IO_EXTENT);
 }
 
+#ifndef MODULE
 struct net_device * __init elmc_probe(int unit)
 {
        struct net_device *dev = alloc_etherdev(sizeof(struct priv));
@@ -609,6 +610,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 /**********************************************
  * init the chip (elmc-interrupt should be disabled?!)
index df3240c..c6f1995 100644 (file)
@@ -287,6 +287,7 @@ struct net_device *__init mc32_probe(int unit)
                        
                }
        }
+       free_netdev(dev);
        return ERR_PTR(-ENODEV);
 }
 
@@ -434,10 +435,10 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
         *      Grab the IRQ
         */
 
-       err = request_irq(dev->irq, &mc32_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
+       err = request_irq(dev->irq, &mc32_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM, DRV_NAME, dev);
        if (err) {
                release_region(dev->base_addr, MC32_IO_EXTENT);
-               printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
+               printk(KERN_ERR "%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
                goto err_exit_ports;
        }
 
index 9d436ae..255cc9f 100644 (file)
@@ -446,6 +446,7 @@ enum vortex_chips {
        CH_3C905B_2,
        CH_3C905B_FX,
        CH_3C905C,
+       CH_3C9202,
        CH_3C980,
        CH_3C9805,
 
@@ -520,12 +521,14 @@ static struct vortex_chip_info {
        {"3c905B-FX Cyclone 100baseFx",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
        {"3c905C Tornado",
-        PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
+       PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
+       {"3c920B-EMB-WNM (ATI Radeon 9100 IGP)",
+        PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, },
        {"3c980 Cyclone",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
+
        {"3c980C Python-T",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
-
        {"3cSOHO100-TX Hurricane",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
        {"3c555 Laptop Hurricane",
@@ -536,9 +539,9 @@ static struct vortex_chip_info {
        {"3c556B Laptop Hurricane",
         PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR|
                                        WNO_XCVR_PWR|HAS_HWCKSM, 128, },
+
        {"3c575 [Megahertz] 10/100 LAN  CardBus",
        PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
-
        {"3c575 Boomerang CardBus",
         PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
        {"3CCFE575BT Cyclone CardBus",
@@ -550,10 +553,10 @@ static struct vortex_chip_info {
        {"3CCFE656 Cyclone CardBus",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
                                                                        INVERT_LED_PWR|HAS_HWCKSM, 128, },
+
        {"3CCFEM656B Cyclone+Winmodem CardBus",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
                                                                        INVERT_LED_PWR|HAS_HWCKSM, 128, },
-
        {"3CXFEM656C Tornado+Winmodem CardBus",                 /* From pcmcia-cs-3.1.5 */
         PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
                                                                        MAX_COLLISION_RESET|HAS_HWCKSM, 128, },
@@ -563,9 +566,9 @@ static struct vortex_chip_info {
         PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
        {"3c982 Hydra Dual Port A",
         PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
+
        {"3c982 Hydra Dual Port B",
         PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
-
        {"3c905B-T4",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
        {"3c920B-EMB-WNM Tornado",
@@ -597,6 +600,7 @@ static struct pci_device_id vortex_pci_tbl[] = {
        { 0x10B7, 0x9058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_2 },
        { 0x10B7, 0x905A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_FX },
        { 0x10B7, 0x9200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905C },
+       { 0x10B7, 0x9202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9202 },
        { 0x10B7, 0x9800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C980 },
        { 0x10B7, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9805 },
 
@@ -1789,7 +1793,7 @@ vortex_timer(unsigned long data)
        struct net_device *dev = (struct net_device *)data;
        struct vortex_private *vp = netdev_priv(dev);
        long ioaddr = dev->base_addr;
-       int next_tick = 60*HZ;
+       int next_tick = 10*HZ;
        int ok = 0;
        int media_status, mii_status, old_window;
 
@@ -2874,7 +2878,7 @@ static int vortex_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct vortex_private *vp = netdev_priv(dev);
        long ioaddr = dev->base_addr;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+       struct mii_ioctl_data *data = if_mii(rq);
        int phy = vp->phys[0] & 0x1f;
        int retval;
 
@@ -2913,18 +2917,18 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        int err;
        struct vortex_private *vp = netdev_priv(dev);
        int state = 0;
-       
+
        if(VORTEX_PCI(vp))
                state = VORTEX_PCI(vp)->current_state;
 
        /* The kernel core really should have pci_get_power_state() */
 
        if(state != 0)
-               pci_set_power_state(VORTEX_PCI(vp), 0); 
+               pci_set_power_state(VORTEX_PCI(vp), 0);
        err = vortex_do_ioctl(dev, rq, cmd);
        if(state != 0)
-               pci_set_power_state(VORTEX_PCI(vp), state);     
-       
+               pci_set_power_state(VORTEX_PCI(vp), state);
+
        return err;
 }
 
index da98366..62dd139 100644 (file)
@@ -1546,7 +1546,6 @@ static struct ethtool_ops cp_ethtool_ops = {
 static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct cp_private *cp = netdev_priv(dev);
-       struct mii_ioctl_data *mii = (struct mii_ioctl_data *) &rq->ifr_data;
        int rc;
        unsigned long flags;
 
@@ -1554,7 +1553,7 @@ static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
                return -EINVAL;
 
        spin_lock_irqsave(&cp->lock, flags);
-       rc = generic_mii_ioctl(&cp->mii_if, mii, cmd, NULL);
+       rc = generic_mii_ioctl(&cp->mii_if, if_mii(rq), cmd, NULL);
        spin_unlock_irqrestore(&cp->lock, flags);
        return rc;
 }
index 511c2c8..6cc14fd 100644 (file)
@@ -87,8 +87,6 @@
                "rtl8139-diag -mmmaaavvveefN" output
                enable RTL8139_DEBUG below, and look at 'dmesg' or kernel log
 
-               See 8139too.txt for more details.
-
 */
 
 #define DRV_NAME       "8139too"
@@ -2458,14 +2456,13 @@ static struct ethtool_ops rtl8139_ethtool_ops = {
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct rtl8139_private *np = dev->priv;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
        int rc;
 
        if (!netif_running(dev))
                return -EINVAL;
 
        spin_lock_irq(&np->lock);
-       rc = generic_mii_ioctl(&np->mii, data, cmd, NULL);
+       rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
        spin_unlock_irq(&np->lock);
 
        return rc;
index 92cf5e0..51e04db 100644 (file)
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/pgtable.h>
-#include <asm/pgalloc.h>
 
 static char version[] __initdata =
        "82596.c $Revision: 1.5 $\n";
 
+#define DRV_NAME       "82596"
+
 /* DEBUG flags
  */
 
@@ -1191,7 +1192,7 @@ struct net_device * __init i82596_probe(int unit)
                /* this is easy the ethernet interface can only be at 0x300 */
                /* first check nothing is already registered here */
 
-               if (!request_region(ioaddr, I596_TOTAL_SIZE, dev->name)) {
+               if (!request_region(ioaddr, I596_TOTAL_SIZE, DRV_NAME)) {
                        printk(KERN_ERR "82596: IO address 0x%04x in use\n", ioaddr);
                        err = -EBUSY;
                        goto out;
index 346f595..a156a39 100644 (file)
@@ -922,7 +922,7 @@ config HP100
 
 config NET_ISA
        bool "Other ISA cards"
-       depends on NET_ETHERNET && ISA && !X86_PC9800
+       depends on NET_ETHERNET && ISA
        ---help---
          If your network (Ethernet) card hasn't been mentioned yet and its
          bus system (that's the way the cards talks to the other components
@@ -1104,56 +1104,6 @@ config SK_G16
          the Ethernet-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>.
 
-config NET_CBUS
-       bool "NEC PC-9800 C-bus cards"
-       depends on NET_ETHERNET && ISA && X86_PC9800
-       ---help---
-         If your network (Ethernet) card hasn't been mentioned yet and its
-         bus system (that's the way the cards talks to the other components
-         of your computer) is NEC PC-9800 C-Bus, say Y.
-
-config NE2K_CBUS
-       tristate "Most NE2000-based Ethernet support"
-       depends on NET_CBUS
-       select CRC32
-
-config NE2K_CBUS_EGY98
-       bool "Melco EGY-98 support"
-       depends on NE2K_CBUS
-
-config NE2K_CBUS_LGY98
-       bool "Melco LGY-98 support"
-       depends on NE2K_CBUS
-
-config NE2K_CBUS_ICM
-       bool "ICM IF-27xxET support"
-       depends on NE2K_CBUS
-
-config NE2K_CBUS_IOLA98
-       bool "I-O DATA LA-98 support"
-       depends on NE2K_CBUS
-
-config NE2K_CBUS_CNET98EL
-       bool "Contec C-NET(98)E/L support"
-       depends on NE2K_CBUS
-
-config NE2K_CBUS_CNET98EL_IO_BASE
-       hex "C-NET(98)E/L I/O base address (0xaaed or 0x55ed)"
-       depends on NE2K_CBUS_CNET98EL
-       default "0xaaed"
-
-config NE2K_CBUS_ATLA98
-       bool "Allied Telesis LA-98 Support"
-       depends on NE2K_CBUS
-
-config NE2K_CBUS_BDN
-       bool "ELECOM Laneed LD-BDN[123]A Support"
-       depends on NE2K_CBUS
-
-config NE2K_CBUS_NEC108
-       bool "NEC PC-9801-108 Support"
-       depends on NE2K_CBUS
-
 config SKMC
        tristate "SKnet MCA support"
        depends on NET_ETHERNET && MCA && BROKEN
@@ -1286,6 +1236,19 @@ config AMD8111_ETH
 config AMD8111E_NAPI
        bool "Enable NAPI support"
        depends on AMD8111_ETH
+       help
+         NAPI is a new driver API designed to reduce CPU and interrupt load
+         when the driver is receiving lots of packets from the card. It is
+         still somewhat experimental and thus not yet enabled by default.
+
+         If your estimated Rx load is 10kpps or more, or if the card will be
+         deployed on potentially unfriendly networks (e.g. in a firewall),
+         then say Y here.
+
+         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+         information.
+
+         If in doubt, say N.
 
 config ADAPTEC_STARFIRE
        tristate "Adaptec Starfire/DuraLAN support"
@@ -1313,6 +1276,11 @@ config ADAPTEC_STARFIRE_NAPI
          deployed on potentially unfriendly networks (e.g. in a firewall),
          then say Y here.
 
+         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+         information.
+
+         If in doubt, say N.
+
 config AC3200
        tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)"
        depends on NET_PCI && (ISA || EISA) && EXPERIMENTAL
@@ -1500,6 +1468,19 @@ config E100
 config E100_NAPI
        bool "Use Rx Polling (NAPI)"
        depends on E100
+       help
+         NAPI is a new driver API designed to reduce CPU and interrupt load
+         when the driver is receiving lots of packets from the card. It is
+         still somewhat experimental and thus not yet enabled by default.
+
+         If your estimated Rx load is 10kpps or more, or if the card will be
+         deployed on potentially unfriendly networks (e.g. in a firewall),
+         then say Y here.
+
+         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+         information.
+
+         If in doubt, say N.
 
 config LNE390
        tristate "Mylex EISA LNE390A/B support (EXPERIMENTAL)"
@@ -1604,9 +1585,7 @@ config 8139TOO
        ---help---
          This is a driver for the Fast Ethernet PCI network cards based on
          the RTL8139 chips. If you have one of those, say Y and read
-         <file:Documentation/networking/8139too.txt> as well as the
-         Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
+         the Ethernet-HOWTO <http://www.tldp.org/docs.html#howto>.
 
          To compile this driver as a module, choose M here: the module
          will be called 8139too.  This is recommended.
@@ -1744,6 +1723,17 @@ config VIA_RHINE_MMIO
 
          If unsure, say Y.
 
+config VIA_VELOCITY
+       tristate "VIA Velocity support"
+       depends on NET_PCI && PCI
+       select CRC32
+       select MII
+       help
+         If you have a VIA "Velocity" based network card say Y here.
+
+         To compile this driver as a module, choose M here. The module
+         will be called via-rhine.
+
 config LAN_SAA9730
        bool "Philips SAA9730 Ethernet support (EXPERIMENTAL)"
        depends on NET_PCI && EXPERIMENTAL && MIPS
@@ -1962,6 +1952,19 @@ config E1000
 config E1000_NAPI
        bool "Use Rx Polling (NAPI)"
        depends on E1000
+       help
+         NAPI is a new driver API designed to reduce CPU and interrupt load
+         when the driver is receiving lots of packets from the card. It is
+         still somewhat experimental and thus not yet enabled by default.
+
+         If your estimated Rx load is 10kpps or more, or if the card will be
+         deployed on potentially unfriendly networks (e.g. in a firewall),
+         then say Y here.
+
+         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+         information.
+
+         If in doubt, say N.
 
 config MYRI_SBUS
        tristate "MyriCOM Gigabit Ethernet support"
@@ -2147,6 +2150,19 @@ config IXGB
 config IXGB_NAPI
        bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
        depends on IXGB && EXPERIMENTAL
+       help
+         NAPI is a new driver API designed to reduce CPU and interrupt load
+         when the driver is receiving lots of packets from the card. It is
+         still somewhat experimental and thus not yet enabled by default.
+
+         If your estimated Rx load is 10kpps or more, or if the card will be
+         deployed on potentially unfriendly networks (e.g. in a firewall),
+         then say Y here.
+
+         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+         information.
+
+         If in doubt, say N.
 
 config S2IO
        tristate "S2IO 10Gbe XFrame NIC"
@@ -2159,6 +2175,19 @@ config S2IO
 config S2IO_NAPI
        bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
        depends on S2IO && EXPERIMENTAL
+       help
+         NAPI is a new driver API designed to reduce CPU and interrupt load
+         when the driver is receiving lots of packets from the card. It is
+         still somewhat experimental and thus not yet enabled by default.
+
+         If your estimated Rx load is 10kpps or more, or if the card will be
+         deployed on potentially unfriendly networks (e.g. in a firewall),
+         then say Y here.
+
+         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+         information.
+
+         If in doubt, say N.
 
 endmenu
 
index d8d8d90..b6ae311 100644 (file)
@@ -52,6 +52,7 @@ obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_SK98LIN) += sk98lin/
 obj-$(CONFIG_SKFP) += skfp/
 obj-$(CONFIG_VIA_RHINE) += via-rhine.o
+obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
 obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
 
 #
@@ -79,7 +80,6 @@ obj-$(CONFIG_ARM_ETHERH) += 8390.o
 obj-$(CONFIG_WD80x3) += wd.o 8390.o
 obj-$(CONFIG_EL2) += 3c503.o 8390.o
 obj-$(CONFIG_NE2000) += ne.o 8390.o
-obj-$(CONFIG_NE2K_CBUS) += ne2k_cbus.o 8390.o
 obj-$(CONFIG_NE2_MCA) += ne2.o 8390.o
 obj-$(CONFIG_HPLAN) += hp.o 8390.o
 obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390.o
index 7df6deb..797e93d 100644 (file)
@@ -191,8 +191,8 @@ static struct devprobe2 isa_probes[] __initdata = {
 #ifdef CONFIG_E2100            /* Cabletron E21xx series. */
        {e2100_probe, 0},
 #endif
-#if defined(CONFIG_NE2000) || defined(CONFIG_NE2K_CBUS)        || \
-    defined(CONFIG_NE_H8300)  /* ISA & PC-9800 CBUS (use ne2k-pci for PCI cards) */
+#if defined(CONFIG_NE2000) || \
+    defined(CONFIG_NE_H8300)  /* ISA (use ne2k-pci for PCI cards) */
        {ne_probe, 0},
 #endif
 #ifdef CONFIG_LANCE            /* ISA/VLB (use pcnet32 for PCI cards) */
index 22e1856..6f2e92f 100644 (file)
@@ -39,6 +39,8 @@ static const char version[] =
 
 #include "8390.h"
 
+#define DRV_NAME       "ac3200"
+
 /* Offsets from the base address. */
 #define AC_NIC_BASE    0x00
 #define AC_SA_PROM     0x16                    /* The station address PROM. */
@@ -130,6 +132,7 @@ static void cleanup_card(struct net_device *dev)
                iounmap((void *)dev->mem_start);
 }
 
+#ifndef MODULE
 struct net_device * __init ac3200_probe(int unit)
 {
        struct net_device *dev = alloc_ei_netdev();
@@ -154,12 +157,13 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init ac_probe1(int ioaddr, struct net_device *dev)
 {
        int i, retval;
 
-       if (!request_region(ioaddr, AC_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, AC_IO_EXTENT, DRV_NAME))
                return -EBUSY;
 
        if (inb_p(ioaddr + AC_ID_PORT) == 0xff) {
@@ -203,7 +207,7 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev)
                printk(", assigning");
        }
 
-       retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
+       retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
        if (retval) {
                printk (" nothing! Unable to get IRQ %d.\n", dev->irq);
                goto out1;
index d2c2370..6f04ee7 100644 (file)
@@ -85,6 +85,8 @@
 #include <asm/uaccess.h>
 
 
+#define DRV_NAME "acenic"
+
 #undef INDEX_DEBUG
 
 #ifdef CONFIG_ACENIC_OMIT_TIGON_I
@@ -443,6 +445,16 @@ static char version[]  =
   "acenic.c: v0.92 08/05/2002  Jes Sorensen, linux-acenic@SunSITE.dk\n"
   "                            http://home.cern.ch/~jes/gige/acenic.html\n";
 
+static int ace_get_settings(struct net_device *, struct ethtool_cmd *);
+static int ace_set_settings(struct net_device *, struct ethtool_cmd *);
+static void ace_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
+
+static struct ethtool_ops ace_ethtool_ops = {
+       .get_settings = ace_get_settings,
+       .set_settings = ace_set_settings,
+       .get_drvinfo = ace_get_drvinfo,
+};
+
 static int __devinit acenic_probe_one(struct pci_dev *pdev,
                const struct pci_device_id *id)
 {
@@ -480,7 +492,7 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev,
        dev->hard_start_xmit = &ace_start_xmit;
        dev->get_stats = &ace_get_stats;
        dev->set_multicast_list = &ace_set_multicast_list;
-       dev->do_ioctl = &ace_ioctl;
+       SET_ETHTOOL_OPS(dev, &ace_ethtool_ops);
        dev->set_mac_address = &ace_set_mac_addr;
        dev->change_mtu = &ace_change_mtu;
 
@@ -1195,10 +1207,10 @@ static int __init ace_init(struct net_device *dev)
        }
 
        ecode = request_irq(pdev->irq, ace_interrupt, SA_SHIRQ,
-                           dev->name, dev);
+                           DRV_NAME, dev);
        if (ecode) {
                printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
-                      dev->name, pdev->irq);
+                      DRV_NAME, pdev->irq);
                goto init_error;
        } else
                dev->irq = pdev->irq;
@@ -2688,146 +2700,136 @@ static int ace_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
-
-static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int ace_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
        struct ace_private *ap = dev->priv;
        struct ace_regs *regs = ap->regs;
-#ifdef SIOCETHTOOL
-       struct ethtool_cmd ecmd;
-       u32 link, speed;
+       u32 link;
 
-       if (cmd != SIOCETHTOOL)
-               return -EOPNOTSUPP;
-       if (copy_from_user(&ecmd, ifr->ifr_data, sizeof(ecmd)))
-               return -EFAULT;
-       switch (ecmd.cmd) {
-       case ETHTOOL_GSET:
-               ecmd.supported =
-                       (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
-                        SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
-                        SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full |
-                        SUPPORTED_Autoneg | SUPPORTED_FIBRE);
-
-               ecmd.port = PORT_FIBRE;
-               ecmd.transceiver = XCVR_INTERNAL;
-               ecmd.phy_address = 0;
-
-               link = readl(&regs->GigLnkState);
-               if (link & LNK_1000MB)
-                       ecmd.speed = SPEED_1000;
-               else {
-                       link = readl(&regs->FastLnkState);
-                       if (link & LNK_100MB)
-                               ecmd.speed = SPEED_100;
-                       else if (link & LNK_100MB)
-                               ecmd.speed = SPEED_10;
-                       else
-                               ecmd.speed = 0;
-               }
-               if (link & LNK_FULL_DUPLEX)
-                       ecmd.duplex = DUPLEX_FULL;
-               else
-                       ecmd.duplex = DUPLEX_HALF;
+       memset(ecmd, 0, sizeof(struct ethtool_cmd));
+       ecmd->supported =
+               (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+                SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+                SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full |
+                SUPPORTED_Autoneg | SUPPORTED_FIBRE);
+
+       ecmd->port = PORT_FIBRE;
+       ecmd->transceiver = XCVR_INTERNAL;
 
-               if (link & LNK_NEGOTIATE)
-                       ecmd.autoneg = AUTONEG_ENABLE;
+       link = readl(&regs->GigLnkState);
+       if (link & LNK_1000MB)
+               ecmd->speed = SPEED_1000;
+       else {
+               link = readl(&regs->FastLnkState);
+               if (link & LNK_100MB)
+                       ecmd->speed = SPEED_100;
+               else if (link & LNK_10MB)
+                       ecmd->speed = SPEED_10;
                else
-                       ecmd.autoneg = AUTONEG_DISABLE;
+                       ecmd->speed = 0;
+       }
+       if (link & LNK_FULL_DUPLEX)
+               ecmd->duplex = DUPLEX_FULL;
+       else
+               ecmd->duplex = DUPLEX_HALF;
+
+       if (link & LNK_NEGOTIATE)
+               ecmd->autoneg = AUTONEG_ENABLE;
+       else
+               ecmd->autoneg = AUTONEG_DISABLE;
 
 #if 0
-               /*
-                * Current struct ethtool_cmd is insufficient
-                */
-               ecmd.trace = readl(&regs->TuneTrace);
+       /*
+        * Current struct ethtool_cmd is insufficient
+        */
+       ecmd->trace = readl(&regs->TuneTrace);
 
-               ecmd.txcoal = readl(&regs->TuneTxCoalTicks);
-               ecmd.rxcoal = readl(&regs->TuneRxCoalTicks);
+       ecmd->txcoal = readl(&regs->TuneTxCoalTicks);
+       ecmd->rxcoal = readl(&regs->TuneRxCoalTicks);
 #endif
-               ecmd.maxtxpkt = readl(&regs->TuneMaxTxDesc);
-               ecmd.maxrxpkt = readl(&regs->TuneMaxRxDesc);
+       ecmd->maxtxpkt = readl(&regs->TuneMaxTxDesc);
+       ecmd->maxrxpkt = readl(&regs->TuneMaxRxDesc);
 
-               if(copy_to_user(ifr->ifr_data, &ecmd, sizeof(ecmd)))
-                       return -EFAULT;
-               return 0;
+       return 0;
+}
 
-       case ETHTOOL_SSET:
-               link = readl(&regs->GigLnkState);
-               if (link & LNK_1000MB)
-                       speed = SPEED_1000;
-               else {
-                       link = readl(&regs->FastLnkState);
-                       if (link & LNK_100MB)
-                               speed = SPEED_100;
-                       else if (link & LNK_100MB)
-                               speed = SPEED_10;
-                       else
-                               speed = SPEED_100;
-               }
+static int ace_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+       struct ace_private *ap = dev->priv;
+       struct ace_regs *regs = ap->regs;
+       u32 link, speed;
 
-               link = LNK_ENABLE | LNK_1000MB | LNK_100MB | LNK_10MB |
-                       LNK_RX_FLOW_CTL_Y | LNK_NEG_FCTL;
-               if (!ACE_IS_TIGON_I(ap))
-                       link |= LNK_TX_FLOW_CTL_Y;
-               if (ecmd.autoneg == AUTONEG_ENABLE)
-                       link |= LNK_NEGOTIATE;
-               if (ecmd.speed != speed) {
-                       link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
-                       switch (speed) {
-                       case SPEED_1000:
-                               link |= LNK_1000MB;
-                               break;
-                       case SPEED_100:
-                               link |= LNK_100MB;
-                               break;
-                       case SPEED_10:
-                               link |= LNK_10MB;
-                               break;
-                       }
+       link = readl(&regs->GigLnkState);
+       if (link & LNK_1000MB)
+               speed = SPEED_1000;
+       else {
+               link = readl(&regs->FastLnkState);
+               if (link & LNK_100MB)
+                       speed = SPEED_100;
+               else if (link & LNK_10MB)
+                       speed = SPEED_10;
+               else
+                       speed = SPEED_100;
+       }
+
+       link = LNK_ENABLE | LNK_1000MB | LNK_100MB | LNK_10MB |
+               LNK_RX_FLOW_CTL_Y | LNK_NEG_FCTL;
+       if (!ACE_IS_TIGON_I(ap))
+               link |= LNK_TX_FLOW_CTL_Y;
+       if (ecmd->autoneg == AUTONEG_ENABLE)
+               link |= LNK_NEGOTIATE;
+       if (ecmd->speed != speed) {
+               link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
+               switch (speed) {
+               case SPEED_1000:
+                       link |= LNK_1000MB;
+                       break;
+               case SPEED_100:
+                       link |= LNK_100MB;
+                       break;
+               case SPEED_10:
+                       link |= LNK_10MB;
+                       break;
                }
-               if (ecmd.duplex == DUPLEX_FULL)
-                       link |= LNK_FULL_DUPLEX;
+       }
 
-               if (link != ap->link) {
-                       struct cmd cmd;
-                       printk(KERN_INFO "%s: Renegotiating link state\n",
-                              dev->name);
+       if (ecmd->duplex == DUPLEX_FULL)
+               link |= LNK_FULL_DUPLEX;
 
-                       ap->link = link;
-                       writel(link, &regs->TuneLink);
-                       if (!ACE_IS_TIGON_I(ap))
-                               writel(link, &regs->TuneFastLink);
-                       wmb();
+       if (link != ap->link) {
+               struct cmd cmd;
+               printk(KERN_INFO "%s: Renegotiating link state\n",
+                      dev->name);
 
-                       cmd.evt = C_LNK_NEGOTIATION;
-                       cmd.code = 0;
-                       cmd.idx = 0;
-                       ace_issue_cmd(regs, &cmd);
-               }
-               return 0;
-
-       case ETHTOOL_GDRVINFO: {
-               struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
-               strncpy(info.driver, "acenic", sizeof(info.driver) - 1);
-               sprintf(info.fw_version, "%i.%i.%i", 
-                        tigonFwReleaseMajor, tigonFwReleaseMinor,
-                        tigonFwReleaseFix);
-               strncpy(info.version, version, sizeof(info.version) - 1);
-               if (ap && ap->pdev)
-                       strcpy(info.bus_info, pci_name(ap->pdev));
-               if (copy_to_user(ifr->ifr_data, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       default:
-               break;
-       }
-       
-#endif
+               ap->link = link;
+               writel(link, &regs->TuneLink);
+               if (!ACE_IS_TIGON_I(ap))
+                       writel(link, &regs->TuneFastLink);
+               wmb();
 
-       return -EOPNOTSUPP;
+               cmd.evt = C_LNK_NEGOTIATION;
+               cmd.code = 0;
+               cmd.idx = 0;
+               ace_issue_cmd(regs, &cmd);
+       }
+       return 0;
 }
 
+static void ace_get_drvinfo(struct net_device *dev, 
+                           struct ethtool_drvinfo *info)
+{
+       struct ace_private *ap = dev->priv;
+
+       strlcpy(info->driver, "acenic", sizeof(info->driver));
+       snprintf(info->version, sizeof(info->version), "%i.%i.%i", 
+               tigonFwReleaseMajor, tigonFwReleaseMinor,
+               tigonFwReleaseFix);
+
+       if (ap->pdev)
+               strlcpy(info->bus_info, pci_name(ap->pdev), 
+                       sizeof(info->bus_info));
+
+}
 
 /*
  * Set the hardware MAC address.
index eb516e1..c4624b8 100644 (file)
@@ -790,7 +790,6 @@ static void ace_tasklet(unsigned long dev);
 static void ace_dump_trace(struct ace_private *ap);
 static void ace_set_multicast_list(struct net_device *dev);
 static int ace_change_mtu(struct net_device *dev, int new_mtu);
-static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
 static int ace_set_mac_addr(struct net_device *dev, void *p);
 static void ace_set_rxtx_parms(struct net_device *dev, int jumbo);
 static int ace_allocate_descriptors(struct net_device *dev);
index c4491da..7b96c01 100755 (executable)
@@ -1571,7 +1571,7 @@ static void amd8111e_set_multicast_list(struct net_device *dev)
 This function handles all the  ethtool ioctls. It gives driver info, gets/sets driver speed, gets memory mapped register values, forces auto negotiation, sets/gets WOL options for ethtool application. 
 */
        
-static int amd8111e_ethtool_ioctl(struct net_device* dev, voiduseraddr)
+static int amd8111e_ethtool_ioctl(struct net_device* dev, void __user *useraddr)
 {
        struct amd8111e_priv *lp = netdev_priv(dev);
        struct pci_dev *pci_dev = lp->pci_dev;
@@ -1694,7 +1694,7 @@ static int amd8111e_ethtool_ioctl(struct net_device* dev, void* useraddr)
 }
 static int amd8111e_ioctl(struct net_device * dev , struct ifreq *ifr, int cmd)
 {
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
+       struct mii_ioctl_data *data = if_mii(ifr);
        struct amd8111e_priv *lp = netdev_priv(dev);
        int err;
        u32 mii_regval;
@@ -1704,7 +1704,7 @@ static int amd8111e_ioctl(struct net_device * dev , struct ifreq *ifr, int cmd)
 
        switch(cmd) {
        case SIOCETHTOOL:
-               return amd8111e_ethtool_ioctl(dev, (void *) ifr->ifr_data);
+               return amd8111e_ethtool_ioctl(dev, ifr->ifr_data);
        case SIOCGMIIPHY:
                data->phy_id = PHY_ID;
 
index 1b49b85..a94216b 100644 (file)
@@ -49,6 +49,8 @@
 
 /* ---- No user-serviceable parts below ---- */
 
+#define DRV_NAME "apne"
+
 #define NE_BASE         (dev->base_addr)
 #define NE_CMD                 0x00
 #define NE_DATAPORT            0x10            /* NatSemi-defined port window offset. */
@@ -168,7 +170,7 @@ struct net_device * __init apne_probe(int unit)
                return ERR_PTR(-ENODEV);
        }
 
-       if (!request_region(IOBASE, 0x20, dev->name)) {
+       if (!request_region(IOBASE, 0x20, DRV_NAME)) {
                free_netdev(dev);
                return ERR_PTR(-EBUSY);
        }
@@ -310,7 +312,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
     dev->base_addr = ioaddr;
 
     /* Install the Interrupt handler */
-    i = request_irq(IRQ_AMIGA_PORTS, apne_interrupt, SA_SHIRQ, dev->name, dev);
+    i = request_irq(IRQ_AMIGA_PORTS, apne_interrupt, SA_SHIRQ, DRV_NAME, dev);
     if (i) return i;
 
     for(i = 0; i < ETHER_ADDR_LEN; i++) {
index db21e0c..925dd04 100644 (file)
@@ -524,7 +524,7 @@ static void cops_reset(struct net_device *dev, int sleep)
 static void cops_load (struct net_device *dev)
 {
         struct ifreq ifr;
-        struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_data;
+        struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_ifru;
         struct cops_local *lp = netdev_priv(dev);
         int ioaddr=dev->base_addr;
        int length, i = 0;
index 8c0a962..8bf0bba 100644 (file)
@@ -259,7 +259,7 @@ static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt)
 
 static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-        struct ipddp_route *rt = (struct ipddp_route *)ifr->ifr_data;
+        struct ipddp_route __user *rt = ifr->ifr_data;
         struct ipddp_route rcp;
 
         if(!capable(CAP_NET_ADMIN))
index 06c1346..1ba12ab 100644 (file)
@@ -45,3 +45,20 @@ config ARM_ETHER00
          number (MTD support is required for this). Otherwise you will
          need to set a suitable hw address using ifconfig.
 
+config SMC91X
+       tristate "SMC 91C9x/91C1xxx support"
+       select CRC32
+       select MII
+       depends on ARM
+       help
+         This is a driver for SMC's 91x series of Ethernet chipsets,
+         including the SMC91C94 and the SMC91C111. Say Y if you want it
+         compiled into the kernel, and read the file
+         <file:Documentation/networking/smc9.txt>  and the Ethernet-HOWTO,
+         available from  <http://www.linuxdoc.org/docs.html#howto>.
+
+         This driver is also available as a module ( = code which can be
+         inserted in and removed from the running kernel whenever you want).
+         The module will be called smc91x.  If you want to compile it as a
+         module, say M here and read <file:Documentation/modules.txt> as well
+         as <file:Documentation/networking/net-modules.txt>.
index b0d7068..d6d87c0 100644 (file)
@@ -8,3 +8,4 @@ obj-$(CONFIG_ARM_ETHER00)       += ether00.o
 obj-$(CONFIG_ARM_ETHERH)       += etherh.o
 obj-$(CONFIG_ARM_ETHER3)       += ether3.o
 obj-$(CONFIG_ARM_ETHER1)       += ether1.o
+obj-$(CONFIG_SMC91X)           += smc91x.o
index 8bd25b9..6b28a3d 100644 (file)
@@ -53,25 +53,31 @@ static const char version[] =
 #ifdef __arm__
 static void write_rreg(u_long base, u_int reg, u_int val)
 {
-       __asm__("str%?h %1, [%2]        @ NET_RAP
-               str%?h  %0, [%2, #-4]   @ NET_RDP
-               " : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
+       __asm__(
+       "str%?h %1, [%2]        @ NET_RAP\n\t"
+       "str%?h %0, [%2, #-4]   @ NET_RDP"
+       :
+       : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
 }
 
 static inline unsigned short read_rreg(u_long base_addr, u_int reg)
 {
        unsigned short v;
-       __asm__("str%?h %1, [%2]        @ NET_RAP
-               ldr%?h  %0, [%2, #-4]   @ NET_RDP
-               " : "=r" (v): "r" (reg), "r" (ISAIO_BASE + 0x0464));
+       __asm__(
+       "str%?h %1, [%2]        @ NET_RAP\n\t"
+       "ldr%?h %0, [%2, #-4]   @ NET_RDP"
+       : "=r" (v)
+       : "r" (reg), "r" (ISAIO_BASE + 0x0464));
        return v;
 }
 
 static inline void write_ireg(u_long base, u_int reg, u_int val)
 {
-       __asm__("str%?h %1, [%2]        @ NET_RAP
-               str%?h  %0, [%2, #8]    @ NET_IDP
-               " : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
+       __asm__(
+       "str%?h %1, [%2]        @ NET_RAP\n\t"
+       "str%?h %0, [%2, #8]    @ NET_IDP"
+       :
+       : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
 }
 
 static inline unsigned short read_ireg(u_long base_addr, u_int reg)
@@ -101,16 +107,16 @@ am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigne
        }
        while (length > 8) {
                unsigned int tmp, tmp2;
-               __asm__ __volatile__("
-                       ldm%?ia %1!, {%2, %3}
-                       str%?h  %2, [%0], #4
-                       mov%?   %2, %2, lsr #16
-                       str%?h  %2, [%0], #4
-                       str%?h  %3, [%0], #4
-                       mov%?   %3, %3, lsr #16
-                       str%?h  %3, [%0], #4
-               : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2)
-                 : "0" (offset), "1" (buf));
+               __asm__ __volatile__(
+                       "ldm%?ia        %1!, {%2, %3}\n\t"
+                       "str%?h %2, [%0], #4\n\t"
+                       "mov%?  %2, %2, lsr #16\n\t"
+                       "str%?h %2, [%0], #4\n\t"
+                       "str%?h %3, [%0], #4\n\t"
+                       "mov%?  %3, %3, lsr #16\n\t"
+                       "str%?h %3, [%0], #4"
+               : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2)
+               : "0" (offset), "1" (buf));
                length -= 8;
        }
        while (length > 0) {
@@ -128,36 +134,36 @@ am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned
        length = (length + 1) & ~1;
        if ((int)buf & 2) {
                unsigned int tmp;
-               __asm__ __volatile__("
-                       ldr%?h  %2, [%0], #4
-                       str%?b  %2, [%1], #1
-                       mov%?   %2, %2, lsr #8
-                       str%?b  %2, [%1], #1
-               : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf));
+               __asm__ __volatile__(
+                       "ldr%?h %2, [%0], #4\n\t"
+                       "str%?b %2, [%1], #1\n\t"
+                       "mov%?  %2, %2, lsr #8\n\t"
+                       "str%?b %2, [%1], #1"
+               : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf));
                length -= 2;
        }
        while (length > 8) {
                unsigned int tmp, tmp2, tmp3;
-               __asm__ __volatile__("
-                       ldr%?h  %2, [%0], #4
-                       ldr%?h  %3, [%0], #4
-                       orr%?   %2, %2, %3, lsl #16
-                       ldr%?h  %3, [%0], #4
-                       ldr%?h  %4, [%0], #4
-                       orr%?   %3, %3, %4, lsl #16
-                       stm%?ia %1!, {%2, %3}
-               : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3)
-                 : "0" (offset), "1" (buf));
+               __asm__ __volatile__(
+                       "ldr%?h %2, [%0], #4\n\t"
+                       "ldr%?h %3, [%0], #4\n\t"
+                       "orr%?  %2, %2, %3, lsl #16\n\t"
+                       "ldr%?h %3, [%0], #4\n\t"
+                       "ldr%?h %4, [%0], #4\n\t"
+                       "orr%?  %3, %3, %4, lsl #16\n\t"
+                       "stm%?ia        %1!, {%2, %3}"
+               : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3)
+               : "0" (offset), "1" (buf));
                length -= 8;
        }
        while (length > 0) {
                unsigned int tmp;
-               __asm__ __volatile__("
-                       ldr%?h  %2, [%0], #4
-                       str%?b  %2, [%1], #1
-                       mov%?   %2, %2, lsr #8
-                       str%?b  %2, [%1], #1
-               : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf));
+               __asm__ __volatile__(
+                       "ldr%?h %2, [%0], #4\n\t"
+                       "str%?b %2, [%1], #1\n\t"
+                       "mov%?  %2, %2, lsr #8\n\t"
+                       "str%?b %2, [%1], #1"
+               : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf));
                length -= 2;
        }
 }
@@ -618,6 +624,7 @@ am79c961_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                if (status & CSR0_CERR) {
                        handled = 1;
                        mod_timer(&priv->timer, jiffies);
+               }
        } while (--n && status & (CSR0_RINT | CSR0_TINT));
 
        return IRQ_RETVAL(handled);
index 7543bfb..8725374 100644 (file)
@@ -65,6 +65,8 @@
 static char version[] __initdata =
        "at1700.c:v1.15 4/7/98  Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
+#define DRV_NAME "at1700"
+
 /* Tunable parameters. */
 
 /* When to switch from the 64-entry multicast filter to Rx-all-multicast. */
@@ -80,17 +82,10 @@ static int fmv18x_probe_list[] __initdata = {
  *     ISA
  */
 
-#ifndef CONFIG_X86_PC9800
 static unsigned at1700_probe_list[] __initdata = {
        0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
 };
 
-#else /* CONFIG_X86_PC9800 */
-static unsigned at1700_probe_list[] __initdata = {
-       0x1d6, 0x1d8, 0x1da, 0x1d4, 0xd4, 0xd2, 0xd8, 0xd0, 0
-};
-
-#endif /* CONFIG_X86_PC9800 */
 /*
  *     MCA
  */
@@ -133,7 +128,6 @@ struct net_local {
 
 
 /* Offsets from the base address. */
-#ifndef CONFIG_X86_PC9800
 #define STATUS                 0
 #define TX_STATUS              0
 #define RX_STATUS              1
@@ -161,34 +155,6 @@ struct net_local {
 #define RESET                  31              /* Write to reset some parts of the chip. */
 #define AT1700_IO_EXTENT       32
 #define PORT_OFFSET(o) (o)
-#else /* CONFIG_X86_PC9800 */
-#define STATUS                 (0x0000)
-#define TX_STATUS              (0x0000)
-#define RX_STATUS              (0x0001)
-#define TX_INTR                        (0x0200)/* Bit-mapped interrupt enable registers. */
-#define RX_INTR                        (0x0201)
-#define TX_MODE                        (0x0400)
-#define RX_MODE                        (0x0401)
-#define CONFIG_0               (0x0600)/* Misc. configuration settings. */
-#define CONFIG_1               (0x0601)
-/* Run-time register bank 2 definitions. */
-#define DATAPORT               (0x0800)/* Word-wide DMA or programmed-I/O dataport. */
-#define TX_START               (0x0a00)
-#define COL16CNTL              (0x0a01)/* Controll Reg for 16 collisions */
-#define MODE13                 (0x0c01)
-#define RX_CTRL                        (0x0e00)
-/* Configuration registers only on the '865A/B chips. */
-#define EEPROM_Ctrl    (0x1000)
-#define EEPROM_Data    (0x1200)
-#define CARDSTATUS     16                      /* FMV-18x Card Status */
-#define CARDSTATUS1    17                      /* FMV-18x Card Status */
-#define IOCONFIG               (0x1400)/* Either read the jumper, or move the I/O. */
-#define IOCONFIG1              (0x1600)
-#define        SAPROM                  20              /* The station address PROM, if no EEPROM. */
-#define        MODE24                  (0x1800)/* The station address PROM, if no EEPROM. */
-#define RESET                  (0x1e01)/* Write to reset some parts of the chip. */
-#define PORT_OFFSET(o) ({ int _o_ = (o); (_o_ & ~1) * 0x100 + (_o_ & 1); })
-#endif /* CONFIG_X86_PC9800 */
 
 
 #define TX_TIMEOUT             10
@@ -230,11 +196,7 @@ static struct at1720_mca_adapters_struct at1720_mca_adapters[] __initdata = {
    (detachable devices only).
    */
 
-#ifndef CONFIG_X86_PC9800
 static int io = 0x260;
-#else
-static int io = 0xd0;
-#endif
 
 static int irq;
 
@@ -242,19 +204,11 @@ static void cleanup_card(struct net_device *dev)
 {
 #ifdef CONFIG_MCA      
        struct net_local *lp = netdev_priv(dev);
-       if (lp->mca_slot)
+       if (lp->mca_slot >= 0)
                mca_mark_as_unused(lp->mca_slot);
 #endif 
        free_irq(dev->irq, NULL);
-#ifndef CONFIG_X86_PC9800
        release_region(dev->base_addr, AT1700_IO_EXTENT);
-#else
-       {
-               int i;
-               for (i = 0; i < 0x2000; i += 0x200)
-                       release_region(dev->base_addr + i, 2);
-       }
-#endif
 }
 
 struct net_device * __init at1700_probe(int unit)
@@ -321,20 +275,8 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr)
        int slot, ret = -ENODEV;
        struct net_local *lp = netdev_priv(dev);
 
-#ifndef CONFIG_X86_PC9800
-       if (!request_region(ioaddr, AT1700_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, AT1700_IO_EXTENT, DRV_NAME))
                return -EBUSY;
-#else
-       for (i = 0; i < 0x2000; i += 0x0200) {
-               if (!request_region(ioaddr + i, 2, dev->name)) {
-                       while (i > 0) {
-                               i -= 0x0200;
-                               release_region(ioaddr + i, 2);
-                       }
-                       return -EBUSY;
-               }
-       }
-#endif
 
        /* Resetting the chip doesn't reset the ISA interface, so don't bother.
           That means we have to be careful with the register values we probe
@@ -425,15 +367,8 @@ found:
        outb(0, ioaddr + RESET);
 
        if (is_at1700) {
-#ifndef CONFIG_X86_PC9800
                irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04)
                                                   | (read_eeprom(ioaddr, 0)>>14)];
-#else
-               {
-                       char re1000plus_irqmap[4] = {3, 5, 6, 12};
-                       irq = re1000plus_irqmap[inb(ioaddr + IOCONFIG1) >> 6];
-               }
-#endif
        } else {
                /* Check PnP mode for FMV-183/184/183A/184A. */
                /* This PnP routine is very poor. IO and IRQ should be known. */
@@ -444,11 +379,11 @@ found:
                                        break;
                        }
                        if (i == 8) {
-                               goto err_out;
+                               goto err_mca;
                        }
                } else {
                        if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] != ioaddr)
-                               goto err_out;
+                               goto err_mca;
                        irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03];
                }
        }
@@ -517,11 +452,7 @@ found:
        /* Switch to bank 2 */
        /* Lock our I/O address, and set manual processing mode for 16 collisions. */
        outb(0x08, ioaddr + CONFIG_1);
-#ifndef CONFIG_X86_PC9800
        outb(dev->if_port, ioaddr + MODE13);
-#else
-       outb(0, ioaddr + MODE13);
-#endif
        outb(0x00, ioaddr + COL16CNTL);
 
        if (net_debug)
@@ -542,22 +473,22 @@ found:
        lp->jumpered = is_fmv18x;
        lp->mca_slot = slot;
        /* Snarf the interrupt vector now. */
-       ret = request_irq(irq, &net_interrupt, 0, dev->name, dev);
+       ret = request_irq(irq, &net_interrupt, 0, DRV_NAME, dev);
        if (ret) {
                printk ("  AT1700 at %#3x is unusable due to a conflict on"
                                "IRQ %d.\n", ioaddr, irq);
-               goto err_out;
+               goto err_mca;
        }
 
        return 0;
 
+err_mca:
+#ifdef CONFIG_MCA
+       if (slot >= 0)
+               mca_mark_as_unused(slot);
+#endif
 err_out:
-#ifndef CONFIG_X86_PC9800
        release_region(ioaddr, AT1700_IO_EXTENT);
-#else
-       for (i = 0; i < 0x2000; i += 0x0200)
-               release_region(ioaddr + i, 2);
-#endif
        return ret;
 }
 
@@ -568,13 +499,6 @@ err_out:
 #define EE_DATA_WRITE  0x80    /* EEPROM chip data in, in reg. 17. */
 #define EE_DATA_READ   0x80    /* EEPROM chip data out, in reg. 17. */
 
-/* Delay between EEPROM clock transitions. */
-#ifndef CONFIG_X86_PC9800
-#define eeprom_delay() do { } while (0)
-#else
-#define eeprom_delay() __asm__ ("out%B0 %%al,%0" :: "N"(0x5f))
-#endif
-
 /* The EEPROM commands include the alway-set leading bit. */
 #define EE_WRITE_CMD   (5 << 6)
 #define EE_READ_CMD            (6 << 6)
@@ -593,22 +517,17 @@ static int __init read_eeprom(long ioaddr, int location)
                short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
                outb(EE_CS, ee_addr);
                outb(dataval, ee_daddr);
-               eeprom_delay();
                outb(EE_CS | EE_SHIFT_CLK, ee_addr);    /* EEPROM clock tick. */
-               eeprom_delay();
        }
        outb(EE_DATA_WRITE, ee_daddr);
        for (i = 16; i > 0; i--) {
                outb(EE_CS, ee_addr);
-               eeprom_delay();
                outb(EE_CS | EE_SHIFT_CLK, ee_addr);
-               eeprom_delay();
                retval = (retval << 1) | ((inb(ee_daddr) & EE_DATA_READ) ? 1 : 0);
        }
 
        /* Terminate the EEPROM access. */
        outb(EE_CS, ee_addr);
-       eeprom_delay();
        outb(EE_SHIFT_CLK, ee_addr);
        outb(0, ee_addr);
        return retval;
index 2bd0ac9..afcdcff 100644 (file)
@@ -1269,7 +1269,7 @@ static void set_rx_mode(struct net_device *dev)
 
 static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-       u16 *data = (u16 *)&rq->ifr_data;
+       u16 *data = (u16 *)&rq->ifr_ifru;
 
        /* fixme */
        switch(cmd) { 
index d7f2142..ba1d4fc 100644 (file)
@@ -1633,7 +1633,7 @@ static struct ethtool_ops b44_ethtool_ops = {
 
 static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-       struct mii_ioctl_data __user *data = (struct mii_ioctl_data __user *)&ifr->ifr_data;
+       struct mii_ioctl_data *data = if_mii(ifr);
        struct b44 *bp = netdev_priv(dev);
        int err;
 
index 778fd07..6e57c14 100644 (file)
@@ -1103,7 +1103,7 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
 
                /* Yes, the mii is overlaid on the ifreq.ifr_ifru */
                strncpy(ifr.ifr_name, slave_dev->name, IFNAMSIZ);
-               mii = (struct mii_ioctl_data *)&ifr.ifr_data;
+               mii = if_mii(&ifr);
                if (IOCTL(slave_dev, &ifr, SIOCGMIIPHY) == 0) {
                        mii->reg_num = MII_BMSR;
                        if (IOCTL(slave_dev, &ifr, SIOCGMIIREG) == 0) {
@@ -2357,10 +2357,10 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
 static int bond_ethtool_ioctl(struct net_device *bond_dev, struct ifreq *ifr)
 {
        struct ethtool_drvinfo info;
-       void *addr = ifr->ifr_data;
+       void __user *addr = ifr->ifr_data;
        uint32_t cmd;
 
-       if (get_user(cmd, (uint32_t *)addr)) {
+       if (get_user(cmd, (uint32_t __user *)addr)) {
                return -EFAULT;
        }
 
@@ -3667,8 +3667,10 @@ static struct net_device_stats *bond_get_stats(struct net_device *bond_dev)
 static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd)
 {
        struct net_device *slave_dev = NULL;
-       struct ifbond *u_binfo = NULL, k_binfo;
-       struct ifslave *u_sinfo = NULL, k_sinfo;
+       struct ifbond k_binfo;
+       struct ifbond __user *u_binfo = NULL;
+       struct ifslave k_sinfo;
+       struct ifslave __user *u_sinfo = NULL;
        struct mii_ioctl_data *mii = NULL;
        int prev_abi_ver = orig_app_abi_ver;
        int res = 0;
@@ -3680,7 +3682,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
        case SIOCETHTOOL:
                return bond_ethtool_ioctl(bond_dev, ifr);
        case SIOCGMIIPHY:
-               mii = (struct mii_ioctl_data *)&ifr->ifr_data;
+               mii = if_mii(ifr);
                if (!mii) {
                        return -EINVAL;
                }
@@ -3691,7 +3693,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
                 * We do this again just in case we were called by SIOCGMIIREG
                 * instead of SIOCGMIIPHY.
                 */
-               mii = (struct mii_ioctl_data *)&ifr->ifr_data;
+               mii = if_mii(ifr);
                if (!mii) {
                        return -EINVAL;
                }
@@ -3711,7 +3713,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
                return 0;
        case BOND_INFO_QUERY_OLD:
        case SIOCBONDINFOQUERY:
-               u_binfo = (struct ifbond *)ifr->ifr_data;
+               u_binfo = (struct ifbond __user *)ifr->ifr_data;
 
                if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond))) {
                        return -EFAULT;
@@ -3727,7 +3729,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
                return res;
        case BOND_SLAVE_INFO_QUERY_OLD:
        case SIOCBONDSLAVEINFOQUERY:
-               u_sinfo = (struct ifslave *)ifr->ifr_data;
+               u_sinfo = (struct ifslave __user *)ifr->ifr_data;
 
                if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave))) {
                        return -EFAULT;
index 9745bf6..7e616f7 100644 (file)
 static char version[] __initdata =
 "cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>\n";
 
+#define DRV_NAME "cs89x0"
+
 /* First, a few definitions that the brave might change.
    A zero-terminated list of I/O addresses to be probed. Some special flags..
       Addr & 1 = Read back the address port, look for signature and reset
@@ -261,7 +263,6 @@ static int __init media_fn(char *str)
 }
 
 __setup("cs89x0_media=", media_fn);
-#endif
 
 \f
 /* Check for a network adaptor of this type, and return '0' iff one exists.
@@ -318,6 +319,7 @@ out:
        printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected.  Be sure to disable PnP with SETUP\n");
        return ERR_PTR(err);
 }
+#endif
 
 static int
 readreg(struct net_device *dev, int portno)
@@ -425,9 +427,9 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
 
        /* Grab the region so we can find another board if autoIRQ fails. */
        /* WTF is going on here? */
-       if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, dev->name)) {
+       if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) {
                printk(KERN_ERR "%s: request_region(0x%x, 0x%x) failed\n",
-                               dev->name, ioaddr, NETCARD_IO_EXTENT);
+                               DRV_NAME, ioaddr, NETCARD_IO_EXTENT);
                retval = -EBUSY;
                goto out1;
        }
index cada0c6..9ef9f39 100644 (file)
 static char version[] __devinitdata =
        "defxx.c:v1.06 2003/08/04  Lawrence V. Stefani and others\n";
 
+#define DRV_NAME "defxx"
+
 #define DYNAMIC_BUFFERS 1
 
 #define SKBUFF_RX_COPYBREAK 200
@@ -435,9 +437,9 @@ static int __devinit dfx_init_one_pci_or_eisa(struct pci_dev *pdev, long ioaddr)
 
        bp = dev->priv;
 
-       if (!request_region (ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN, dev->name)) {
+       if (!request_region (ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN, DRV_NAME)) {
                printk (KERN_ERR "%s: Cannot reserve I/O resource 0x%x @ 0x%lx, aborting\n",
-                       dev->name, PFI_K_CSR_IO_LEN, ioaddr);
+                       DRV_NAME, PFI_K_CSR_IO_LEN, ioaddr);
                err = -EBUSY;
                goto err_out;
        }
index 80e8617..5d62a03 100644 (file)
@@ -1937,7 +1937,7 @@ static void depca_dbg_open(struct net_device *dev)
 static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct depca_private *lp = (struct depca_private *) dev->priv;
-       struct depca_ioctl *ioc = (struct depca_ioctl *) &rq->ifr_data;
+       struct depca_ioctl *ioc = (struct depca_ioctl *) &rq->ifr_ifru;
        int i, status = 0;
        u_long ioaddr = dev->base_addr;
        union {
index 2fa1558..1178527 100644 (file)
 struct depca_ioctl {
        unsigned short cmd;                /* Command to run */
        unsigned short len;                /* Length of the data buffer */
-       unsigned char  *data;              /* Pointer to the data buffer */
+       unsigned char  __user *data;       /* Pointer to the data buffer */
 };
 
 /* 
index 4673bd8..39cabaf 100644 (file)
@@ -107,7 +107,7 @@ static int change_mtu (struct net_device *dev, int new_mtu);
 static void set_multicast (struct net_device *dev);
 static struct net_device_stats *get_stats (struct net_device *dev);
 static int clear_stats (struct net_device *dev);
-static int rio_ethtool_ioctl (struct net_device *dev, void *useraddr);
+static int rio_ethtool_ioctl (struct net_device *dev, void __user *useraddr);
 static int rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
 static int rio_close (struct net_device *dev);
 static int find_miiphy (struct net_device *dev);
@@ -1195,7 +1195,7 @@ set_multicast (struct net_device *dev)
 }
 
 static int
-rio_ethtool_ioctl (struct net_device *dev, void *useraddr)
+rio_ethtool_ioctl (struct net_device *dev, void __user *useraddr)
 {
        struct netdev_private *np = dev->priv;
                u32 ethcmd;
@@ -1325,7 +1325,7 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 {
        int phy_addr;
        struct netdev_private *np = dev->priv;
-       struct mii_data *miidata = (struct mii_data *) &rq->ifr_data;
+       struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru;
        
        struct netdev_desc *desc;
        int i;
@@ -1333,7 +1333,7 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
        phy_addr = np->phy_addr;
        switch (cmd) {
        case SIOCETHTOOL:
-               return rio_ethtool_ioctl (dev, (void *) rq->ifr_data);          
+               return rio_ethtool_ioctl(dev, rq->ifr_data);            
        case SIOCDEVPRIVATE:
                break;
        
index 4b95580..8855b20 100644 (file)
@@ -827,8 +827,8 @@ static inline int e100_exec_cb(struct nic *nic, struct sk_buff *skb,
        cb->prev->command &= cpu_to_le16(~cb_s);
 
        while(nic->cb_to_send != nic->cb_to_use) {
-               if(unlikely((err = e100_exec_cmd(nic, nic->cuc_cmd,
-                       nic->cb_to_send->dma_addr)))) {
+               if(unlikely(e100_exec_cmd(nic, nic->cuc_cmd,
+                       nic->cb_to_send->dma_addr))) {
                        /* Ok, here's where things get sticky.  It's
                         * possible that we can't schedule the command
                         * because the controller is too busy, so
@@ -1323,7 +1323,7 @@ static inline int e100_tx_clean(struct nic *nic)
 static void e100_clean_cbs(struct nic *nic)
 {
        if(nic->cbs) {
-               while(nic->cb_to_clean != nic->cb_to_use) {
+               while(nic->cbs_avail != nic->params.cbs.count) {
                        struct cb *cb = nic->cb_to_clean;
                        if(cb->skb) {
                                pci_unmap_single(nic->pdev,
@@ -1333,8 +1333,8 @@ static void e100_clean_cbs(struct nic *nic)
                                dev_kfree_skb(cb->skb);
                        }
                        nic->cb_to_clean = nic->cb_to_clean->next;
+                       nic->cbs_avail++;
                }
-               nic->cbs_avail = nic->params.cbs.count;
                pci_free_consistent(nic->pdev,
                        sizeof(struct cb) * nic->params.cbs.count,
                        nic->cbs, nic->cbs_dma_addr);
@@ -1659,17 +1659,16 @@ static int e100_up(struct nic *nic)
                goto err_clean_cbs;
        e100_set_multicast_list(nic->netdev);
        e100_start_receiver(nic);
-       netif_start_queue(nic->netdev);
        mod_timer(&nic->watchdog, jiffies);
        if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
                nic->netdev->name, nic->netdev)))
                goto err_no_irq;
        e100_enable_irq(nic);
+       netif_wake_queue(nic->netdev);
        return 0;
 
 err_no_irq:
        del_timer_sync(&nic->watchdog);
-       netif_stop_queue(nic->netdev);
 err_clean_cbs:
        e100_clean_cbs(nic);
 err_rx_clean_list:
@@ -2075,9 +2074,8 @@ static struct ethtool_ops e100_ethtool_ops = {
 static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 {
        struct nic *nic = netdev_priv(netdev);
-       struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr->ifr_data;
 
-       return generic_mii_ioctl(&nic->mii, mii, cmd, NULL);
+       return generic_mii_ioctl(&nic->mii, if_mii(ifr), cmd, NULL);
 }
 
 static int e100_alloc(struct nic *nic)
index 0394fd2..9ca716e 100644 (file)
@@ -1004,11 +1004,12 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter)
                struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i);
                struct sk_buff *skb;
 
-               if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + 2, GFP_KERNEL))) {
+               if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN,
+                                    GFP_KERNEL))) {
                        ret_val = 6;
                        goto err_nomem;
                }
-               skb_reserve(skb, 2);
+               skb_reserve(skb, NET_IP_ALIGN);
                rxdr->buffer_info[i].skb = skb;
                rxdr->buffer_info[i].length = E1000_RXBUFFER_2048;
                rxdr->buffer_info[i].dma =
index 8a8173c..b575268 100644 (file)
@@ -52,7 +52,7 @@
 
 char e1000_driver_name[] = "e1000";
 char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-char e1000_driver_version[] = "5.2.52-k2";
+char e1000_driver_version[] = "5.2.52-k4";
 char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
@@ -2143,6 +2143,7 @@ e1000_clean(struct net_device *netdev, int *budget)
        if(work_done < work_to_do || !netif_running(netdev)) {
                netif_rx_complete(netdev);
                e1000_irq_enable(adapter);
+               return 0;
        }
 
        return (work_done >= work_to_do);
@@ -2366,7 +2367,6 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
        struct e1000_rx_desc *rx_desc;
        struct e1000_buffer *buffer_info;
        struct sk_buff *skb;
-       int reserve_len = 2;
        unsigned int i;
 
        i = rx_ring->next_to_use;
@@ -2375,7 +2375,7 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
        while(!buffer_info->skb) {
                rx_desc = E1000_RX_DESC(*rx_ring, i);
 
-               skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len);
+               skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
 
                if(!skb) {
                        /* Better luck next round */
@@ -2386,7 +2386,7 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
                 * this will result in a 16 byte aligned IP header after
                 * the 14 byte MAC header is removed
                 */
-               skb_reserve(skb, reserve_len);
+               skb_reserve(skb, NET_IP_ALIGN);
 
                skb->dev = netdev;
 
@@ -2503,7 +2503,7 @@ static int
 e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 {
        struct e1000_adapter *adapter = netdev->priv;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
+       struct mii_ioctl_data *data = if_mii(ifr);
        int retval;
        uint16_t mii_reg;
        uint16_t spddplx;
index 71c632b..7fc9860 100644 (file)
@@ -51,6 +51,8 @@ static const char version[] =
 
 #include "8390.h"
 
+#define DRV_NAME "e2100"
+
 static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0};
 
 /* Offsets from the base_addr.
@@ -144,6 +146,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr, E21_IO_EXTENT);
 }
 
+#ifndef MODULE
 struct net_device * __init e2100_probe(int unit)
 {
        struct net_device *dev = alloc_ei_netdev();
@@ -168,6 +171,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init e21_probe1(struct net_device *dev, int ioaddr)
 {
@@ -175,7 +179,7 @@ static int __init e21_probe1(struct net_device *dev, int ioaddr)
        unsigned char *station_addr = dev->dev_addr;
        static unsigned version_printed;
 
-       if (!request_region(ioaddr, E21_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, E21_IO_EXTENT, DRV_NAME))
                return -EBUSY;
 
        /* First check the station address for the Ctron prefix. */
index 785daf6..9f5ea60 100644 (file)
@@ -151,6 +151,8 @@ static const char version[] =
 #include <asm/io.h>
 #include <asm/dma.h>
 
+#define DRV_NAME "eepro"
+
 #define compat_dev_kfree_skb( skb, mode ) dev_kfree_skb( (skb) )
 /* I had reports of looong delays with SLOW_DOWN defined as udelay(2) */
 #define SLOW_DOWN inb(0x80)
@@ -577,6 +579,7 @@ static int __init do_eepro_probe(struct net_device *dev)
        return -ENODEV;
 }
 
+#ifndef MODULE
 struct net_device * __init eepro_probe(int unit)
 {
        struct net_device *dev = alloc_etherdev(sizeof(struct eepro_local));
@@ -603,6 +606,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static void __init printEEPROMInfo(short ioaddr, struct net_device *dev)
 {
@@ -745,7 +749,7 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
        int ioaddr = dev->base_addr;
 
        /* Grab the region so we can find another board if autoIRQ fails. */
-       if (!request_region(ioaddr, EEPRO_IO_EXTENT, dev->name)) { 
+       if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) { 
                if (!autoprobe)
                        printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n",
                                ioaddr);
index f460db4..56fc878 100644 (file)
@@ -2017,7 +2017,7 @@ speedo_get_stats(struct net_device *dev)
        return &sp->stats;
 }
 
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
        u32 ethcmd;
        struct speedo_private *sp = netdev_priv(dev);
@@ -2096,7 +2096,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
 static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct speedo_private *sp = netdev_priv(dev);
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+       struct mii_ioctl_data *data = if_mii(rq);
        int phy = sp->phy[0] & 0x1f;
        int saved_acpi;
        int t;
@@ -2129,7 +2129,7 @@ static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                pci_set_power_state(sp->pdev, saved_acpi);
                return 0;
        case SIOCETHTOOL:
-               return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+               return netdev_ethtool_ioctl(dev, rq->ifr_data);
        default:
                return -EOPNOTSUPP;
        }
index 24663cb..a379c0a 100644 (file)
@@ -423,6 +423,7 @@ static int __init do_express_probe(struct net_device *dev)
        return -ENODEV;
 }
 
+#ifndef MODULE
 struct net_device * __init express_probe(int unit)
 {
        struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
@@ -443,6 +444,7 @@ struct net_device * __init express_probe(int unit)
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 /*
  * open and initialize the adapter, ready for use
index cf7ae05..e81e0af 100644 (file)
        LK1.1.14 (Kryzsztof Halasa):
        * fix spurious bad initializations
        * pound phy a la SMSC's app note on the subject
+       
+       AC1.1.14ac
+       * fix power up/down for ethtool that broke in 1.11
 
 */
 
 #define DRV_NAME        "epic100"
-#define DRV_VERSION     "1.11+LK1.1.14"
-#define DRV_RELDATE     "Aug 4, 2002"
+#define DRV_VERSION     "1.11+LK1.1.14+AC1.1.14"
+#define DRV_RELDATE     "June 2, 2004"
 
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
@@ -1215,13 +1218,8 @@ static int epic_rx(struct net_device *dev)
                                                            ep->rx_ring[entry].bufaddr,
                                                            ep->rx_buf_sz,
                                                            PCI_DMA_FROMDEVICE);
-#if 1 /* HAS_IP_COPYSUM */
                                eth_copy_and_sum(skb, ep->rx_skbuff[entry]->tail, pkt_len, 0);
                                skb_put(skb, pkt_len);
-#else
-                               memcpy(skb_put(skb, pkt_len), ep->rx_skbuff[entry]->tail,
-                                          pkt_len);
-#endif
                                pci_dma_sync_single_for_device(ep->pci_dev,
                                                               ep->rx_ring[entry].bufaddr,
                                                               ep->rx_buf_sz,
@@ -1424,6 +1422,27 @@ static void netdev_set_msglevel(struct net_device *dev, u32 value)
        debug = value;
 }
 
+static int ethtool_begin(struct net_device *dev)
+{
+       unsigned long ioaddr = dev->base_addr;
+       /* power-up, if interface is down */
+       if (! netif_running(dev)) {
+               outl(0x0200, ioaddr + GENCTL);
+               outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
+       }
+       return 0;
+}
+
+static void ethtool_complete(struct net_device *dev)
+{
+       unsigned long ioaddr = dev->base_addr;
+       /* power-down, if interface is down */
+       if (! netif_running(dev)) {
+               outl(0x0008, ioaddr + GENCTL);
+               outl((inl(ioaddr + NVCTL) & ~0x483C) | 0x0000, ioaddr + NVCTL);
+       }
+}
+
 static struct ethtool_ops netdev_ethtool_ops = {
        .get_drvinfo            = netdev_get_drvinfo,
        .get_settings           = netdev_get_settings,
@@ -1434,13 +1453,15 @@ static struct ethtool_ops netdev_ethtool_ops = {
        .set_msglevel           = netdev_set_msglevel,
        .get_sg                 = ethtool_op_get_sg,
        .get_tx_csum            = ethtool_op_get_tx_csum,
+       .begin                  = ethtool_begin,
+       .complete               = ethtool_complete
 };
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct epic_private *np = dev->priv;
        long ioaddr = dev->base_addr;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+       struct mii_ioctl_data *data = if_mii(rq);
        int rc;
 
        /* power-up, if interface is down */
index 0ee18be..9ab7274 100644 (file)
@@ -255,14 +255,14 @@ static int eql_close(struct net_device *dev)
        return 0;
 }
 
-static int eql_enslave(struct net_device *dev,  slaving_request_t *srq);
-static int eql_emancipate(struct net_device *dev, slaving_request_t *srq);
+static int eql_enslave(struct net_device *dev,  slaving_request_t __user *srq);
+static int eql_emancipate(struct net_device *dev, slaving_request_t __user *srq);
 
-static int eql_g_slave_cfg(struct net_device *dev, slave_config_t *sc);
-static int eql_s_slave_cfg(struct net_device *dev, slave_config_t *sc);
+static int eql_g_slave_cfg(struct net_device *dev, slave_config_t __user *sc);
+static int eql_s_slave_cfg(struct net_device *dev, slave_config_t __user *sc);
 
-static int eql_g_master_cfg(struct net_device *dev, master_config_t *mc);
-static int eql_s_master_cfg(struct net_device *dev, master_config_t *mc);
+static int eql_g_master_cfg(struct net_device *dev, master_config_t __user *mc);
+static int eql_s_master_cfg(struct net_device *dev, master_config_t __user *mc);
 
 static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {  
@@ -272,23 +272,17 @@ static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
        switch (cmd) {
                case EQL_ENSLAVE:
-                       return eql_enslave(dev,
-                                          (slaving_request_t *) ifr->ifr_data);
+                       return eql_enslave(dev, ifr->ifr_data);
                case EQL_EMANCIPATE:
-                       return eql_emancipate(dev,
-                                             (slaving_request_t *) ifr->ifr_data);
+                       return eql_emancipate(dev, ifr->ifr_data);
                case EQL_GETSLAVECFG:
-                       return eql_g_slave_cfg(dev,
-                                              (slave_config_t *) ifr->ifr_data);
+                       return eql_g_slave_cfg(dev, ifr->ifr_data);
                case EQL_SETSLAVECFG:
-                       return eql_s_slave_cfg(dev,
-                                              (slave_config_t *) ifr->ifr_data);
+                       return eql_s_slave_cfg(dev, ifr->ifr_data);
                case EQL_GETMASTRCFG:
-                       return eql_g_master_cfg(dev,
-                                               (master_config_t *) ifr->ifr_data);
+                       return eql_g_master_cfg(dev, ifr->ifr_data);
                case EQL_SETMASTRCFG:
-                       return eql_s_master_cfg(dev,
-                                               (master_config_t *) ifr->ifr_data);
+                       return eql_s_master_cfg(dev, ifr->ifr_data);
                default:
                        return -EOPNOTSUPP;
        };
@@ -411,7 +405,7 @@ static int __eql_insert_slave(slave_queue_t *queue, slave_t *slave)
        return -ENOSPC;
 }
 
-static int eql_enslave(struct net_device *master_dev, slaving_request_t *srqp)
+static int eql_enslave(struct net_device *master_dev, slaving_request_t __user *srqp)
 {
        struct net_device *slave_dev;
        slaving_request_t srq;
@@ -457,7 +451,7 @@ static int eql_enslave(struct net_device *master_dev, slaving_request_t *srqp)
        return -EINVAL;
 }
 
-static int eql_emancipate(struct net_device *master_dev, slaving_request_t *srqp)
+static int eql_emancipate(struct net_device *master_dev, slaving_request_t __user *srqp)
 {
        equalizer_t *eql = master_dev->priv;
        struct net_device *slave_dev;
@@ -489,7 +483,7 @@ static int eql_emancipate(struct net_device *master_dev, slaving_request_t *srqp
        return ret;
 }
 
-static int eql_g_slave_cfg(struct net_device *dev, slave_config_t *scp)
+static int eql_g_slave_cfg(struct net_device *dev, slave_config_t __user *scp)
 {
        equalizer_t *eql = dev->priv;
        slave_t *slave;
@@ -501,6 +495,8 @@ static int eql_g_slave_cfg(struct net_device *dev, slave_config_t *scp)
                return -EFAULT;
 
        slave_dev = dev_get_by_name(sc.slave_name);
+       if (!slave_dev)
+               return -ENODEV;
 
        ret = -EINVAL;
 
@@ -522,7 +518,7 @@ static int eql_g_slave_cfg(struct net_device *dev, slave_config_t *scp)
        return ret;
 }
 
-static int eql_s_slave_cfg(struct net_device *dev, slave_config_t *scp)
+static int eql_s_slave_cfg(struct net_device *dev, slave_config_t __user *scp)
 {
        slave_t *slave;
        equalizer_t *eql;
@@ -533,11 +529,13 @@ static int eql_s_slave_cfg(struct net_device *dev, slave_config_t *scp)
        if (copy_from_user(&sc, scp, sizeof (slave_config_t)))
                return -EFAULT;
 
-       eql = dev->priv;
        slave_dev = dev_get_by_name(sc.slave_name);
+       if (!slave_dev)
+               return -ENODEV;
 
        ret = -EINVAL;
 
+       eql = dev->priv;
        spin_lock_bh(&eql->queue.lock);
        if (eql_is_slave(slave_dev)) {
                slave = __eql_find_slave_dev(&eql->queue, slave_dev);
@@ -553,7 +551,7 @@ static int eql_s_slave_cfg(struct net_device *dev, slave_config_t *scp)
        return ret;
 }
 
-static int eql_g_master_cfg(struct net_device *dev, master_config_t *mcp)
+static int eql_g_master_cfg(struct net_device *dev, master_config_t __user *mcp)
 {
        equalizer_t *eql;
        master_config_t mc;
@@ -569,7 +567,7 @@ static int eql_g_master_cfg(struct net_device *dev, master_config_t *mcp)
        return -EINVAL;
 }
 
-static int eql_s_master_cfg(struct net_device *dev, master_config_t *mcp)
+static int eql_s_master_cfg(struct net_device *dev, master_config_t __user *mcp)
 {
        equalizer_t *eql;
        master_config_t mc;
index ca21905..50d8aad 100644 (file)
@@ -161,6 +161,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr, ES_IO_EXTENT);
 }
 
+#ifndef MODULE
 struct net_device * __init es_probe(int unit)
 {
        struct net_device *dev = alloc_ei_netdev();
@@ -185,6 +186,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init es_probe1(struct net_device *dev, int ioaddr)
 {
index 88b441f..5a9ae26 100644 (file)
@@ -458,6 +458,7 @@ static int __init do_eth16i_probe(struct net_device *dev)
        return -ENODEV;
 }
 
+#ifndef MODULE
 struct net_device * __init eth16i_probe(int unit)
 {
        struct net_device *dev = alloc_etherdev(sizeof(struct eth16i_local));
@@ -483,6 +484,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
 {
@@ -491,7 +493,7 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
        int retval;
 
        /* Let's grab the region */
-       if (!request_region(ioaddr, ETH16I_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, ETH16I_IO_EXTENT, cardname))
                return -EBUSY;
 
        /*
@@ -538,9 +540,9 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
 
        /* Try to obtain interrupt vector */
 
-       if ((retval = request_irq(dev->irq, (void *)&eth16i_interrupt, 0, dev->name, dev))) {
-               printk(KERN_WARNING "%s: %s at %#3x, but is unusable due conflicting IRQ %d.\n", 
-                      dev->name, cardname, ioaddr, dev->irq);
+       if ((retval = request_irq(dev->irq, (void *)&eth16i_interrupt, 0, cardname, dev))) {
+               printk(KERN_WARNING "%s at %#3x, but is unusable due to conflicting IRQ %d.\n", 
+                      cardname, ioaddr, dev->irq);
                goto out;
        }
 
index 3bf2273..d896baa 100644 (file)
@@ -341,6 +341,7 @@ static int num_ewrks3s;
     mdelay(1);\
 }
 
+#ifndef MODULE
 struct net_device * __init ewrk3_probe(int unit)
 {
        struct net_device *dev = alloc_etherdev(sizeof(struct ewrk3_private));
@@ -364,6 +365,7 @@ out:
        return ERR_PTR(err);
        
 }
+#endif
 
 static int __init ewrk3_probe1(struct net_device *dev, u_long iobase, int irq)
 {
@@ -1269,7 +1271,7 @@ static int __init isa_probe(struct net_device *dev, u_long ioaddr)
        for (; (i < maxSlots) && (dev != NULL);
             iobase += EWRK3_IOP_INC, i++)
        {
-               if (request_region(iobase, EWRK3_TOTAL_SIZE, dev->name)) {
+               if (request_region(iobase, EWRK3_TOTAL_SIZE, DRV_NAME)) {
                        if (DevicePresent(iobase) == 0) {
                                int irq = dev->irq;
                                ret = ewrk3_hw_init(dev, iobase);
@@ -1310,7 +1312,7 @@ static int __init eisa_probe(struct net_device *dev, u_long ioaddr)
 
        for (i = 1; (i < maxSlots) && (dev != NULL); i++, iobase += EISA_SLOT_INC) {
                if (EISA_signature(name, EISA_ID) == 0) {
-                       if (request_region(iobase, EWRK3_TOTAL_SIZE, dev->name) &&
+                       if (request_region(iobase, EWRK3_TOTAL_SIZE, DRV_NAME) &&
                            DevicePresent(iobase) == 0) {
                                int irq = dev->irq;
                                ret = ewrk3_hw_init(dev, iobase);
@@ -1518,13 +1520,13 @@ static int __init EISA_signature(char *name, s32 eisa_id)
        return status;          /* return the device name string */
 }
 
-static int ewrk3_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int ewrk3_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
        struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv;
        u_long iobase = dev->base_addr;
        u32 ethcmd;
 
-       if (get_user(ethcmd, (u32 *)useraddr))
+       if (get_user(ethcmd, (u32 __user *)useraddr))
                return -EFAULT;
 
        switch (ethcmd) {
@@ -1707,7 +1709,7 @@ static int ewrk3_ethtool_ioctl(struct net_device *dev, void *useraddr)
 static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv;
-       struct ewrk3_ioctl *ioc = (struct ewrk3_ioctl *) &rq->ifr_data;
+       struct ewrk3_ioctl *ioc = (struct ewrk3_ioctl *) &rq->ifr_ifru;
        u_long iobase = dev->base_addr;
        int i, j, status = 0;
        u_char csr;
@@ -1721,7 +1723,7 @@ static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
        /* ethtool IOCTLs are handled elsewhere */
        if (cmd == SIOCETHTOOL)
-               return ewrk3_ethtool_ioctl(dev, (void *)rq->ifr_data);
+               return ewrk3_ethtool_ioctl(dev, rq->ifr_data);
 
        /* Other than ethtool, all we handle are private IOCTLs */
        if (cmd != EWRK3IOCTL)
index 46ec009..fb74bd0 100644 (file)
 struct ewrk3_ioctl {
        unsigned short cmd;                /* Command to run */
        unsigned short len;                /* Length of the data buffer */
-       unsigned char  *data;              /* Pointer to the data buffer */
+       unsigned char  __user *data;       /* Pointer to the data buffer */
 };
 
 /* 
index ec3fff4..a5e12b2 100644 (file)
@@ -52,7 +52,7 @@ static const char *version =
                               others + includes if_fcdevice.h */
 
 #include "../../scsi/scsi.h"
-#include "../../scsi/hosts.h"
+#include <scsi/scsi_host.h>
 #include "../../fc4/fcp.h"
 
 #include <asm/system.h>
index b81777d..9112ca0 100644 (file)
@@ -858,12 +858,17 @@ static int netdev_open(struct net_device *dev)
 {
        struct netdev_private *np = dev->priv;
        long ioaddr = dev->base_addr;
+       int i;
 
        writel(0x00000001, ioaddr + BCR);       /* Reset */
 
        if (request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev))
                return -EAGAIN;
 
+       for (i = 0; i < 3; i++)
+               writew(((unsigned short*)dev->dev_addr)[i],
+                               ioaddr + PAR0 + i*2);
+
        init_ring(dev);
 
        writel(np->rx_ring_dma, ioaddr + RXLBA);
@@ -1923,14 +1928,13 @@ static struct ethtool_ops netdev_ethtool_ops = {
 static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct netdev_private *np = dev->priv;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
        int rc;
 
        if (!netif_running(dev))
                return -EINVAL;
 
        spin_lock_irq(&np->lock);
-       rc = generic_mii_ioctl(&np->mii, data, cmd, NULL);
+       rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
        spin_unlock_irq(&np->lock);
 
        return rc;
index 8bfb50f..f0b6f9c 100644 (file)
@@ -57,6 +57,8 @@ static const char version[] =
 #include <asm/io.h>
 #include <asm/dma.h>
 
+#define DRV_NAME "fmv18x"
+
 static unsigned fmv18x_probe_list[] __initdata = {
        0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0
 };
@@ -192,7 +194,7 @@ static int __init fmv18x_probe1(struct net_device *dev, short ioaddr)
           That means we have to be careful with the register values we probe for.
           */
 
-       if (!request_region(ioaddr, FMV18X_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, FMV18X_IO_EXTENT, DRV_NAME))
                return -EBUSY;
 
        dev->irq = irq;
@@ -224,7 +226,7 @@ static int __init fmv18x_probe1(struct net_device *dev, short ioaddr)
        }
 
        /* Snarf the interrupt vector now. */
-       retval = request_irq(dev->irq, &net_interrupt, 0, dev->name, dev);
+       retval = request_irq(dev->irq, &net_interrupt, 0, DRV_NAME, dev);
        if (retval) {
                printk ("FMV-18x found at %#3x, but it's unusable due to a conflict on"
                                "IRQ %d.\n", ioaddr, dev->irq);
index 73dcb68..a3518e2 100644 (file)
@@ -81,6 +81,7 @@
  * superfluous timer interrupts from the nic.
  */
 #define FORCEDETH_VERSION              "0.25"
+#define DRV_NAME                       "forcedeth"
 
 #include <linux/module.h>
 #include <linux/types.h>
@@ -556,7 +557,7 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
        return &np->stats;
 }
 
-static int nv_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int nv_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
        struct fe_priv *np = get_nvpriv(dev);
        u8 *base = get_hwbase(dev);
@@ -634,7 +635,7 @@ static int nv_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        switch(cmd) {
        case SIOCETHTOOL:
-               return nv_ethtool_ioctl(dev, (void *) rq->ifr_data);
+               return nv_ethtool_ioctl(dev, rq->ifr_data);
 
        default:
                return -EOPNOTSUPP;
@@ -1424,7 +1425,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
 
        pci_set_master(pci_dev);
 
-       err = pci_request_regions(pci_dev, dev->name);
+       err = pci_request_regions(pci_dev, DRV_NAME);
        if (err < 0)
                goto out_disable;
 
index 2089b1a..f1ec806 100644 (file)
@@ -1869,7 +1869,7 @@ static void set_rx_mode(struct net_device *dev)
        }
 }
 
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
        struct hamachi_private *np = dev->priv;
        u32 ethcmd;
@@ -1937,17 +1937,17 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct hamachi_private *np = dev->priv;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
+       struct mii_ioctl_data *data = if_mii(rq);
        int rc;
 
        if (!netif_running(dev))
                return -EINVAL;
 
        if (cmd == SIOCETHTOOL)
-               rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+               rc = netdev_ethtool_ioctl(dev, rq->ifr_data);
 
        else if (cmd == (SIOCDEVPRIVATE+3)) { /* set rx,tx intr params */
-               u32 *d = (u32 *)&rq->ifr_data;
+               u32 *d = (u32 *)&rq->ifr_ifru;
                /* Should add this check here or an ordinary user can do nasty
                 * things. -KDU
                 *
index d5b7fd9..d5b7db1 100644 (file)
@@ -1166,8 +1166,6 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        bc = netdev_priv(dev);
        if (cmd != SIOCDEVPRIVATE)
                return -ENOIOCTLCMD;
-       if (get_user(cmd, (int *)ifr->ifr_data))
-               return -EFAULT;
 
        if (copy_from_user(&hi, ifr->ifr_data, sizeof(hi)))
                return -EFAULT;
index 28e9da3..4bd7c09 100644 (file)
@@ -414,7 +414,6 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
 {
        struct baycom_state *bc;
        struct baycom_ioctl bi;
-       int cmd2;
 
        if (!dev || !dev->priv ||
            ((struct baycom_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
@@ -425,8 +424,6 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
 
        if (cmd != SIOCDEVPRIVATE)
                return -ENOIOCTLCMD;
-       if (get_user(cmd2, (int *)ifr->ifr_data))
-               return -EFAULT;
        switch (hi->cmd) {
        default:
                break;
index 2dc64f0..5c6257e 100644 (file)
@@ -529,7 +529,6 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
 {
        struct baycom_state *bc;
        struct baycom_ioctl bi;
-       int cmd2;
 
        if (!dev || !dev->priv ||
            ((struct baycom_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
@@ -540,8 +539,6 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
 
        if (cmd != SIOCDEVPRIVATE)
                return -ENOIOCTLCMD;
-       if (get_user(cmd2, (int *)ifr->ifr_data))
-               return -EFAULT;
        switch (hi->cmd) {
        default:
                break;
index f288c92..4aef970 100644 (file)
@@ -569,7 +569,6 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
 {
        struct baycom_state *bc;
        struct baycom_ioctl bi;
-       int cmd2;
 
        if (!dev || !dev->priv ||
            ((struct baycom_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
@@ -580,8 +579,6 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
 
        if (cmd != SIOCDEVPRIVATE)
                return -ENOIOCTLCMD;
-       if (get_user(cmd2, (int *)ifr->ifr_data))
-               return -EFAULT;
        switch (hi->cmd) {
        default:
                break;
index fda1872..6b85ab3 100644 (file)
@@ -331,7 +331,7 @@ static int bpq_set_mac_address(struct net_device *dev, void *addr)
  */
 static int bpq_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-       struct bpq_ethaddr *ethaddr = (struct bpq_ethaddr *)ifr->ifr_data;
+       struct bpq_ethaddr __user *ethaddr = ifr->ifr_data;
        struct bpqdev *bpq = dev->priv;
        struct bpq_req req;
 
index 0e6844f..f7fc3b9 100644 (file)
@@ -1714,13 +1714,11 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        struct scc_mem_config memcfg;
        struct scc_hw_config hwcfg;
        struct scc_calibrate cal;
-       struct scc_channel *scc;
+       struct scc_channel *scc = (struct scc_channel *) dev->priv;
        int chan;
        unsigned char device_name[IFNAMSIZ];
-       void *arg;
+       void __user *arg = ifr->ifr_data;
        
-       scc = (struct scc_channel *) dev->priv;
-       arg = (void *) ifr->ifr_data;
        
        if (!Driver_Initialized)
        {
index 0e60de8..70b58d2 100644 (file)
@@ -37,6 +37,8 @@ static const char version[] =
 
 #include "8390.h"
 
+#define DRV_NAME "hp-plus"
+
 /* A zero-terminated list of I/O addresses to be probed. */
 static unsigned int hpplus_portlist[] __initdata =
 {0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
@@ -142,6 +144,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
 }
 
+#ifndef MODULE
 struct net_device * __init hp_plus_probe(int unit)
 {
        struct net_device *dev = alloc_ei_netdev();
@@ -166,6 +169,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 /* Do the interesting part of the probe at a single address. */
 static int __init hpp_probe1(struct net_device *dev, int ioaddr)
@@ -176,7 +180,7 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr)
        int mem_start;
        static unsigned version_printed;
 
-       if (!request_region(ioaddr, HP_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME))
                return -EBUSY;
 
        /* Check for the HP+ signature, 50 48 0x 53. */
index 2f48a7f..00358a9 100644 (file)
@@ -37,6 +37,8 @@ static const char version[] =
 
 #include "8390.h"
 
+#define DRV_NAME "hp"
+
 /* A zero-terminated list of I/O addresses to be probed. */
 static unsigned int hppclan_portlist[] __initdata =
 { 0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240, 0};
@@ -106,6 +108,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
 }
 
+#ifndef MODULE
 struct net_device * __init hp_probe(int unit)
 {
        struct net_device *dev = alloc_ei_netdev();
@@ -130,6 +133,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init hp_probe1(struct net_device *dev, int ioaddr)
 {
@@ -137,7 +141,7 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
        const char *name;
        static unsigned version_printed;
 
-       if (!request_region(ioaddr, HP_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME))
                return -EBUSY;
 
        /* Check for the HP physical address, 08 00 09 xx xx xx. */
@@ -182,7 +186,7 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
                                outb_p(irqmap[irq] | HP_RUN, ioaddr + HP_CONFIGURE);
                                outb_p( 0x00 | HP_RUN, ioaddr + HP_CONFIGURE);
                                if (irq == probe_irq_off(cookie)                 /* It's a good IRQ line! */
-                                       && request_irq (irq, ei_interrupt, 0, dev->name, dev) == 0) {
+                                       && request_irq (irq, ei_interrupt, 0, DRV_NAME, dev) == 0) {
                                        printk(" selecting IRQ %d.\n", irq);
                                        dev->irq = *irqp;
                                        break;
@@ -197,7 +201,7 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
        } else {
                if (dev->irq == 2)
                        dev->irq = 9;
-               if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) {
+               if ((retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev))) {
                        printk (" unable to get IRQ %d.\n", dev->irq);
                        goto out;
                }
index a845c11..78ae4b2 100644 (file)
@@ -386,6 +386,7 @@ static int  __init hp100_isa_probe(struct net_device *dev, int addr)
 }
 
 
+#ifndef MODULE
 struct net_device * __init hp100_probe(int unit)
 {
        struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
@@ -420,6 +421,7 @@ struct net_device * __init hp100_probe(int unit)
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init hp100_probe1(struct net_device *dev, int ioaddr,
                               u_char bus, struct pci_dev *pci_dev)
index 0bc7f82..2ca3de0 100644 (file)
@@ -1556,7 +1556,7 @@ static struct ethtool_ops emac_ethtool_ops = {
 static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct ocp_enet_private *fep = dev->priv;
-       uint *data = (uint *) & rq->ifr_data;
+       uint *data = (uint *) & rq->ifr_ifru;
 
        switch (cmd) {
        case SIOCGMIIPHY:
index a0eaa80..0aa0a82 100644 (file)
@@ -98,6 +98,8 @@ History:
 
 #undef DEBUG
 
+#define DRV_NAME "ibmlana"
+
 /* ------------------------------------------------------------------------
  * global static data - not more since we can handle multiple boards and
  * have to pack all state info into the device struct!
@@ -952,8 +954,8 @@ static int ibmlana_probe(struct net_device *dev)
        printk(KERN_INFO "%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1);
 
        /* try to obtain I/O range */
-       if (!request_region(iobase, IBM_LANA_IORANGE, dev->name)) {
-               printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", dev->name, iobase);
+       if (!request_region(iobase, IBM_LANA_IORANGE, DRV_NAME)) {
+               printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", DRV_NAME, iobase);
                startslot = slot + 1;
                return -EBUSY;
        }
index 4e4e876..5fa162f 100644 (file)
@@ -901,7 +901,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
 
        adapter = netdev->priv;
        memset(adapter, 0, sizeof(adapter));
-       dev->driver_data = netdev;
+       dev->dev.driver_data = netdev;
 
        adapter->vdev = dev;
        adapter->netdev = netdev;
@@ -971,7 +971,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
 
 static int __devexit ibmveth_remove(struct vio_dev *dev)
 {
-       struct net_device *netdev = dev->driver_data;
+       struct net_device *netdev = dev->dev.driver_data;
        struct ibmveth_adapter *adapter = netdev->priv;
 
        unregister_netdev(netdev);
index 654fd69..a93cda6 100644 (file)
@@ -1529,12 +1529,11 @@ static struct ethtool_ops ioc3_ethtool_ops = {
 
 static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
        struct ioc3_private *ip = netdev_priv(dev);
        int rc;
 
        spin_lock_irq(&ip->ioc3_lock);
-       rc = generic_mii_ioctl(&ip->mii, data, cmd, NULL);
+       rc = generic_mii_ioctl(&ip->mii, if_mii(rq), cmd, NULL);
        spin_unlock_irq(&ip->ioc3_lock);
 
        return rc;
index ad4ab63..6a10d96 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/serial_reg.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -304,16 +305,18 @@ static int ali_ircc_open(int i, chipio_t *info)
        self->tx_buff.truesize = 14384;
 
        /* Allocate memory if needed */
-       self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
-                                             GFP_KERNEL |GFP_DMA); 
+       self->rx_buff.head =
+               dma_alloc_coherent(NULL, self->rx_buff.truesize,
+                                  &self->rx_buff_dma, GFP_KERNEL);
        if (self->rx_buff.head == NULL) {
                err = -ENOMEM;
                goto err_out2;
        }
        memset(self->rx_buff.head, 0, self->rx_buff.truesize);
        
-       self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
-                                             GFP_KERNEL|GFP_DMA); 
+       self->tx_buff.head =
+               dma_alloc_coherent(NULL, self->tx_buff.truesize,
+                                  &self->tx_buff_dma, GFP_KERNEL);
        if (self->tx_buff.head == NULL) {
                err = -ENOMEM;
                goto err_out3;
@@ -362,9 +365,11 @@ static int ali_ircc_open(int i, chipio_t *info)
        return 0;
 
  err_out4:
-       kfree(self->tx_buff.head);
+       dma_free_coherent(NULL, self->tx_buff.truesize,
+                         self->tx_buff.head, self->tx_buff_dma);
  err_out3:
-       kfree(self->rx_buff.head);
+       dma_free_coherent(NULL, self->rx_buff.truesize,
+                         self->rx_buff.head, self->rx_buff_dma);
  err_out2:
        release_region(self->io.fir_base, self->io.fir_ext);
  err_out1:
@@ -398,10 +403,12 @@ static int __exit ali_ircc_close(struct ali_ircc_cb *self)
        release_region(self->io.fir_base, self->io.fir_ext);
 
        if (self->tx_buff.head)
-               kfree(self->tx_buff.head);
+               dma_free_coherent(NULL, self->tx_buff.truesize,
+                                 self->tx_buff.head, self->tx_buff_dma);
        
        if (self->rx_buff.head)
-               kfree(self->rx_buff.head);
+               dma_free_coherent(NULL, self->rx_buff.truesize,
+                                 self->rx_buff.head, self->rx_buff_dma);
 
        dev_self[self->index] = NULL;
        free_netdev(self->netdev);
@@ -1572,7 +1579,8 @@ static void ali_ircc_dma_xmit(struct ali_ircc_cb *self)
        self->io.direction = IO_XMIT;
        
        irda_setup_dma(self->io.dma, 
-                      self->tx_fifo.queue[self->tx_fifo.ptr].start, 
+                      ((u8 *)self->tx_fifo.queue[self->tx_fifo.ptr].start -
+                       self->tx_buff.head) + self->tx_buff_dma,
                       self->tx_fifo.queue[self->tx_fifo.ptr].len, 
                       DMA_TX_MODE);
                
@@ -1724,8 +1732,8 @@ static int ali_ircc_dma_receive(struct ali_ircc_cb *self)
        self->st_fifo.len = self->st_fifo.pending_bytes = 0;
        self->st_fifo.tail = self->st_fifo.head = 0;
                
-       irda_setup_dma(self->io.dma, self->rx_buff.data, 
-                      self->rx_buff.truesize, DMA_RX_MODE);    
+       irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize,
+                      DMA_RX_MODE);
         
        /* Set Receive Mode,Brick Wall */
        //switch_bank(iobase, BANK0);
index dc5edd1..e489c66 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/pm.h>
+#include <linux/types.h>
 #include <asm/io.h>
 
 /* SIR Register */
@@ -198,6 +199,8 @@ struct ali_ircc_cb {
        chipio_t io;               /* IrDA controller information */
        iobuff_t tx_buff;          /* Transmit buffer */
        iobuff_t rx_buff;          /* Receive buffer */
+       dma_addr_t tx_buff_dma;
+       dma_addr_t rx_buff_dma;
 
        __u8 ier;                  /* Interrupt enable register */
        
index 035da95..b924ff1 100644 (file)
@@ -438,7 +438,6 @@ static int irtty_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
        struct irtty_info { char name[6]; } info;
        struct sir_dev *dev;
        struct sirtty_cb *priv = tty->disc_data;
-       int size = _IOC_SIZE(cmd);
        int err = 0;
 
        ASSERT(priv != NULL, return -ENODEV;);
@@ -449,13 +448,6 @@ static int irtty_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
        dev = priv->dev;
        ASSERT(dev != NULL, return -1;);
 
-       if (_IOC_DIR(cmd) & _IOC_READ)
-               err = verify_area(VERIFY_WRITE, (void *) arg, size);
-       else if (_IOC_DIR(cmd) & _IOC_WRITE)
-               err = verify_area(VERIFY_READ, (void *) arg, size);
-       if (err)
-               return err;
-       
        switch (cmd) {
        case TCGETS:
        case TCGETA:
@@ -473,7 +465,7 @@ static int irtty_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
                memset(&info, 0, sizeof(info)); 
                strncpy(info.name, dev->netdev->name, sizeof(info.name)-1);
 
-               if (copy_to_user((void *)arg, &info, sizeof(info)))
+               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
                        err = -EFAULT;
                break;
        default:
index 2248e66..c1e79f5 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -307,8 +308,9 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
        self->tx_buff.truesize = 14384;
 
        /* Allocate memory if needed */
-       self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
-                                             GFP_KERNEL|GFP_DMA);
+       self->rx_buff.head =
+               dma_alloc_coherent(NULL, self->rx_buff.truesize,
+                                  &self->rx_buff_dma, GFP_KERNEL);
        if (self->rx_buff.head == NULL) {
                err = -ENOMEM;
                goto out2;
@@ -316,8 +318,9 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
        }
        memset(self->rx_buff.head, 0, self->rx_buff.truesize);
        
-       self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
-                                             GFP_KERNEL|GFP_DMA);
+       self->tx_buff.head =
+               dma_alloc_coherent(NULL, self->tx_buff.truesize,
+                                  &self->tx_buff_dma, GFP_KERNEL);
        if (self->tx_buff.head == NULL) {
                err = -ENOMEM;
                goto out3;
@@ -368,9 +371,11 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
 
        return 0;
  out4:
-       kfree(self->tx_buff.head);
+       dma_free_coherent(NULL, self->tx_buff.truesize,
+                         self->tx_buff.head, self->tx_buff_dma);
  out3:
-       kfree(self->rx_buff.head);
+       dma_free_coherent(NULL, self->rx_buff.truesize,
+                         self->rx_buff.head, self->rx_buff_dma);
  out2:
        release_region(self->io.fir_base, self->io.fir_ext);
  out1:
@@ -404,10 +409,12 @@ static int __exit nsc_ircc_close(struct nsc_ircc_cb *self)
        release_region(self->io.fir_base, self->io.fir_ext);
 
        if (self->tx_buff.head)
-               kfree(self->tx_buff.head);
+               dma_free_coherent(NULL, self->tx_buff.truesize,
+                                 self->tx_buff.head, self->tx_buff_dma);
        
        if (self->rx_buff.head)
-               kfree(self->rx_buff.head);
+               dma_free_coherent(NULL, self->rx_buff.truesize,
+                                 self->rx_buff.head, self->rx_buff_dma);
 
        dev_self[self->index] = NULL;
        free_netdev(self->netdev);
@@ -1409,7 +1416,8 @@ static void nsc_ircc_dma_xmit(struct nsc_ircc_cb *self, int iobase)
        outb(ECR1_DMASWP|ECR1_DMANF|ECR1_EXT_SL, iobase+ECR1);
        
        irda_setup_dma(self->io.dma, 
-                      self->tx_fifo.queue[self->tx_fifo.ptr].start, 
+                      ((u8 *)self->tx_fifo.queue[self->tx_fifo.ptr].start -
+                       self->tx_buff.head) + self->tx_buff_dma,
                       self->tx_fifo.queue[self->tx_fifo.ptr].len, 
                       DMA_TX_MODE);
 
@@ -1566,8 +1574,8 @@ static int nsc_ircc_dma_receive(struct nsc_ircc_cb *self)
        self->st_fifo.len = self->st_fifo.pending_bytes = 0;
        self->st_fifo.tail = self->st_fifo.head = 0;
        
-       irda_setup_dma(self->io.dma, self->rx_buff.data, 
-                      self->rx_buff.truesize, DMA_RX_MODE);
+       irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize,
+                      DMA_RX_MODE);
 
        /* Enable DMA */
        switch_bank(iobase, BANK0);
index 0f541aa..6edf7e5 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/pm.h>
+#include <linux/types.h>
 #include <asm/io.h>
 
 /* DMA modes needed */
@@ -255,6 +256,8 @@ struct nsc_ircc_cb {
        chipio_t io;               /* IrDA controller information */
        iobuff_t tx_buff;          /* Transmit buffer */
        iobuff_t rx_buff;          /* Receive buffer */
+       dma_addr_t tx_buff_dma;
+       dma_addr_t rx_buff_dma;
 
        __u8 ier;                  /* Interrupt enable register */
 
index e360323..fc3580a 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/serial_reg.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -112,6 +113,8 @@ struct smsc_ircc_cb {
        chipio_t io;               /* IrDA controller information */
        iobuff_t tx_buff;          /* Transmit buffer */
        iobuff_t rx_buff;          /* Receive buffer */
+       dma_addr_t tx_buff_dma;
+       dma_addr_t rx_buff_dma;
 
        struct qos_info qos;       /* QoS capabilities for this device */
 
@@ -413,16 +416,18 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u
        self->rx_buff.truesize = SMSC_IRCC2_RX_BUFF_TRUESIZE; 
        self->tx_buff.truesize = SMSC_IRCC2_TX_BUFF_TRUESIZE;
 
-       self->rx_buff.head = (u8 *) kmalloc(self->rx_buff.truesize,
-                                             GFP_KERNEL|GFP_DMA);
+       self->rx_buff.head =
+               dma_alloc_coherent(NULL, self->rx_buff.truesize,
+                                  &self->rx_buff_dma, GFP_KERNEL);
        if (self->rx_buff.head == NULL) {
                ERROR("%s, Can't allocate memory for receive buffer!\n",
                       driver_name);
                goto err_out2;
        }
 
-       self->tx_buff.head = (u8 *) kmalloc(self->tx_buff.truesize, 
-                                             GFP_KERNEL|GFP_DMA);
+       self->tx_buff.head =
+               dma_alloc_coherent(NULL, self->tx_buff.truesize,
+                                  &self->tx_buff_dma, GFP_KERNEL);
        if (self->tx_buff.head == NULL) {
                ERROR("%s, Can't allocate memory for transmit buffer!\n",
                       driver_name);
@@ -464,9 +469,11 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u
 
        return 0;
  err_out4:
-       kfree(self->tx_buff.head);
+       dma_free_coherent(NULL, self->tx_buff.truesize,
+                         self->tx_buff.head, self->tx_buff_dma);
  err_out3:
-       kfree(self->rx_buff.head);
+       dma_free_coherent(NULL, self->rx_buff.truesize,
+                         self->rx_buff.head, self->rx_buff_dma);
  err_out2:
        free_netdev(self->netdev);
        dev_self[--dev_count] = NULL;
@@ -1159,7 +1166,7 @@ static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int iobase, int bofs)
             IRCC_CFGB_DMA_BURST, iobase+IRCC_SCE_CFGB);
 
        /* Setup DMA controller (must be done after enabling chip DMA) */
-       irda_setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, 
+       irda_setup_dma(self->io.dma, self->tx_buff_dma, self->tx_buff.len,
                       DMA_TX_MODE);
 
        /* Enable interrupt */
@@ -1249,8 +1256,8 @@ static int smsc_ircc_dma_receive(struct smsc_ircc_cb *self, int iobase)
        outb(2050 & 0xff, iobase+IRCC_RX_SIZE_LO);
 
        /* Setup DMA controller */
-       irda_setup_dma(self->io.dma, self->rx_buff.data,
-                      self->rx_buff.truesize, DMA_RX_MODE);
+       irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize,
+                      DMA_RX_MODE);
 
        /* Enable burst mode chip Rx DMA */
        register_bank(iobase, 1);
@@ -1717,10 +1724,12 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self)
        release_region(self->io.sir_base, self->io.sir_ext);
 
        if (self->tx_buff.head)
-               kfree(self->tx_buff.head);
+               dma_free_coherent(NULL, self->tx_buff.truesize,
+                                 self->tx_buff.head, self->tx_buff_dma);
        
        if (self->rx_buff.head)
-               kfree(self->rx_buff.head);
+               dma_free_coherent(NULL, self->rx_buff.truesize,
+                                 self->rx_buff.head, self->rx_buff_dma);
 
        free_netdev(self->netdev);
 
index 95b9c32..4d1000e 100644 (file)
@@ -39,6 +39,7 @@ F02 Oct/28/02: Add SB device ID for 3147 and 3177.
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -383,7 +384,8 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
 
        /* Allocate memory if needed */
        self->rx_buff.head =
-           (__u8 *) kmalloc(self->rx_buff.truesize, GFP_KERNEL | GFP_DMA);
+               dma_alloc_coherent(NULL, self->rx_buff.truesize,
+                                  &self->rx_buff_dma, GFP_KERNEL);
        if (self->rx_buff.head == NULL) {
                err = -ENOMEM;
                goto err_out2;
@@ -391,7 +393,8 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
        memset(self->rx_buff.head, 0, self->rx_buff.truesize);
 
        self->tx_buff.head =
-           (__u8 *) kmalloc(self->tx_buff.truesize, GFP_KERNEL | GFP_DMA);
+               dma_alloc_coherent(NULL, self->tx_buff.truesize,
+                                  &self->tx_buff_dma, GFP_KERNEL);
        if (self->tx_buff.head == NULL) {
                err = -ENOMEM;
                goto err_out3;
@@ -432,9 +435,11 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
 
        return 0;
  err_out4:
-       kfree(self->tx_buff.head);
+       dma_free_coherent(NULL, self->tx_buff.truesize,
+                         self->tx_buff.head, self->tx_buff_dma);
  err_out3:
-       kfree(self->rx_buff.head);
+       dma_free_coherent(NULL, self->rx_buff.truesize,
+                         self->rx_buff.head, self->rx_buff_dma);
  err_out2:
        release_region(self->io.fir_base, self->io.fir_ext);
  err_out1:
@@ -468,9 +473,11 @@ static int __exit via_ircc_close(struct via_ircc_cb *self)
                   __FUNCTION__, self->io.fir_base);
        release_region(self->io.fir_base, self->io.fir_ext);
        if (self->tx_buff.head)
-               kfree(self->tx_buff.head);
+               dma_free_coherent(NULL, self->tx_buff.truesize,
+                                 self->tx_buff.head, self->tx_buff_dma);
        if (self->rx_buff.head)
-               kfree(self->rx_buff.head);
+               dma_free_coherent(NULL, self->rx_buff.truesize,
+                                 self->rx_buff.head, self->rx_buff_dma);
        dev_self[self->index] = NULL;
 
        free_netdev(self->netdev);
@@ -816,7 +823,7 @@ static int via_ircc_hard_xmit_sir(struct sk_buff *skb,
        EnTXDMA(iobase, ON);
        EnRXDMA(iobase, OFF);
 
-       irda_setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len,
+       irda_setup_dma(self->io.dma, self->tx_buff_dma, self->tx_buff.len,
                       DMA_TX_MODE);
 
        SetSendByte(iobase, self->tx_buff.len);
@@ -897,7 +904,8 @@ static int via_ircc_dma_xmit(struct via_ircc_cb *self, u16 iobase)
        EnTXDMA(iobase, ON);
        EnRXDMA(iobase, OFF);
        irda_setup_dma(self->io.dma,
-                      self->tx_fifo.queue[self->tx_fifo.ptr].start,
+                      ((u8 *)self->tx_fifo.queue[self->tx_fifo.ptr].start -
+                       self->tx_buff.head) + self->tx_buff_dma,
                       self->tx_fifo.queue[self->tx_fifo.ptr].len, DMA_TX_MODE);
 #ifdef DBGMSG
        DBG(printk
@@ -1022,8 +1030,8 @@ static int via_ircc_dma_receive(struct via_ircc_cb *self)
        EnAllInt(iobase, ON);
        EnTXDMA(iobase, OFF);
        EnRXDMA(iobase, ON);
-       irda_setup_dma(self->io.dma2, self->rx_buff.data,
-                      self->rx_buff.truesize, DMA_RX_MODE);
+       irda_setup_dma(self->io.dma2, self->rx_buff_dma,
+                 self->rx_buff.truesize, DMA_RX_MODE);
        TXStart(iobase, OFF);
        RXStart(iobase, ON);
 
index c3568b6..dcb5c3d 100644 (file)
@@ -33,6 +33,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
 #include <linux/time.h>
 #include <linux/spinlock.h>
 #include <linux/pm.h>
+#include <linux/types.h>
 #include <asm/io.h>
 
 #define MAX_TX_WINDOW 7
@@ -102,6 +103,8 @@ struct via_ircc_cb {
        chipio_t io;            /* IrDA controller information */
        iobuff_t tx_buff;       /* Transmit buffer */
        iobuff_t rx_buff;       /* Receive buffer */
+       dma_addr_t tx_buff_dma;
+       dma_addr_t rx_buff_dma;
 
        __u8 ier;               /* Interrupt enable register */
 
index 1d4382b..64d8d3f 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -207,8 +208,9 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq,
        self->tx_buff.truesize = 4000;
        
        /* Allocate memory if needed */
-       self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
-                                             GFP_KERNEL|GFP_DMA);
+       self->rx_buff.head =
+               dma_alloc_coherent(NULL, self->rx_buff.truesize,
+                                  &self->rx_buff_dma, GFP_KERNEL);
        if (self->rx_buff.head == NULL) {
                err = -ENOMEM;
                goto err_out1;
@@ -216,8 +218,9 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq,
 
        memset(self->rx_buff.head, 0, self->rx_buff.truesize);
        
-       self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
-                                             GFP_KERNEL|GFP_DMA);
+       self->tx_buff.head =
+               dma_alloc_coherent(NULL, self->tx_buff.truesize,
+                                  &self->tx_buff_dma, GFP_KERNEL);
        if (self->tx_buff.head == NULL) {
                err = -ENOMEM;
                goto err_out2;
@@ -252,9 +255,11 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq,
        
        return 0;
 err_out3:
-       kfree(self->tx_buff.head);
+       dma_free_coherent(NULL, self->tx_buff.truesize,
+                         self->tx_buff.head, self->tx_buff_dma);
 err_out2:      
-       kfree(self->rx_buff.head);
+       dma_free_coherent(NULL, self->rx_buff.truesize,
+                         self->rx_buff.head, self->rx_buff_dma);
 err_out1:
        free_netdev(dev);
 err_out:
@@ -297,10 +302,12 @@ static int w83977af_close(struct w83977af_ir *self)
        release_region(self->io.fir_base, self->io.fir_ext);
 
        if (self->tx_buff.head)
-               kfree(self->tx_buff.head);
+               dma_free_coherent(NULL, self->tx_buff.truesize,
+                                 self->tx_buff.head, self->tx_buff_dma);
        
        if (self->rx_buff.head)
-               kfree(self->rx_buff.head);
+               dma_free_coherent(NULL, self->rx_buff.truesize,
+                                 self->rx_buff.head, self->rx_buff_dma);
 
        free_netdev(self->netdev);
 
@@ -606,10 +613,10 @@ static void w83977af_dma_write(struct w83977af_ir *self, int iobase)
        disable_dma(self->io.dma);
        clear_dma_ff(self->io.dma);
        set_dma_mode(self->io.dma, DMA_MODE_READ);
-       set_dma_addr(self->io.dma, isa_virt_to_bus(self->tx_buff.data));
+       set_dma_addr(self->io.dma, self->tx_buff_dma);
        set_dma_count(self->io.dma, self->tx_buff.len);
 #else
-       irda_setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, 
+       irda_setup_dma(self->io.dma, self->tx_buff_dma, self->tx_buff.len,
                       DMA_MODE_WRITE); 
 #endif
        self->io.direction = IO_XMIT;
@@ -763,10 +770,10 @@ int w83977af_dma_receive(struct w83977af_ir *self)
        disable_dma(self->io.dma);
        clear_dma_ff(self->io.dma);
        set_dma_mode(self->io.dma, DMA_MODE_READ);
-       set_dma_addr(self->io.dma, isa_virt_to_bus(self->rx_buff.data));
+       set_dma_addr(self->io.dma, self->rx_buff_dma);
        set_dma_count(self->io.dma, self->rx_buff.truesize);
 #else
-       irda_setup_dma(self->io.dma, self->rx_buff.data, self->rx_buff.truesize, 
+       irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize,
                       DMA_MODE_READ);
 #endif
        /* 
index c578ddc..0b7661d 100644 (file)
@@ -26,6 +26,7 @@
 #define W83977AF_IR_H
 
 #include <asm/io.h>
+#include <linux/types.h>
 
 /* Flags for configuration register CRF0 */
 #define ENBNKSEL       0x01
@@ -179,6 +180,8 @@ struct w83977af_ir {
        chipio_t io;               /* IrDA controller information */
        iobuff_t tx_buff;          /* Transmit buffer */
        iobuff_t rx_buff;          /* Receive buffer */
+       dma_addr_t tx_buff_dma;
+       dma_addr_t rx_buff_dma;
 
        /* Note : currently locking is *very* incomplete, but this
         * will get you started. Check in nsc-ircc.c for a proper
index 8df84e9..6509433 100644 (file)
@@ -161,6 +161,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr, NETCARD_IO_EXTENT);
 }
 
+#ifndef MODULE
 struct net_device * __init netcard_probe(int unit)
 {
        struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
@@ -185,6 +186,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 /*
  * This is the real probe routine. Linux has a history of friendly device
index 7bd6fe2..605a687 100644 (file)
@@ -362,7 +362,7 @@ ixgb_ethtool_geeprom(struct ixgb_adapter *adapter,
 
 static int
 ixgb_ethtool_seeprom(struct ixgb_adapter *adapter,
-                    struct ethtool_eeprom *eeprom, void *user_data)
+                    struct ethtool_eeprom *eeprom, void __user *user_data)
 {
        struct ixgb_hw *hw = &adapter->hw;
        uint16_t eeprom_buff[256];
@@ -457,10 +457,10 @@ ixgb_ethtool_led_blink(struct ixgb_adapter *adapter, struct ethtool_value *id)
 int ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
 {
        struct ixgb_adapter *adapter = netdev->priv;
-       void *addr = ifr->ifr_data;
+       void __user *addr = ifr->ifr_data;
        uint32_t cmd;
 
-       if (get_user(cmd, (uint32_t *) addr))
+       if (get_user(cmd, (uint32_t __user *) addr))
                return -EFAULT;
 
        switch (cmd) {
index 0bd4348..f28ab33 100644 (file)
@@ -1876,7 +1876,6 @@ static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
        struct ixgb_rx_desc *rx_desc;
        struct ixgb_buffer *buffer_info;
        struct sk_buff *skb;
-       int reserve_len = 2;
        unsigned int i;
        int num_group_tail_writes;
        long cleancount;
@@ -1895,7 +1894,7 @@ static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
        while (--cleancount > 0) {
                rx_desc = IXGB_RX_DESC(*rx_ring, i);
 
-               skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len);
+               skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
 
                if (unlikely(!skb)) {
                        /* Better luck next round */
@@ -1906,7 +1905,7 @@ static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
                 * this will result in a 16 byte aligned IP header after
                 * the 14 byte MAC header is removed
                 */
-               skb_reserve(skb, reserve_len);
+               skb_reserve(skb, NET_IP_ALIGN);
 
                skb->dev = netdev;
 
index 20f757c..8624bfc 100644 (file)
@@ -37,6 +37,8 @@
 #include <asm/jazz.h>
 #include <asm/jazzdma.h>
 
+#define DRV_NAME "jazzsonic"
+
 #define SREGS_PAD(n)    u16 n;
 
 #include "sonic.h"
@@ -151,7 +153,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
        int err = -ENODEV;
        int i;
 
-       if (!request_region(base_addr, 0x100, dev->name))
+       if (!request_region(base_addr, 0x100, DRV_NAME))
                return -EBUSY;
        /*
         * get the Silicon Revision ID. If this is one of the known
index a39f7a7..25c7aa4 100644 (file)
@@ -432,6 +432,7 @@ static int __init do_lance_probe(struct net_device *dev)
        return -ENODEV;
 }
 
+#ifndef MODULE
 struct net_device * __init lance_probe(int unit)
 {
        struct net_device *dev = alloc_etherdev(0);
@@ -456,6 +457,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options)
 {
index 4648326..9e83a01 100644 (file)
@@ -87,7 +87,6 @@
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
-#include <asm/pgalloc.h>
 #include <asm/irq.h>
 #include <asm/pdc.h>
 #include <asm/cache.h>
index 4a21b1c..0aa574b 100644 (file)
@@ -49,6 +49,8 @@ static const char *version =
 
 #include "8390.h"
 
+#define DRV_NAME "lne390"
+
 static int lne390_probe1(struct net_device *dev, int ioaddr);
 
 static int lne390_open(struct net_device *dev);
@@ -112,7 +114,7 @@ static int __init do_lne390_probe(struct net_device *dev)
        SET_MODULE_OWNER(dev);
 
        if (ioaddr > 0x1ff) {           /* Check a single specified location. */
-               if (!request_region(ioaddr, LNE390_IO_EXTENT, dev->name))
+               if (!request_region(ioaddr, LNE390_IO_EXTENT, DRV_NAME))
                        return -EBUSY;
                ret = lne390_probe1(dev, ioaddr);
                if (ret)
@@ -131,7 +133,7 @@ static int __init do_lne390_probe(struct net_device *dev)
 
        /* EISA spec allows for up to 16 slots, but 8 is typical. */
        for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
-               if (!request_region(ioaddr, LNE390_IO_EXTENT, dev->name))
+               if (!request_region(ioaddr, LNE390_IO_EXTENT, DRV_NAME))
                        continue;
                if (lne390_probe1(dev, ioaddr) == 0)
                        return 0;
@@ -151,6 +153,7 @@ static void cleanup_card(struct net_device *dev)
                iounmap((void *)dev->mem_start);
 }
 
+#ifndef MODULE
 struct net_device * __init lne390_probe(int unit)
 {
        struct net_device *dev = alloc_ei_netdev();
@@ -175,6 +178,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init lne390_probe1(struct net_device *dev, int ioaddr)
 {
@@ -228,7 +232,7 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr)
        }
        printk(" IRQ %d,", dev->irq);
 
-       if ((ret = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) {
+       if ((ret = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev))) {
                printk (" unable to get IRQ %d.\n", dev->irq);
                return ret;
        }
index 7dda5dd..38281f5 100644 (file)
@@ -75,6 +75,8 @@ All other communication is through memory!
 #include <asm/io.h>
 #include <asm/dma.h>
 
+#define DRV_NAME "lp486e"
+
 /* debug print flags */
 #define LOG_SRCDST    0x80000000
 #define LOG_STATINT   0x40000000
@@ -970,7 +972,7 @@ int __init lp486e_probe(struct net_device *dev) {
                return -ENODEV;
        probed++;
 
-       if (!request_region(IOADDR, LP486E_TOTAL_SIZE, dev->name)) {
+       if (!request_region(IOADDR, LP486E_TOTAL_SIZE, DRV_NAME)) {
                printk(KERN_ERR "lp486e: IO address 0x%x in use\n", IOADDR);
                return -EBUSY;
        }
index 73b1bbe..f597572 100644 (file)
@@ -53,7 +53,6 @@
 #include <asm/macintosh.h>
 #include <asm/macints.h>
 #include <asm/mac_via.h>
-#include <asm/pgalloc.h>
 
 #define SREGS_PAD(n)    u16 n;
 
index 9bae8d9..e81ac44 100644 (file)
@@ -766,7 +766,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
        SET_MODULE_OWNER(dev);
        SET_NETDEV_DEV(dev, &pdev->dev);
 
-       i = pci_request_regions(pdev, dev->name);
+       i = pci_request_regions(pdev, DRV_NAME);
        if (i)
                goto err_pci_request_regions;
 
@@ -1798,14 +1798,9 @@ static void netdev_rx(struct net_device *dev)
                                        np->rx_dma[entry],
                                        buflen,
                                        PCI_DMA_FROMDEVICE);
-#if HAS_IP_COPYSUM
                                eth_copy_and_sum(skb,
                                        np->rx_skbuff[entry]->tail, pkt_len, 0);
                                skb_put(skb, pkt_len);
-#else
-                               memcpy(skb_put(skb, pkt_len),
-                                       np->rx_skbuff[entry]->tail, pkt_len);
-#endif
                                pci_dma_sync_single_for_device(np->pci_dev,
                                        np->rx_dma[entry],
                                        buflen,
@@ -1961,12 +1956,12 @@ static void set_rx_mode(struct net_device *dev)
        spin_unlock_irq(&np->lock);
 }
 
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
        struct netdev_private *np = dev->priv;
        u32 cmd;
 
-       if (get_user(cmd, (u32 *)useraddr))
+       if (get_user(cmd, (u32 __user *)useraddr))
                return -EFAULT;
 
        switch (cmd) {
@@ -2417,11 +2412,11 @@ static int netdev_get_eeprom(struct net_device *dev, u8 *buf)
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+       struct mii_ioctl_data *data = if_mii(rq);
 
        switch(cmd) {
        case SIOCETHTOOL:
-               return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+               return netdev_ethtool_ioctl(dev, rq->ifr_data);
        case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
        case SIOCDEVPRIVATE:            /* for binary compat, remove in 2.5 */
                data->phy_id = 1;
index 86f34b5..84e291e 100644 (file)
@@ -34,6 +34,8 @@ static const char version1[] =
 
 #include "8390.h"
 
+#define DRV_NAME "ne-h8300"
+
 /* Some defines that people can play with if so inclined. */
 
 /* Do we perform extra sanity checks on stuff ? */
@@ -156,6 +158,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr, NE_IO_EXTENT);
 }
 
+#ifndef MODULE
 struct net_device * __init ne_probe(int unit)
 {
        struct net_device *dev = alloc_ei_netdev();
@@ -187,6 +190,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init ne_probe1(struct net_device *dev, int ioaddr)
 {
@@ -200,7 +204,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
        struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        unsigned char bus_width;
 
-       if (!request_region(ioaddr, NE_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME))
                return -EBUSY;
 
        reg0 = inb_p(ioaddr);
index 9de5ccc..ee9d4dd 100644 (file)
@@ -55,6 +55,8 @@ static const char version2[] =
 
 #include "8390.h"
 
+#define DRV_NAME "ne"
+
 /* Some defines that people can play with if so inclined. */
 
 /* Do we support clones that don't adhere to 14,15 of the SAprom ? */
@@ -203,6 +205,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr, NE_IO_EXTENT);
 }
 
+#ifndef MODULE
 struct net_device * __init ne_probe(int unit)
 {
        struct net_device *dev = alloc_ei_netdev();
@@ -227,6 +230,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init ne_probe_isapnp(struct net_device *dev)
 {
@@ -284,7 +288,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
        int reg0, ret;
        static unsigned version_printed;
 
-       if (!request_region(ioaddr, NE_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME))
                return -EBUSY;
 
        reg0 = inb_p(ioaddr);
index 739f92a..311471a 100644 (file)
@@ -82,6 +82,8 @@ static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon <wimpie@kotnet.o
 
 #include "8390.h"
 
+#define DRV_NAME "ne2"
+
 /* Some defines that people can play with if so inclined. */
 
 /* Do we perform extra sanity checks on stuff ? */
@@ -284,6 +286,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr, NE_IO_EXTENT);
 }
 
+#ifndef MODULE
 struct net_device * __init ne2_probe(int unit)
 {
        struct net_device *dev = alloc_ei_netdev();
@@ -308,6 +311,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int ne2_procinfo(char *buf, int slot, struct net_device *dev)
 {
@@ -368,7 +372,7 @@ static int __init ne2_probe1(struct net_device *dev, int slot)
                irq = irqs[(POS & 0x60)>>5];
        }
 
-       if (!request_region(base_addr, NE_IO_EXTENT, dev->name))
+       if (!request_region(base_addr, NE_IO_EXTENT, DRV_NAME))
                return -EBUSY;
 
 #ifdef DEBUG
@@ -470,7 +474,7 @@ static int __init ne2_probe1(struct net_device *dev, int slot)
 
        /* Snarf the interrupt now.  There's no point in waiting since we cannot
           share and the board will usually be enabled. */
-       retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
+       retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
        if (retval) {
                printk (" unable to get IRQ %d (irqval=%d).\n", 
                                dev->irq, retval);
index ec77fca..7228ba2 100644 (file)
@@ -45,6 +45,8 @@ static const char *version =
 
 #include "8390.h"
 
+#define DRV_NAME "ne3210"
+
 static int ne3210_open(struct net_device *dev);
 static int ne3210_close(struct net_device *dev);
 
@@ -111,13 +113,13 @@ static int __init ne3210_eisa_probe (struct device *device)
        device->driver_data = dev;
        ioaddr = edev->base_addr;
 
-       if (!request_region(ioaddr, NE3210_IO_EXTENT, dev->name)) {
+       if (!request_region(ioaddr, NE3210_IO_EXTENT, DRV_NAME)) {
                retval = -EBUSY;
                goto out;
        }
 
        if (!request_region(ioaddr + NE3210_CFG1,
-                           NE3210_CFG_EXTENT, dev->name)) {
+                           NE3210_CFG_EXTENT, DRV_NAME)) {
                retval = -EBUSY;
                goto out1;
        }
@@ -140,7 +142,7 @@ static int __init ne3210_eisa_probe (struct device *device)
        dev->irq = irq_map[(inb(ioaddr + NE3210_CFG2) >> 3) & 0x07];
        printk(".\nne3210.c: using IRQ %d, ", dev->irq);
 
-       retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
+       retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
        if (retval) {
                printk (" unable to get IRQ %d.\n", dev->irq);
                goto out2;
@@ -163,7 +165,7 @@ static int __init ne3210_eisa_probe (struct device *device)
                }
        }
        
-       if (!request_mem_region (phys_mem, NE3210_STOP_PG*0x100, dev->name)) {
+       if (!request_mem_region (phys_mem, NE3210_STOP_PG*0x100, DRV_NAME)) {
                printk ("ne3210.c: Unable to request shared memory at physical address %#lx\n",
                        phys_mem);
                goto out3;
index 714d970..234709d 100644 (file)
@@ -124,6 +124,8 @@ static int fifo=0x8;        /* don't change */
 
 #include "ni52.h"
 
+#define DRV_NAME "ni52"
+
 #define DEBUG       /* debug on */
 #define SYSBUSVAL 1 /* 8 Bit */
 
@@ -424,7 +426,7 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr)
        dev->mem_start = memstart;
        dev->mem_end = memend;
 
-       if (!request_region(ioaddr, NI52_TOTAL_SIZE, dev->name))
+       if (!request_region(ioaddr, NI52_TOTAL_SIZE, DRV_NAME))
                return -EBUSY;
 
        if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) ||
index 41fc5f9..1ee8c49 100644 (file)
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
+#define DRV_NAME "ns83820"
+
 /* Global parameters.  See MODULE_PARM near the bottom. */
 static int ihr = 2;
 static int reset_phy = 0;
@@ -1190,7 +1192,7 @@ static struct net_device_stats *ns83820_get_stats(struct net_device *ndev)
        return &dev->stats;
 }
 
-static int ns83820_ethtool_ioctl (struct ns83820 *dev, void *useraddr)
+static int ns83820_ethtool_ioctl (struct ns83820 *dev, void __user *useraddr)
 {
        u32 ethcmd;
 
@@ -1236,7 +1238,7 @@ static int ns83820_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 
        switch(cmd) {
        case SIOCETHTOOL:
-               return ns83820_ethtool_ioctl(dev, (void *) rq->ifr_data);
+               return ns83820_ethtool_ioctl(dev, rq->ifr_data);
 
        default:
                return -EOPNOTSUPP;
@@ -1851,7 +1853,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
                0);
 
        err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ,
-                         ndev->name, ndev);
+                         DRV_NAME, ndev);
        if (err) {
                printk(KERN_INFO "ns83820: unable to register irq %d\n",
                        pci_dev->irq);
index c241b7a..62167a2 100644 (file)
@@ -164,7 +164,7 @@ static int __init oaknet_init(void)
        ret = -EAGAIN;
        if (request_irq(dev->irq, ei_interrupt, 0, name, dev)) {
                printk("%s: unable to request interrupt %d.\n",
-                      dev->name, dev->irq);
+                      name, dev->irq);
                goto out_region;
        }
 
index 28d8b53..2385386 100644 (file)
@@ -1778,7 +1778,7 @@ static int netdrv_close (struct net_device *dev)
 static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct netdrv_private *tp = dev->priv;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
+       struct mii_ioctl_data *data = if_mii(rq);
        unsigned long flags;
        int rc = 0;
 
index 47a102f..59d80eb 100644 (file)
@@ -1196,7 +1196,7 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct el3_private *lp = netdev_priv(dev);
        ioaddr_t ioaddr = dev->base_addr;
-       u16 *data = (u16 *)&rq->ifr_data;
+       u16 *data = (u16 *)&rq->ifr_ifru;
        int phy = lp->phys & 0x1f;
 
        DEBUG(2, "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
index 9a46c56..ea5a88c 100644 (file)
@@ -778,7 +778,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
 static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
     axnet_dev_t *info = PRIV(dev);
-    u16 *data = (u16 *)&rq->ifr_data;
+    u16 *data = (u16 *)&rq->ifr_ifru;
     ioaddr_t mii_addr = dev->base_addr + AXNET_MII_EEP;
     switch (cmd) {
     case SIOCGMIIPHY:
index d073093..b53f5fc 100644 (file)
@@ -1281,7 +1281,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
 static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
     pcnet_dev_t *info = PRIV(dev);
-    u16 *data = (u16 *)&rq->ifr_data;
+    u16 *data = (u16 *)&rq->ifr_ifru;
     ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO;
     switch (cmd) {
     case SIOCGMIIPHY:
index 13ed04f..7c1bd34 100644 (file)
@@ -2119,12 +2119,12 @@ static int smc_netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
     return 0;
 }
 
-static int smc_ethtool_ioctl (struct net_device *dev, void *useraddr)
+static int smc_ethtool_ioctl (struct net_device *dev, void __user *useraddr)
 {
     u32 ethcmd;
     struct smc_private *smc = netdev_priv(dev);
 
-    if (get_user(ethcmd, (u32 *)useraddr))
+    if (get_user(ethcmd, (u32 __user *)useraddr))
        return -EFAULT;
 
     switch (ethcmd) {
@@ -2221,7 +2221,7 @@ static int smc_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
     u_short saved_bank;
     ioaddr_t ioaddr = dev->base_addr;
 
-    mii = (struct mii_ioctl_data *) &rq->ifr_data;
+    mii = if_mii(rq);
     if (!netif_running(dev))
        return -EINVAL;
 
@@ -2229,7 +2229,7 @@ static int smc_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
     case SIOCETHTOOL:
        saved_bank = inw(ioaddr + BANK_SELECT);
        SMC_SELECT_BANK(3);
-       rc = smc_ethtool_ioctl(dev, (void *) rq->ifr_data);
+       rc = smc_ethtool_ioctl(dev, rq->ifr_data);
        SMC_SELECT_BANK(saved_bank);
        break;
 
index 5671f12..d4cc269 100644 (file)
@@ -1681,7 +1681,7 @@ do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
     local_info_t *local = netdev_priv(dev);
     ioaddr_t ioaddr = dev->base_addr;
-    u16 *data = (u16 *)&rq->ifr_data;
+    u16 *data = (u16 *)&rq->ifr_ifru;
 
     DEBUG(1, "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
          dev->name, rq->ifr_ifrn.ifrn_name, cmd,
index 511bc10..bdf90d4 100644 (file)
@@ -2170,14 +2170,13 @@ static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val)
 static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
     struct pcnet32_private *lp = dev->priv;
-    struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
     int rc;
     unsigned long flags;
 
     /* SIOC[GS]MIIxxx ioctls */
     if (lp->mii) {
        spin_lock_irqsave(&lp->lock, flags);
-       rc = generic_mii_ioctl(&lp->mii_if, data, cmd, NULL);
+       rc = generic_mii_ioctl(&lp->mii_if, if_mii(rq), cmd, NULL);
        spin_unlock_irqrestore(&lp->lock, flags);
     } else {
        rc = -EOPNOTSUPP;
index 31bbff4..43f923c 100644 (file)
@@ -1217,7 +1217,7 @@ static int
 plip_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct net_local *nl = netdev_priv(dev);
-       struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
+       struct plipconf *pc = (struct plipconf *) &rq->ifr_ifru;
 
        if (cmd != SIOCDEVPLIP)
                return -EOPNOTSUPP;
index 0e27077..e686cb4 100644 (file)
@@ -716,7 +716,7 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
                goto err_out_disable;
        }
 
-       rc = pci_request_regions(pdev, dev->name);
+       rc = pci_request_regions(pdev, MODULENAME);
        if (rc) {
                printk(KERN_ERR PFX "%s: Could not request regions.\n", pdev->slot_name);
                goto err_out_disable;
index a6d09dd..d773145 100644 (file)
@@ -1715,7 +1715,7 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                return error;
                
        case SIOCRRID:
-               return put_user(0x52523032, (int *)(&rq->ifr_data[0]));
+               return put_user(0x52523032, (int __user *)rq->ifr_data);
        default:
                return error;
        }
index 83a53bc..c4bd179 100644 (file)
@@ -99,45 +99,45 @@ static char s2io_gstrings[][ETH_GSTRING_LEN] = {
 };
 
 static char ethtool_stats_keys[][ETH_GSTRING_LEN] = {
-       {"tmac_frms"},
-       {"tmac_data_octets"},
-       {"tmac_drop_frms"},
-       {"tmac_mcst_frms"},
-       {"tmac_bcst_frms"},
-       {"tmac_pause_ctrl_frms"},
-       {"tmac_any_err_frms"},
-       {"tmac_vld_ip_octets"},
-       {"tmac_vld_ip"},
-       {"tmac_drop_ip"},
-       {"tmac_icmp"},
-       {"tmac_rst_tcp"},
-       {"tmac_tcp"},
-       {"tmac_udp"},
-       {"rmac_vld_frms"},
-       {"rmac_data_octets"},
-       {"rmac_fcs_err_frms"},
-       {"rmac_drop_frms"},
-       {"rmac_vld_mcst_frms"},
-       {"rmac_vld_bcst_frms"},
-       {"rmac_in_rng_len_err_frms"},
-       {"rmac_long_frms"},
-       {"rmac_pause_ctrl_frms"},
-       {"rmac_discarded_frms"},
-       {"rmac_usized_frms"},
-       {"rmac_osized_frms"},
-       {"rmac_frag_frms"},
-       {"rmac_jabber_frms"},
-       {"rmac_ip"},
-       {"rmac_ip_octets"},
-       {"rmac_hdr_err_ip"},
-       {"rmac_drop_ip"},
-       {"rmac_icmp"},
-       {"rmac_tcp"},
-       {"rmac_udp"},
-       {"rmac_err_drp_udp"},
-       {"rmac_pause_cnt"},
-       {"rmac_accepted_ip"},
-       {"rmac_err_tcp"},
+       "tmac_frms",
+       "tmac_data_octets",
+       "tmac_drop_frms",
+       "tmac_mcst_frms",
+       "tmac_bcst_frms",
+       "tmac_pause_ctrl_frms",
+       "tmac_any_err_frms",
+       "tmac_vld_ip_octets",
+       "tmac_vld_ip",
+       "tmac_drop_ip",
+       "tmac_icmp",
+       "tmac_rst_tcp",
+       "tmac_tcp",
+       "tmac_udp",
+       "rmac_vld_frms",
+       "rmac_data_octets",
+       "rmac_fcs_err_frms",
+       "rmac_drop_frms",
+       "rmac_vld_mcst_frms",
+       "rmac_vld_bcst_frms",
+       "rmac_in_rng_len_err_frms",
+       "rmac_long_frms",
+       "rmac_pause_ctrl_frms",
+       "rmac_discarded_frms",
+       "rmac_usized_frms",
+       "rmac_osized_frms",
+       "rmac_frag_frms",
+       "rmac_jabber_frms",
+       "rmac_ip",
+       "rmac_ip_octets",
+       "rmac_hdr_err_ip",
+       "rmac_drop_ip",
+       "rmac_icmp",
+       "rmac_tcp",
+       "rmac_udp",
+       "rmac_err_drp_udp",
+       "rmac_pause_cnt",
+       "rmac_accepted_ip",
+       "rmac_err_tcp",
 };
 
 #define S2IO_STAT_LEN sizeof(ethtool_stats_keys)/ ETH_GSTRING_LEN
@@ -1425,13 +1425,13 @@ int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                        goto end;
                }
 
-               skb = dev_alloc_skb(size + HEADER_ALIGN_LAYER_3);
+               skb = dev_alloc_skb(size + NET_IP_ALIGN);
                if (!skb) {
                        DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name);
                        DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n");
                        return -ENOMEM;
                }
-               skb_reserve(skb, HEADER_ALIGN_LAYER_3);
+               skb_reserve(skb, NET_IP_ALIGN);
                memset(rxdp, 0, sizeof(RxD_t));
                rxdp->Buffer0_ptr = pci_map_single
                    (nic->pdev, skb->data, size, PCI_DMA_FROMDEVICE);
index 41cb60f..e9a1664 100644 (file)
@@ -411,7 +411,6 @@ struct config_param {
 #define HEADER_802_2_SIZE              3
 #define HEADER_SNAP_SIZE               5
 #define HEADER_VLAN_SIZE               4
-#define HEADER_ALIGN_LAYER_3           2
 
 #define MIN_MTU                       46
 #define MAX_PYLD                    1500
index ea2d891..8ac2d81 100644 (file)
@@ -1031,14 +1031,14 @@ static int sb1000_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        case SIOCGCMFREQUENCY:          /* get frequency */
                if ((status = sb1000_get_frequency(ioaddr, name, &frequency)))
                        return status;
-               if(put_user(frequency, (int*) ifr->ifr_data))
+               if(put_user(frequency, (int __user *) ifr->ifr_data))
                        return -EFAULT;
                break;
 
        case SIOCSCMFREQUENCY:          /* set frequency */
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
-               if(get_user(frequency, (int*) ifr->ifr_data))
+               if(get_user(frequency, (int __user *) ifr->ifr_data))
                        return -EFAULT;
                if ((status = sb1000_set_frequency(ioaddr, name, frequency)))
                        return status;
index 0b15d65..7914167 100644 (file)
@@ -2721,7 +2721,7 @@ static void sbmac_set_rx_mode(struct net_device *dev)
 static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct sbmac_softc *sc = netdev_priv(dev);
-       u16 *data = (u16 *)&rq->ifr_data;
+       u16 *data = (u16 *)&rq->ifr_ifru;
        unsigned long flags;
        int retval;
        
index 9352fc6..2351e18 100644 (file)
@@ -579,7 +579,7 @@ static int shaper_attach(struct net_device *shdev, struct shaper *sh, struct net
 
 static int shaper_ioctl(struct net_device *dev,  struct ifreq *ifr, int cmd)
 {
-       struct shaperconf *ss= (struct shaperconf *)&ifr->ifr_data;
+       struct shaperconf *ss= (struct shaperconf *)&ifr->ifr_ifru;
        struct shaper *sh=dev->priv;
        
        if(ss->ss_cmd == SHAPER_SET_DEV || ss->ss_cmd == SHAPER_SET_SPEED)
index 05479dd..aa045b6 100644 (file)
@@ -1893,7 +1893,7 @@ static struct ethtool_ops sis900_ethtool_ops = {
 static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
 {
        struct sis900_private *sis_priv = net_dev->priv;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+       struct mii_ioctl_data *data = if_mii(rq);
 
        switch(cmd) {
        case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
index e783ac0..a896711 100644 (file)
@@ -1138,6 +1138,7 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
 {
        struct slip *sl = (struct slip *) tty->disc_data;
        unsigned int tmp;
+       int __user *p = (int __user *)arg;
 
        /* First make sure we're connected. */
        if (!sl || sl->magic != SLIP_MAGIC) {
@@ -1147,17 +1148,17 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
        switch(cmd) {
         case SIOCGIFNAME:
                tmp = strlen(sl->dev->name) + 1;
-               if (copy_to_user((void *)arg, sl->dev->name, tmp))
+               if (copy_to_user((void __user *)arg, sl->dev->name, tmp))
                        return -EFAULT;
                return 0;
 
        case SIOCGIFENCAP:
-               if (put_user(sl->mode, (int *)arg))
+               if (put_user(sl->mode, p))
                        return -EFAULT;
                return 0;
 
        case SIOCSIFENCAP:
-               if (get_user(tmp,(int *)arg))
+               if (get_user(tmp, p))
                        return -EFAULT;
 #ifndef SL_INCLUDE_CSLIP
                if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE))  {
@@ -1185,7 +1186,7 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
 #ifdef CONFIG_SLIP_SMART
        /* VSV changes start here */
         case SIOCSKEEPALIVE:
-               if (get_user(tmp,(int *)arg))
+               if (get_user(tmp, p))
                        return -EFAULT;
                 if (tmp > 255) /* max for unchar */
                        return -EINVAL;
@@ -1205,12 +1206,12 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
                return 0;
 
         case SIOCGKEEPALIVE:
-               if (put_user(sl->keepalive, (int *)arg))
+               if (put_user(sl->keepalive, p))
                        return -EFAULT;
                return 0;
 
         case SIOCSOUTFILL:
-               if (get_user(tmp,(int *)arg))
+               if (get_user(tmp, p))
                        return -EFAULT;
                 if (tmp > 255) /* max for unchar */
                        return -EINVAL;
@@ -1229,7 +1230,7 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
                 return 0;
 
         case SIOCGOUTFILL:
-               if (put_user(sl->outfill, (int *)arg))
+               if (put_user(sl->outfill, p))
                        return -EFAULT;
                return 0;
        /* VSV changes end */
@@ -1254,6 +1255,7 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
 static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
 {
        struct slip *sl = (struct slip*)(dev->priv);
+       unsigned long *p = (unsigned long *)&rq->ifr_ifru;
 
        if (sl == NULL)         /* Allocation failed ?? */
                return -ENODEV;
@@ -1268,11 +1270,11 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
        switch(cmd){
         case SIOCSKEEPALIVE:
                /* max for unchar */
-                if (((unsigned int)((unsigned long)rq->ifr_data)) > 255) {
+                if ((unsigned)*p > 255) {
                        spin_unlock_bh(&sl->lock);
                        return -EINVAL;
                }
-               sl->keepalive = (unchar) ((unsigned long)rq->ifr_data);
+               sl->keepalive = (unchar) *p;
                if (sl->keepalive != 0) {
                        sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ;
                        mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ);
@@ -1283,15 +1285,15 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
                break;
 
         case SIOCGKEEPALIVE:
-               rq->ifr_data=(caddr_t)((unsigned long)sl->keepalive);
+               *p = sl->keepalive;
                break;
 
         case SIOCSOUTFILL:
-                if (((unsigned)((unsigned long)rq->ifr_data)) > 255) { /* max for unchar */
+                if ((unsigned)*p > 255) { /* max for unchar */
                        spin_unlock_bh(&sl->lock);
                        return -EINVAL;
                }
-                if ((sl->outfill = (unchar)((unsigned long) rq->ifr_data)) != 0){
+                if ((sl->outfill = (unchar)*p) != 0){
                        mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ);
                        set_bit(SLF_OUTWAIT, &sl->flags);
                } else {
@@ -1300,7 +1302,7 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
                 break;
 
         case SIOCGOUTFILL:
-               rq->ifr_data=(caddr_t)((unsigned long)sl->outfill);
+               *p = sl->outfill;
                break;
 
         case SIOCSLEASE:
@@ -1312,12 +1314,12 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
                        return -EPERM;
                }
                sl->leased = 0;
-                if ((unsigned long)rq->ifr_data)
+                if (*p)
                        sl->leased = 1;
                 break;
 
         case SIOCGLEASE:
-               rq->ifr_data=(caddr_t)((unsigned long)sl->leased);
+               *p = sl->leased;
        };
        spin_unlock_bh(&sl->lock);
        return 0;
index b67fcc0..c176df6 100644 (file)
@@ -51,6 +51,8 @@
 #include "8390.h"
 #include "smc-mca.h"
 
+#define DRV_NAME "smc-mca"
+
 static int ultramca_open(struct net_device *dev);
 static void ultramca_reset_8390(struct net_device *dev);
 static void ultramca_get_8390_hdr(struct net_device *dev,
@@ -265,7 +267,7 @@ int __init ultramca_probe(struct device *gen_dev)
                goto err_unclaim;
        }
 
-       if (!request_region(ioaddr, ULTRA_IO_EXTENT, dev->name)) {
+       if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) {
                rc = -ENODEV;
                goto err_unclaim;
        }
index 5d71ed2..ce4628f 100644 (file)
@@ -72,6 +72,8 @@ static const char version[] =
 
 #include "8390.h"
 
+#define DRV_NAME "smc-ultra"
+
 /* A zero-terminated list of I/O addresses to be probed. */
 static unsigned int ultra_portlist[] __initdata =
 {0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0};
@@ -178,6 +180,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT);
 }
 
+#ifndef MODULE
 struct net_device * __init ultra_probe(int unit)
 {
        struct net_device *dev = alloc_ei_netdev();
@@ -202,6 +205,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init ultra_probe1(struct net_device *dev, int ioaddr)
 {
@@ -215,7 +219,7 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr)
        unsigned char idreg = inb(ioaddr + 7);
        unsigned char reg4 = inb(ioaddr + 4) & 0x7f;
 
-       if (!request_region(ioaddr, ULTRA_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME))
                return -EBUSY;
 
        /* Check the ID nibble. */
index b26e0f8..8080a37 100644 (file)
@@ -61,6 +61,8 @@ static const char *version = "smc-ultra32.c: 06/97 v1.00\n";
 
 #include "8390.h"
 
+#define DRV_NAME "smc-ultra32"
+
 static int ultra32_probe1(struct net_device *dev, int ioaddr);
 static int ultra32_open(struct net_device *dev);
 static void ultra32_reset_8390(struct net_device *dev);
@@ -163,7 +165,7 @@ static int __init ultra32_probe1(struct net_device *dev, int ioaddr)
        unsigned char reg4;
        const char *ifmap[] = {"UTP No Link", "", "UTP/AUI", "UTP/BNC"};
 
-       if (!request_region(ioaddr, ULTRA32_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, ULTRA32_IO_EXTENT, DRV_NAME))
                return -EBUSY;
 
        if (inb(ioaddr + ULTRA32_IDPORT) == 0xff ||
index d2a2fe9..a827349 100644 (file)
@@ -78,6 +78,8 @@ static const char version[] =
 
 #include "smc9194.h"
 
+#define DRV_NAME "smc9194"
+
 /*------------------------------------------------------------------------
  .
  . Configuration options, for the experienced user to change.
@@ -843,7 +845,7 @@ static int __init smc_probe(struct net_device *dev, int ioaddr)
        word memory_cfg_register;
 
        /* Grab the region so that no one else tries to probe our ioports. */
-       if (!request_region(ioaddr, SMC_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, SMC_IO_EXTENT, DRV_NAME))
                return -EBUSY;
 
        dev->irq = irq;
@@ -1001,9 +1003,9 @@ static int __init smc_probe(struct net_device *dev, int ioaddr)
        memset(dev->priv, 0, sizeof(struct smc_local));
 
        /* Grab the IRQ */
-       retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev);
+       retval = request_irq(dev->irq, &smc_interrupt, 0, DRV_NAME, dev);
        if (retval) {
-               printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
+               printk("%s: unable to get IRQ %d (irqval=%d).\n", DRV_NAME,
                        dev->irq, retval);
                goto err_out;
        }
index 9b47edb..793201d 100644 (file)
@@ -880,7 +880,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
 
        irq = pdev->irq;
 
-       if (pci_request_regions (pdev, dev->name)) {
+       if (pci_request_regions (pdev, DRV_NAME)) {
                printk(KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx);
                goto err_out_free_netdev;
        }
@@ -1997,7 +1997,7 @@ static void set_rx_mode(struct net_device *dev)
 }
 
 
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
        struct ethtool_cmd ecmd;
        struct netdev_private *np = dev->priv;
@@ -2079,16 +2079,16 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct netdev_private *np = dev->priv;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
        int rc;
 
        if (!netif_running(dev))
                return -EINVAL;
 
        if (cmd == SIOCETHTOOL)
-               rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+               rc = netdev_ethtool_ioctl(dev, rq->ifr_data);
 
        else {
+               struct mii_ioctl_data *data = if_mii(rq);
                spin_lock_irq(&np->lock);
                rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL);
                spin_unlock_irq(&np->lock);
index 8346de4..b6dfdf8 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "8390.h"
 
+#define DRV_NAME "stnic"
+
 #define byte   unsigned char
 #define half   unsigned short
 #define word   unsigned int
@@ -130,7 +132,7 @@ static int __init stnic_probe(void)
 
   /* Snarf the interrupt now.  There's no point in waiting since we cannot
      share and the board will usually be enabled. */
-  err = request_irq (dev->irq, ei_interrupt, 0, dev->name, dev);
+  err = request_irq (dev->irq, ei_interrupt, 0, DRV_NAME, dev);
   if (err)  {
       printk (KERN_EMERG " unable to get IRQ %d.\n", dev->irq);
       free_netdev(dev);
index 669a02f..053fcaf 100644 (file)
@@ -53,6 +53,8 @@ static int fifo=0x8;  /* don't change */
 
 #include "sun3_82586.h"
 
+#define DRV_NAME "sun3_82586"
+
 #define DEBUG       /* debug on */
 #define SYSBUSVAL 0 /* 16 Bit */
 #define SUN3_82586_TOTAL_SIZE  PAGE_SIZE
@@ -336,7 +338,7 @@ static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
 {
        int i, size, retval;
 
-       if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, dev->name))
+       if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, DRV_NAME))
                return -EBUSY;
 
        /* copy in the ethernet address from the prom */
index f0512a4..6faef84 100644 (file)
@@ -42,7 +42,6 @@ static char *version = "sun3lance.c: v1.2 1/12/2001  Sam Creasey (sammy@sammy.ne
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
-#include <asm/pgalloc.h>
 #include <asm/dvma.h>
 #include <asm/idprom.h>
 #include <asm/machines.h>
index 838c9c5..e5069fc 100644 (file)
@@ -1576,7 +1576,7 @@ static int __set_mac_addr(struct net_device *dev)
 }
        
 
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
        struct netdev_private *np = dev->priv;
        u32 ethcmd;
@@ -1659,7 +1659,6 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct netdev_private *np = dev->priv;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
        int rc;
        int i;
        long ioaddr = dev->base_addr;
@@ -1668,11 +1667,11 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                return -EINVAL;
 
        if (cmd == SIOCETHTOOL)
-               rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+               rc = netdev_ethtool_ioctl(dev, rq->ifr_data);
 
        else {
                spin_lock_irq(&np->lock);
-               rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL);
+               rc = generic_mii_ioctl(&np->mii_if, if_mii(rq), cmd, NULL);
                spin_unlock_irq(&np->lock);
        }
        switch (cmd) {
index 36ddb6d..b831eef 100644 (file)
@@ -2510,7 +2510,7 @@ static struct ethtool_ops gem_ethtool_ops = {
 static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        struct gem *gp = dev->priv;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
+       struct mii_ioctl_data *data = if_mii(ifr);
        int rc = -EOPNOTSUPP;
        
        /* Hold the PM semaphore while doing ioctl's or we may collide
@@ -2717,7 +2717,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
 
        gp = dev->priv;
 
-       err = pci_request_regions(pdev, dev->name);
+       err = pci_request_regions(pdev, DRV_NAME);
        if (err) {
                printk(KERN_ERR PFX "Cannot obtain PCI resources, "
                       "aborting.\n");
index 5c2917c..c56a4ba 100644 (file)
@@ -68,6 +68,8 @@ static char version[] =
 #include "sunhme.h"
 
 
+#define DRV_NAME "sunhme"
+
 static int macaddr[6];
 
 /* accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */
@@ -3085,7 +3087,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
                printk(KERN_ERR "happymeal(PCI): Cannot find proper PCI device base address.\n");
                goto err_out_clear_quattro;
        }
-       if (pci_request_regions(pdev, dev->name)) {
+       if (pci_request_regions(pdev, DRV_NAME)) {
                printk(KERN_ERR "happymeal(PCI): Cannot obtain PCI resources, "
                       "aborting.\n");
                goto err_out_clear_quattro;
index 20ba895..6b2a168 100644 (file)
@@ -56,8 +56,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.5"
-#define DRV_MODULE_RELDATE     "May 25, 2004"
+#define DRV_MODULE_VERSION     "3.6"
+#define DRV_MODULE_RELDATE     "June 12, 2004"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -177,6 +177,8 @@ static struct pci_device_id tg3_pci_tbl[] = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5788,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5789,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2,
@@ -195,6 +197,10 @@ static struct pci_device_id tg3_pci_tbl[] = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750M,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751M,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751F,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX,
@@ -6678,7 +6684,7 @@ static void tg3_get_ethtool_stats (struct net_device *dev,
 
 static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
+       struct mii_ioctl_data *data = if_mii(ifr);
        struct tg3 *tp = netdev_priv(dev);
        int err;
 
@@ -7536,6 +7542,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        udelay(50);
        tg3_nvram_init(tp);
 
+       /* Always use host TXDs, it performs better in particular
+        * with multi-frag packets.  The tests below are kept here
+        * as documentation should we change this decision again
+        * in the future.
+        */
+       tp->tg3_flags |= TG3_FLAG_HOST_TXDS;
+
+#if 0
        /* Determine if TX descriptors will reside in
         * main memory or in the chip SRAM.
         */
@@ -7543,6 +7557,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
                tp->tg3_flags |= TG3_FLAG_HOST_TXDS;
+#endif
 
        grc_misc_cfg = tr32(GRC_MISC_CFG);
        grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK;
@@ -7565,7 +7580,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
             tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM &&
             (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901 ||
              tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901_2 ||
-             tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)))
+             tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)) ||
+           (tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM &&
+            tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F))
                tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
 
        err = tg3_phy_probe(tp);
@@ -8446,6 +8463,8 @@ static int tg3_resume(struct pci_dev *pdev)
        if (!netif_running(dev))
                return 0;
 
+       pci_restore_state(tp->pdev, tp->pci_cfg_state);
+
        err = tg3_set_power_state(tp, 0);
        if (err)
                return err;
index 3c10d2a..4c57ab2 100644 (file)
@@ -984,7 +984,7 @@ static int TLan_Open( struct net_device *dev )
 static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        TLanPrivateInfo *priv = dev->priv;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+       struct mii_ioctl_data *data = if_mii(rq);
        u32 phy   = priv->phy[priv->phyNum];
        
        if (!priv->phyOnline)
index 02bc6d3..6182cf4 100644 (file)
@@ -71,10 +71,17 @@ config TULIP_MMIO
 config TULIP_NAPI
        bool "Use NAPI RX polling "
        depends on TULIP
-       ---help---
-         This is of useful for servers and routers dealing with high network loads.
-         See <file:Documentation/networking/NAPI_HOWTO.txt>.
+       help
+         NAPI is a new driver API designed to reduce CPU and interrupt load
+         when the driver is receiving lots of packets from the card. It is
+         still somewhat experimental and thus not yet enabled by default.
+
+         If your estimated Rx load is 10kpps or more, or if the card will be
+         deployed on potentially unfriendly networks (e.g. in a firewall),
+         then say Y here.
+
+         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+         information.
 
          If in doubt, say N.
 
index 3fb06e5..d59d46e 100644 (file)
@@ -5535,7 +5535,7 @@ static int
 de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
     struct de4x5_private *lp = netdev_priv(dev);
-    struct de4x5_ioctl *ioc = (struct de4x5_ioctl *) &rq->ifr_data;
+    struct de4x5_ioctl *ioc = (struct de4x5_ioctl *) &rq->ifr_ifru;
     u_long iobase = dev->base_addr;
     int i, j, status = 0;
     s32 omr;
index 7f02aac..ad37a40 100644 (file)
 struct de4x5_ioctl {
        unsigned short cmd;                /* Command to run */
        unsigned short len;                /* Length of the data buffer */
-       unsigned char  *data;              /* Pointer to the data buffer */
+       unsigned char  __user *data;       /* Pointer to the data buffer */
 };
 
 /* 
index cb0e304..f86170e 100644 (file)
@@ -133,6 +133,10 @@ int tulip_poll(struct net_device *dev, int *budget)
                           tp->rx_ring[entry].status);
 
        do {
+               if (inl(dev->base_addr + CSR5) == 0xffffffff) {
+                       printk(KERN_DEBUG " In tulip_poll(), hardware disappeared.\n");
+                       break;
+               }
                /* Acknowledge current RX interrupt sources. */
                outl((RxIntr | RxNoBuf), dev->base_addr + CSR5);
  
index 0fc00ed..498f612 100644 (file)
@@ -830,7 +830,7 @@ static struct net_device_stats *tulip_get_stats(struct net_device *dev)
 }
 
 
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
        struct tulip_private *np = netdev_priv(dev);
        u32 ethcmd;
@@ -859,14 +859,14 @@ static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct tulip_private *tp = netdev_priv(dev);
        long ioaddr = dev->base_addr;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
+       struct mii_ioctl_data *data = if_mii(rq);
        const unsigned int phy_idx = 0;
        int phy = tp->phys[phy_idx] & 0x1f;
        unsigned int regnum = data->reg_num;
 
        switch (cmd) {
        case SIOCETHTOOL:
-               return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+               return netdev_ethtool_ioctl(dev, rq->ifr_data);
 
        case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
                if (tp->mii_cnt)
index 74d4253..6246e44 100644 (file)
@@ -1292,14 +1292,8 @@ static int netdev_rx(struct net_device *dev)
                                pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry],
                                                            np->rx_skbuff[entry]->len,
                                                            PCI_DMA_FROMDEVICE);
-                               /* Call copy + cksum if available. */
-#if HAS_IP_COPYSUM
                                eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
                                skb_put(skb, pkt_len);
-#else
-                               memcpy(skb_put(skb, pkt_len), np->rx_skbuff[entry]->tail,
-                                          pkt_len);
-#endif
                                pci_dma_sync_single_for_device(np->pci_dev,np->rx_addr[entry],
                                                               np->rx_skbuff[entry]->len,
                                                               PCI_DMA_FROMDEVICE);
@@ -1526,8 +1520,8 @@ static struct ethtool_ops netdev_ethtool_ops = {
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
-       struct netdev_private *np = dev->priv;
+       struct mii_ioctl_data *data = if_mii(rq);
+       struct netdev_private *np = netdev_priv(dev);
 
        switch(cmd) {
        case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
index 5f6cea1..a01cc1b 100644 (file)
@@ -1369,7 +1369,7 @@ static struct net_device_stats *xircom_get_stats(struct net_device *dev)
 }
 
 
-static int xircom_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int xircom_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
        struct ethtool_cmd ecmd;
        struct xircom_private *tp = dev->priv;
@@ -1471,13 +1471,13 @@ static int xircom_ethtool_ioctl(struct net_device *dev, void *useraddr)
 static int xircom_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct xircom_private *tp = dev->priv;
-       u16 *data = (u16 *)&rq->ifr_data;
+       u16 *data = (u16 *)&rq->ifr_ifru;
        int phy = tp->phys[0] & 0x1f;
        unsigned long flags;
 
        switch(cmd) {
        case SIOCETHTOOL:
-               return xircom_ethtool_ioctl(dev, (void *) rq->ifr_data);
+               return xircom_ethtool_ioctl(dev, rq->ifr_data);
 
        /* Legacy mii-diag interface */
        case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
index e6df23f..d0fe0f6 100644 (file)
@@ -129,8 +129,8 @@ static void tun_net_init(struct net_device *dev)
                dev->addr_len = 0;
                dev->mtu = 1500;
 
-               /* Type PPP seems most suitable */
-               dev->type = ARPHRD_PPP
+               /* Zero header length */
+               dev->type = ARPHRD_NONE
                dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
                dev->tx_queue_len = 10;
                break;
@@ -241,10 +241,10 @@ static ssize_t tun_chr_writev(struct file * file, const struct iovec *iv,
 }
 
 /* Write */
-static ssize_t tun_chr_write(struct file * file, const char * buf, 
+static ssize_t tun_chr_write(struct file * file, const char __user * buf, 
                             size_t count, loff_t *pos)
 {
-       struct iovec iv = { (void *) buf, count };
+       struct iovec iv = { (void __user *) buf, count };
        return tun_chr_writev(file, &iv, 1, pos);
 }
 
@@ -333,7 +333,7 @@ static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv,
 }
 
 /* Read */
-static ssize_t tun_chr_read(struct file * file, char * buf, 
+static ssize_t tun_chr_read(struct file * file, char __user * buf, 
                            size_t count, loff_t *pos)
 {
        struct iovec iv = { buf, count };
@@ -462,7 +462,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
                struct ifreq ifr;
                int err;
 
-               if (copy_from_user(&ifr, (void *)arg, sizeof(ifr)))
+               if (copy_from_user(&ifr, (void __user *)arg, sizeof(ifr)))
                        return -EFAULT;
                ifr.ifr_name[IFNAMSIZ-1] = '\0';
 
@@ -473,7 +473,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
                if (err)
                        return err;
 
-               if (copy_to_user((void *)arg, &ifr, sizeof(ifr)))
+               if (copy_to_user((void __user *)arg, &ifr, sizeof(ifr)))
                        return -EFAULT;
                return 0;
        }
index 39949db..45ab199 100644 (file)
@@ -1162,7 +1162,7 @@ typhoon_ethtool_sset(struct typhoon *tp, struct ethtool_cmd *cmd)
 }
 
 static inline int
-typhoon_ethtool_ioctl(struct net_device *dev, void *useraddr)
+typhoon_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
        struct typhoon *tp = (struct typhoon *) dev->priv;
        u32 ethcmd;
@@ -1237,7 +1237,7 @@ typhoon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        switch (cmd) {
        case SIOCETHTOOL:
-               return typhoon_ethtool_ioctl(dev, (void *) ifr->ifr_data);
+               return typhoon_ethtool_ioctl(dev, ifr->ifr_data);
        default:
                break;
        }
index d399b34..4744325 100644 (file)
@@ -354,59 +354,46 @@ The chip does not pad to minimum transmit length.
    second only the 1234 card.
 */
 
-enum pci_flags_bit {
-       PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
-       PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
+enum rhine_revs {
+       VT86C100A       = 0x00,
+       VT6102          = 0x40,
+       VT8231          = 0x50, /* Integrated MAC */
+       VT8233          = 0x60, /* Integrated MAC */
+       VT8235          = 0x74, /* Integrated MAC */
+       VT8237          = 0x78, /* Integrated MAC */
+       VTunknown0      = 0x7C,
+       VT6105          = 0x80,
+       VT6105_B0       = 0x83,
+       VT6105L         = 0x8A,
+       VT6107          = 0x8C,
+       VTunknown1      = 0x8E,
+       VT6105M         = 0x90,
 };
 
-enum rhine_chips {
-       VT86C100A = 0,
-       VT6102,
-       VT6105,
-       VT6105M
-};
-
-struct rhine_chip_info {
-       const char *name;
-       u16 pci_flags;
-       int io_size;
-       int drv_flags;
-};
-
-
-enum chip_capability_flags {
-       CanHaveMII=1, HasESIPhy=2, HasDavicomPhy=4,
-       ReqTxAlign=0x10, HasWOL=0x20,
+enum rhine_quirks {
+       rqWOL           = 0x0001,       /* Wake-On-LAN support */
+       rqForceReset    = 0x0002,
+       rqDavicomPhy    = 0x0020,
+       rq6patterns     = 0x0040,       /* 6 instead of 4 patterns for WOL */
+       rqStatusWBRace  = 0x0080,       /* Tx Status Writeback Error possible */
+       rqRhineI        = 0x0100,       /* See comment below */
 };
+/*
+ * rqRhineI: VT86C100A (aka Rhine-I) uses different bits to enable
+ * MMIO as well as for the collision counter and the Tx FIFO underflow
+ * indicator. In addition, Tx and Rx buffers need to 4 byte aligned.
+ */
 
-#ifdef USE_MMIO
-#define RHINE_IOTYPE (PCI_USES_MEM | PCI_USES_MASTER | PCI_ADDR1)
-#else
-#define RHINE_IOTYPE (PCI_USES_IO  | PCI_USES_MASTER | PCI_ADDR0)
-#endif
 /* Beware of PCI posted writes */
 #define IOSYNC do { readb(dev->base_addr + StationAddr); } while (0)
 
-/* directly indexed by enum rhine_chips, above */
-static struct rhine_chip_info rhine_chip_info[] __devinitdata =
-{
-       { "VIA VT86C100A Rhine", RHINE_IOTYPE, 128,
-         CanHaveMII | ReqTxAlign | HasDavicomPhy },
-       { "VIA VT6102 Rhine-II", RHINE_IOTYPE, 256,
-         CanHaveMII | HasWOL },
-       { "VIA VT6105 Rhine-III", RHINE_IOTYPE, 256,
-         CanHaveMII | HasWOL },
-       { "VIA VT6105M Rhine-III", RHINE_IOTYPE, 256,
-         CanHaveMII | HasWOL },
-};
-
 static struct pci_device_id rhine_pci_tbl[] =
 {
-       {0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT86C100A},
-       {0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6102},
-       {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105}, /* 6105{,L,LOM} */
-       {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105M},
-       {0,}    /* terminate list */
+       {0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT86C100A */
+       {0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT6102 */
+       {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* 6105{,L,LOM} */
+       {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT6105M */
+       { }     /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, rhine_pci_tbl);
 
@@ -421,8 +408,10 @@ enum register_offsets {
        MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74,
        ConfigA=0x78, ConfigB=0x79, ConfigC=0x7A, ConfigD=0x7B,
        RxMissed=0x7C, RxCRCErrs=0x7E, MiscCmd=0x81,
-       StickyHW=0x83, IntrStatus2=0x84, WOLcrClr=0xA4, WOLcgClr=0xA7,
-       PwrcsrClr=0xAC,
+       StickyHW=0x83, IntrStatus2=0x84,
+       WOLcrSet=0xA0, WOLcrClr=0xA4, WOLcrClr1=0xA6,
+       WOLcgClr=0xA7,
+       PwrcsrSet=0xA8, PwrcsrSet1=0xA9, PwrcsrClr=0xAC, PwrcsrClr1=0xAD,
 };
 
 /* Bits in ConfigD */
@@ -514,7 +503,7 @@ struct rhine_private {
        spinlock_t lock;
 
        /* Frequently used values: keep some adjacent for cache effect. */
-       int chip_id, drv_flags;
+       u32 quirks;
        struct rx_desc *rx_head_desc;
        unsigned int cur_rx, dirty_rx;  /* Producer/consumer ring indices */
        unsigned int cur_tx, dirty_tx;
@@ -522,7 +511,6 @@ struct rhine_private {
        u16 chip_cmd;                   /* Current setting for ChipCmd */
 
        /* These values are keep track of the transceiver/media in use. */
-       unsigned int default_port:4;    /* Last dev->if_port value. */
        u8 tx_thresh, rx_thresh;
 
        /* MII transceiver section. */
@@ -557,12 +545,41 @@ static inline u32 get_intr_status(struct net_device *dev)
 
        intr_status = readw(ioaddr + IntrStatus);
        /* On Rhine-II, Bit 3 indicates Tx descriptor write-back race. */
-       if (rp->chip_id == VT6102)
+       if (rp->quirks & rqStatusWBRace)
                intr_status |= readb(ioaddr + IntrStatus2) << 16;
        return intr_status;
 }
 
-static void wait_for_reset(struct net_device *dev, int chip_id, char *name)
+/*
+ * Get power related registers into sane state.
+ * Returns content of power-event (WOL) registers.
+ */
+static void rhine_power_init(struct net_device *dev)
+{
+       long ioaddr = dev->base_addr;
+       struct rhine_private *rp = netdev_priv(dev);
+
+       if (rp->quirks & rqWOL) {
+               /* Make sure chip is in power state D0 */
+               writeb(readb(ioaddr + StickyHW) & 0xFC, ioaddr + StickyHW);
+
+               /* Disable "force PME-enable" */
+               writeb(0x80, ioaddr + WOLcgClr);
+
+               /* Clear power-event config bits (WOL) */
+               writeb(0xFF, ioaddr + WOLcrClr);
+               /* More recent cards can manage two additional patterns */
+               if (rp->quirks & rq6patterns)
+                       writeb(0x03, ioaddr + WOLcrClr1);
+
+               /* Clear power-event status bits */
+               writeb(0xFF, ioaddr + PwrcsrClr);
+               if (rp->quirks & rq6patterns)
+                       writeb(0x03, ioaddr + PwrcsrClr1);
+       }
+}
+
+static void wait_for_reset(struct net_device *dev, u32 quirks, char *name)
 {
        long ioaddr = dev->base_addr;
        int boguscnt = 20;
@@ -574,7 +591,7 @@ static void wait_for_reset(struct net_device *dev, int chip_id, char *name)
                        "Trying harder.\n", name);
 
                /* Rhine-II needs to be forced sometimes */
-               if (chip_id == VT6102)
+               if (quirks & rqForceReset)
                        writeb(0x40, ioaddr + MiscCmd);
 
                /* VT86C100A may need long delay after reset (dlink) */
@@ -590,10 +607,10 @@ static void wait_for_reset(struct net_device *dev, int chip_id, char *name)
 }
 
 #ifdef USE_MMIO
-static void __devinit enable_mmio(long ioaddr, int chip_id)
+static void __devinit enable_mmio(long ioaddr, u32 quirks)
 {
        int n;
-       if (chip_id == VT86C100A) {
+       if (quirks & rqRhineI) {
                /* More recent docs say that this bit is reserved ... */
                n = inb(ioaddr + ConfigA) | 0x20;
                outb(n, ioaddr + ConfigA);
@@ -628,16 +645,18 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
 {
        struct net_device *dev;
        struct rhine_private *rp;
-       int i, option;
-       int chip_id = (int) ent->driver_data;
+       int i, option, rc;
+       u8 pci_rev;
+       u32 quirks;
        static int card_idx = -1;
        long ioaddr;
        long memaddr;
        int io_size;
-       int pci_flags;
+       int phy, phy_idx = 0;
 #ifdef USE_MMIO
        long ioaddr0;
 #endif
+       const char *name;
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -648,14 +667,34 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
 
        card_idx++;
        option = card_idx < MAX_UNITS ? options[card_idx] : 0;
-       io_size = rhine_chip_info[chip_id].io_size;
-       pci_flags = rhine_chip_info[chip_id].pci_flags;
+       pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
 
-       if (pci_enable_device(pdev))
+       io_size = 256;
+       if (pci_rev < VT6102) {
+               quirks = rqRhineI | rqDavicomPhy;
+               io_size = 128;
+               name = "VT86C100A Rhine";
+       }
+       else {
+               quirks = rqWOL | rqForceReset;
+               if (pci_rev < VT6105) {
+                       name = "Rhine II";
+                       quirks |= rqStatusWBRace;       /* Rhine-II exclusive */
+               }
+               else {
+                       name = "Rhine III";
+                       if (pci_rev >= VT6105_B0)
+                               quirks |= rq6patterns;
+               }
+       }
+
+       rc = pci_enable_device(pdev);
+       if (rc)
                goto err_out;
 
        /* this should always be supported */
-       if (pci_set_dma_mask(pdev, 0xffffffff)) {
+       rc = pci_set_dma_mask(pdev, 0xffffffff);
+       if (rc) {
                printk(KERN_ERR "32-bit PCI DMA addresses not supported by "
                       "the card!?\n");
                goto err_out;
@@ -664,6 +703,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
        /* sanity check */
        if ((pci_resource_len(pdev, 0) < io_size) ||
            (pci_resource_len(pdev, 1) < io_size)) {
+               rc = -EIO;
                printk(KERN_ERR "Insufficient PCI resources, aborting\n");
                goto err_out;
        }
@@ -671,11 +711,11 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
        ioaddr = pci_resource_start(pdev, 0);
        memaddr = pci_resource_start(pdev, 1);
 
-       if (pci_flags & PCI_USES_MASTER)
-               pci_set_master(pdev);
+       pci_set_master(pdev);
 
        dev = alloc_etherdev(sizeof(*rp));
        if (dev == NULL) {
+               rc = -ENOMEM;
                printk(KERN_ERR "init_ethernet failed for card #%d\n",
                       card_idx);
                goto err_out;
@@ -683,15 +723,17 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
        SET_MODULE_OWNER(dev);
        SET_NETDEV_DEV(dev, &pdev->dev);
 
-       if (pci_request_regions(pdev, shortname))
+       rc = pci_request_regions(pdev, shortname);
+       if (rc)
                goto err_out_free_netdev;
 
 #ifdef USE_MMIO
        ioaddr0 = ioaddr;
-       enable_mmio(ioaddr0, chip_id);
+       enable_mmio(ioaddr0, quirks);
 
        ioaddr = (long) ioremap(memaddr, io_size);
        if (!ioaddr) {
+               rc = -EIO;
                printk(KERN_ERR "ioremap failed for device %s, region 0x%X "
                       "@ 0x%lX\n", pci_name(pdev), io_size, memaddr);
                goto err_out_free_res;
@@ -704,36 +746,21 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
                unsigned char a = inb(ioaddr0+reg);
                unsigned char b = readb(ioaddr+reg);
                if (a != b) {
+                       rc = -EIO;
                        printk(KERN_ERR "MMIO do not match PIO [%02x] "
                               "(%02x != %02x)\n", reg, a, b);
                        goto err_out_unmap;
                }
        }
 #endif /* USE_MMIO */
+       dev->base_addr = ioaddr;
 
-       /* D-Link provided reset code (with comment additions) */
-       if (rhine_chip_info[chip_id].drv_flags & HasWOL) {
-               unsigned char byOrgValue;
-
-               /* clear sticky bit before reset & read ethernet address */
-               byOrgValue = readb(ioaddr + StickyHW);
-               byOrgValue = byOrgValue & 0xFC;
-               writeb(byOrgValue, ioaddr + StickyHW);
-
-               /* (bits written are cleared?) */
-               /* disable force PME-enable */
-               writeb(0x80, ioaddr + WOLcgClr);
-               /* disable power-event config bit */
-               writeb(0xFF, ioaddr + WOLcrClr);
-               /* clear power status (undocumented in vt6102 docs?) */
-               writeb(0xFF, ioaddr + PwrcsrClr);
-       }
+       rhine_power_init(dev);
 
        /* Reset the chip to erase previous misconfiguration. */
        writew(CmdReset, ioaddr + ChipCmd);
 
-       dev->base_addr = ioaddr;
-       wait_for_reset(dev, chip_id, shortname);
+       wait_for_reset(dev, quirks, shortname);
 
        /* Reload the station address from the EEPROM. */
 #ifdef USE_MMIO
@@ -741,7 +768,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
        /* Reloading from eeprom overwrites cfgA-D, so we must re-enable MMIO.
           If reload_eeprom() was done first this could be avoided, but it is
           not known if that still works with the "win98-reboot" problem. */
-       enable_mmio(ioaddr0, chip_id);
+       enable_mmio(ioaddr0, quirks);
 #else
        reload_eeprom(ioaddr);
 #endif
@@ -750,11 +777,12 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
                dev->dev_addr[i] = readb(ioaddr + StationAddr + i);
 
        if (!is_valid_ether_addr(dev->dev_addr)) {
+               rc = -EIO;
                printk(KERN_ERR "Invalid MAC address for card #%d\n", card_idx);
                goto err_out_unmap;
        }
 
-       if (chip_id == VT6102) {
+       if (quirks & rqWOL) {
                /*
                 * for 3065D, EEPROM reloaded will cause bit 0 in MAC_REG_CFGA
                 * turned on. it makes MAC receive magic packet
@@ -772,9 +800,8 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
 
        rp = netdev_priv(dev);
        spin_lock_init(&rp->lock);
-       rp->chip_id = chip_id;
-       rp->drv_flags = rhine_chip_info[chip_id].drv_flags;
        rp->pdev = pdev;
+       rp->quirks = quirks;
        rp->mii_if.dev = dev;
        rp->mii_if.mdio_read = mdio_read;
        rp->mii_if.mdio_write = mdio_write;
@@ -797,19 +824,18 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        dev->poll_controller = rhine_poll;
 #endif
-       if (rp->drv_flags & ReqTxAlign)
+       if (rp->quirks & rqRhineI)
                dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
 
        /* dev->name not defined before register_netdev()! */
-       i = register_netdev(dev);
-       if (i)
+       rc = register_netdev(dev);
+       if (rc)
                goto err_out_unmap;
 
        /* The lower four bits are the media type. */
        if (option > 0) {
                if (option & 0x220)
                        rp->mii_if.full_duplex = 1;
-               rp->default_port = option & 15;
        }
        if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
                rp->mii_if.full_duplex = 1;
@@ -820,9 +846,14 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
                rp->mii_if.force_media = 1;
        }
 
-       printk(KERN_INFO "%s: %s at 0x%lx, ",
-              dev->name, rhine_chip_info[chip_id].name,
-              (pci_flags & PCI_USES_IO) ? ioaddr : memaddr);
+       printk(KERN_INFO "%s: VIA %s at 0x%lx, ",
+              dev->name, name,
+#ifdef USE_MMIO
+               memaddr
+#else
+               ioaddr
+#endif
+                );
 
        for (i = 0; i < 5; i++)
                printk("%2.2x:", dev->dev_addr[i]);
@@ -830,41 +861,35 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
 
        pci_set_drvdata(pdev, dev);
 
-       if (rp->drv_flags & CanHaveMII) {
-               int phy, phy_idx = 0;
-               rp->phys[0] = 1;                /* Standard for this chip. */
-               for (phy = 1; phy < 32 && phy_idx < MAX_MII_CNT; phy++) {
-                       int mii_status = mdio_read(dev, phy, 1);
-                       if (mii_status != 0xffff && mii_status != 0x0000) {
-                               rp->phys[phy_idx++] = phy;
-                               rp->mii_if.advertising = mdio_read(dev, phy, 4);
-                               printk(KERN_INFO "%s: MII PHY found at address "
-                                      "%d, status 0x%4.4x advertising %4.4x "
-                                      "Link %4.4x.\n", dev->name, phy,
-                                      mii_status, rp->mii_if.advertising,
-                                      mdio_read(dev, phy, 5));
-
-                               /* set IFF_RUNNING */
-                               if (mii_status & BMSR_LSTATUS)
-                                       netif_carrier_on(dev);
-                               else
-                                       netif_carrier_off(dev);
-
-                               break;
-                       }
+       rp->phys[0] = 1;                /* Standard for this chip. */
+       for (phy = 1; phy < 32 && phy_idx < MAX_MII_CNT; phy++) {
+               int mii_status = mdio_read(dev, phy, 1);
+               if (mii_status != 0xffff && mii_status != 0x0000) {
+                       rp->phys[phy_idx++] = phy;
+                       rp->mii_if.advertising = mdio_read(dev, phy, 4);
+                       printk(KERN_INFO "%s: MII PHY found at address "
+                              "%d, status 0x%4.4x advertising %4.4x "
+                              "Link %4.4x.\n", dev->name, phy,
+                              mii_status, rp->mii_if.advertising,
+                              mdio_read(dev, phy, 5));
+
+                       /* set IFF_RUNNING */
+                       if (mii_status & BMSR_LSTATUS)
+                               netif_carrier_on(dev);
+                       else
+                               netif_carrier_off(dev);
+
+                       break;
                }
-               rp->mii_cnt = phy_idx;
-               rp->mii_if.phy_id = rp->phys[0];
        }
+       rp->mii_cnt = phy_idx;
+       rp->mii_if.phy_id = rp->phys[0];
 
        /* Allow forcing the media type. */
        if (option > 0) {
                if (option & 0x220)
                        rp->mii_if.full_duplex = 1;
-               rp->default_port = option & 0x3ff;
                if (option & 0x330) {
-                       /* FIXME: shouldn't someone check this variable? */
-                       /* rp->medialock = 1; */
                        printk(KERN_INFO " Forcing %dMbs %s-duplex "
                                "operation.\n",
                               (option & 0x300 ? 100 : 10),
@@ -887,7 +912,7 @@ err_out_free_res:
 err_out_free_netdev:
        free_netdev(dev);
 err_out:
-       return -ENODEV;
+       return rc;
 }
 
 static int alloc_ring(struct net_device* dev)
@@ -904,7 +929,7 @@ static int alloc_ring(struct net_device* dev)
                printk(KERN_ERR "Could not allocate DMA memory.\n");
                return -ENOMEM;
        }
-       if (rp->drv_flags & ReqTxAlign) {
+       if (rp->quirks & rqRhineI) {
                rp->tx_bufs = pci_alloc_consistent(rp->pdev,
                                                   PKT_BUF_SZ * TX_RING_SIZE,
                                                   &rp->tx_bufs_dma);
@@ -1063,9 +1088,6 @@ static void init_registers(struct net_device *dev)
        rp->rx_thresh = 0x60;           /* Written in rhine_set_rx_mode(). */
        rp->mii_if.full_duplex = 0;
 
-       if (dev->if_port == 0)
-               dev->if_port = rp->default_port;
-
        writel(rp->rx_ring_dma, ioaddr + RxRingPtr);
        writel(rp->tx_ring_dma, ioaddr + TxRingPtr);
 
@@ -1087,9 +1109,8 @@ static void init_registers(struct net_device *dev)
 
        /* The LED outputs of various MII xcvrs should be configured. */
        /* For NS or Mison phys, turn on bit 1 in register 0x17 */
-       /* For ESI phys, turn on bit 7 in register 0x17. */
        mdio_write(dev, rp->phys[0], 0x17, mdio_read(dev, rp->phys[0], 0x17) |
-                  (rp->drv_flags & HasESIPhy) ? 0x0080 : 0x0001);
+                  0x0001);
 }
 
 /* Read and write over the MII Management Data I/O (MDIO) interface. */
@@ -1166,7 +1187,7 @@ static int rhine_open(struct net_device *dev)
                return i;
        alloc_rbufs(dev);
        alloc_tbufs(dev);
-       wait_for_reset(dev, rp->chip_id, dev->name);
+       wait_for_reset(dev, rp->quirks, dev->name);
        init_registers(dev);
        if (debug > 2)
                printk(KERN_DEBUG "%s: Done rhine_open(), status %4.4x "
@@ -1257,8 +1278,6 @@ static void rhine_tx_timeout(struct net_device *dev)
               dev->name, readw(ioaddr + IntrStatus),
               mdio_read(dev, rp->phys[0], MII_BMSR));
 
-       dev->if_port = 0;
-
        /* protect against concurrent rx interrupts */
        disable_irq(rp->pdev->irq);
 
@@ -1274,7 +1293,7 @@ static void rhine_tx_timeout(struct net_device *dev)
        alloc_rbufs(dev);
 
        /* Reinitialize the hardware. */
-       wait_for_reset(dev, rp->chip_id, dev->name);
+       wait_for_reset(dev, rp->quirks, dev->name);
        init_registers(dev);
 
        spin_unlock(&rp->lock);
@@ -1305,7 +1324,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
 
        rp->tx_skbuff[entry] = skb;
 
-       if ((rp->drv_flags & ReqTxAlign) &&
+       if ((rp->quirks & rqRhineI) &&
            (((long)skb->data & 3) || skb_shinfo(skb)->nr_frags != 0 || skb->ip_summed == CHECKSUM_HW)) {
                /* Must use alignment buffer. */
                if (skb->len > PKT_BUF_SZ) {
@@ -1454,7 +1473,7 @@ static void rhine_tx(struct net_device *dev)
                        if (txstatus & 0x0200) rp->stats.tx_window_errors++;
                        if (txstatus & 0x0100) rp->stats.tx_aborted_errors++;
                        if (txstatus & 0x0080) rp->stats.tx_heartbeat_errors++;
-                       if (((rp->chip_id == VT86C100A) && txstatus & 0x0002) ||
+                       if (((rp->quirks & rqRhineI) && txstatus & 0x0002) ||
                            (txstatus & 0x0800) || (txstatus & 0x1000)) {
                                rp->stats.tx_fifo_errors++;
                                rp->tx_ring[entry].tx_status = cpu_to_le32(DescOwn);
@@ -1462,7 +1481,7 @@ static void rhine_tx(struct net_device *dev)
                        }
                        /* Transmitter restarted in 'abnormal' handler. */
                } else {
-                       if (rp->chip_id == VT86C100A)
+                       if (rp->quirks & rqRhineI)
                                rp->stats.collisions += (txstatus >> 3) & 0x0F;
                        else
                                rp->stats.collisions += txstatus & 0x0F;
@@ -1563,15 +1582,10 @@ static void rhine_rx(struct net_device *dev)
                                   eth_copy_and_sum is memcpy for all archs so
                                   this is kind of pointless right now
                                   ... or? */
-#if HAS_IP_COPYSUM             /* Call copy + cksum if available. */
                                eth_copy_and_sum(skb,
                                                 rp->rx_skbuff[entry]->tail,
                                                 pkt_len, 0);
                                skb_put(skb, pkt_len);
-#else
-                               memcpy(skb_put(skb, pkt_len),
-                                      rp->rx_skbuff[entry]->tail, pkt_len);
-#endif
                                pci_dma_sync_single_for_device(rp->pdev,
                                                               rp->rx_skbuff_dma[entry],
                                                               rp->rx_buf_sz,
@@ -1679,7 +1693,7 @@ static void rhine_error(struct net_device *dev, int intr_status)
        if (intr_status & (IntrLinkChange)) {
                if (readb(ioaddr + MIIStatus) & 0x02) {
                        /* Link failed, restart autonegotiation. */
-                       if (rp->drv_flags & HasDavicomPhy)
+                       if (rp->quirks & rqRhineI)
                                mdio_write(dev, rp->phys[0], MII_BMCR, 0x3300);
                } else
                        rhine_check_duplex(dev);
@@ -1805,9 +1819,6 @@ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        struct rhine_private *rp = netdev_priv(dev);
        int rc;
 
-       if (!(rp->drv_flags & CanHaveMII))
-               return -EINVAL;
-
        spin_lock_irq(&rp->lock);
        rc = mii_ethtool_gset(&rp->mii_if, cmd);
        spin_unlock_irq(&rp->lock);
@@ -1820,9 +1831,6 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        struct rhine_private *rp = netdev_priv(dev);
        int rc;
 
-       if (!(rp->drv_flags & CanHaveMII))
-               return -EINVAL;
-
        spin_lock_irq(&rp->lock);
        rc = mii_ethtool_sset(&rp->mii_if, cmd);
        spin_unlock_irq(&rp->lock);
@@ -1834,9 +1842,6 @@ static int netdev_nway_reset(struct net_device *dev)
 {
        struct rhine_private *rp = netdev_priv(dev);
 
-       if (!(rp->drv_flags & CanHaveMII))
-               return -EINVAL;
-
        return mii_nway_restart(&rp->mii_if);
 }
 
@@ -1844,9 +1849,6 @@ static u32 netdev_get_link(struct net_device *dev)
 {
        struct rhine_private *rp = netdev_priv(dev);
 
-       if (!(rp->drv_flags & CanHaveMII))
-               return 0;       /* -EINVAL */
-
        return mii_link_ok(&rp->mii_if);
 }
 
@@ -1875,14 +1877,13 @@ static struct ethtool_ops netdev_ethtool_ops = {
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct rhine_private *rp = netdev_priv(dev);
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
        int rc;
 
        if (!netif_running(dev))
                return -EINVAL;
 
        spin_lock_irq(&rp->lock);
-       rc = generic_mii_ioctl(&rp->mii_if, data, cmd, NULL);
+       rc = generic_mii_ioctl(&rp->mii_if, if_mii(rq), cmd, NULL);
        spin_unlock_irq(&rp->lock);
 
        return rc;
index 82798fd..bad0d41 100644 (file)
@@ -229,7 +229,7 @@ static int dlci_transmit(struct sk_buff *skb, struct net_device *dev)
        return(ret);
 }
 
-static int dlci_config(struct net_device *dev, struct dlci_conf *conf, int get)
+static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, int get)
 {
        struct dlci_conf        config;
        struct dlci_local       *dlp;
@@ -286,7 +286,7 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                        if (!*(short *)(dev->dev_addr))
                                return(-EINVAL);
 
-                       return(dlci_config(dev, (struct dlci_conf *) ifr->ifr_data, cmd == DLCI_GET_CONF));
+                       return(dlci_config(dev, ifr->ifr_data, cmd == DLCI_GET_CONF));
                        break;
 
                default: 
@@ -454,7 +454,7 @@ static int dlci_del(struct dlci_add *dlci)
        return(err);
 }
 
-static int dlci_ioctl(unsigned int cmd, void *arg)
+static int dlci_ioctl(unsigned int cmd, void __user *arg)
 {
        struct dlci_add add;
        int err;
index 05aa310..29b8268 100644 (file)
@@ -2542,7 +2542,7 @@ int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        pc300conf_t conf_aux;
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
        int ch = chan->channel;
-       void *arg = (void *) ifr->ifr_data;
+       void __user *arg = ifr->ifr_data;
        struct if_settings *settings = &ifr->ifr_settings;
        uclong scabase = card->hw.scabase;
 
index e61774a..311ac34 100644 (file)
@@ -1342,7 +1342,7 @@ sbni_ioctl( struct net_device  *dev,  struct ifreq  *ifr,  int  cmd )
                        return  -EPERM;
 
                spin_lock( &nl->lock );
-               flags = *(struct sbni_flags*) &ifr->ifr_data;
+               flags = *(struct sbni_flags*) &ifr->ifr_ifru;
                if( flags.fixed_rxl )
                        nl->delta_rxl = 0,
                        nl->cur_rxl_index = flags.rxl;
index 0abba0f..1259818 100644 (file)
@@ -1095,7 +1095,7 @@ static int sdla_open(struct net_device *dev)
        return(0);
 }
 
-static int sdla_config(struct net_device *dev, struct frad_conf *conf, int get)
+static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, int get)
 {
        struct frad_local *flp;
        struct conf_data  data;
@@ -1193,7 +1193,7 @@ static int sdla_config(struct net_device *dev, struct frad_conf *conf, int get)
        return(0);
 }
 
-static int sdla_xfer(struct net_device *dev, struct sdla_mem *info, int read)
+static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int read)
 {
        struct sdla_mem mem;
        char    *temp;
@@ -1271,7 +1271,7 @@ static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        {
                case FRAD_GET_CONF:
                case FRAD_SET_CONF:
-                       return(sdla_config(dev, (struct frad_conf *)ifr->ifr_data, cmd == FRAD_GET_CONF));
+                       return(sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF));
 
                case SDLA_IDENTIFY:
                        ifr->ifr_flags = flp->type;
@@ -1306,7 +1306,7 @@ NOTE:  This is rather a useless action right now, as the
 
                case SDLA_WRITEMEM:
                case SDLA_READMEM:
-                       return(sdla_xfer(dev, (struct sdla_mem *)ifr->ifr_data, cmd == SDLA_READMEM));
+                       return(sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM));
 
                case SDLA_START:
                        sdla_start(dev);
index e3fe0a7..1f7a27c 100644 (file)
@@ -43,6 +43,8 @@ static const char version[] =
 
 #include "8390.h"
 
+#define DRV_NAME "wd"
+
 /* A zero-terminated list of I/O addresses to be probed. */
 static unsigned int wd_portlist[] __initdata =
 {0x300, 0x280, 0x380, 0x240, 0};
@@ -131,6 +133,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT);
 }
 
+#ifndef MODULE
 struct net_device * __init wd_probe(int unit)
 {
        struct net_device *dev = alloc_ei_netdev();
@@ -155,6 +158,7 @@ out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init wd_probe1(struct net_device *dev, int ioaddr)
 {
@@ -300,7 +304,7 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
 
        /* Snarf the interrupt now.  There's no point in waiting since we cannot
           share and the board will usually be enabled. */
-       i = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
+       i = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
        if (i) {
                printk (" unable to get IRQ %d.\n", dev->irq);
                return i;
index c9f0e0c..40231b6 100644 (file)
@@ -861,9 +861,7 @@ typedef struct {
 #define AIROGMICRID            11
 #define AIROGMICSTATS          12
 #define AIROGFLAGS             13
-#define AIROGID                        14
 #define AIRORRID               15
-#define AIRORSWVERSION         17
 
 /* Leave gap of 40 commands after AIROGSTATSD32 for future */
 
@@ -894,13 +892,10 @@ typedef struct {
 #define AUXMEMSIZE     (256 * 1024)
 
 typedef struct aironet_ioctl {
-       unsigned short command;         // What to do
+       unsigned short command; // What to do
        unsigned short len;             // Len of data
-       unsigned short ridnum;          // rid number
        unsigned char *data;            // d-data
 } aironet_ioctl;
-
-static char *swversion = "2.1";
 #endif /* CISCO_EXT */
 
 #define NUM_MODULES       2
@@ -1102,7 +1097,6 @@ static int transmit_802_11_packet(struct airo_info*, int len, char *pPacket);
 static int mpi_send_packet (struct net_device *dev);
 static void mpi_unmap_card(struct pci_dev *pci);
 static void mpi_receive_802_3(struct airo_info *ai);
-static void mpi_receive_802_11(struct airo_info *ai);
 static int waitbusy (struct airo_info *ai);
 
 static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs
@@ -2457,19 +2451,17 @@ static int mpi_init_descriptors (struct airo_info *ai)
        cmd.parm0 = FID_TX;
        cmd.parm1 = (ai->txfids[0].card_ram_off - ai->pciaux);
        cmd.parm2 = MPI_MAX_FIDS;
+       rc=issuecommand(ai, &cmd, &rsp);
+       if (rc != SUCCESS) {
+               printk(KERN_ERR "airo:  Couldn't allocate TX FID\n");
+               return rc;
+       }
 
        for (i=0; i<MPI_MAX_FIDS; i++) {
                ai->txfids[i].tx_desc.valid = 1;
                memcpy((char *)ai->txfids[i].card_ram_off,
                        &ai->txfids[i].tx_desc, sizeof(TxFid));
        }
-       ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
-
-       rc=issuecommand(ai, &cmd, &rsp);
-       if (rc != SUCCESS) {
-               printk(KERN_ERR "airo:  Couldn't allocate TX FID\n");
-               return rc;
-       }
 
        /* Alloc card Rid descriptor */
        memset(&rsp,0,sizeof(rsp));
@@ -2661,7 +2653,7 @@ static struct net_device *init_wifidev(struct airo_info *ai,
        return dev;
 }
 
-int reset_card( struct net_device *dev , int lock) {
+int reset_mpi_card( struct net_device *dev , int lock) {
        struct airo_info *ai = dev->priv;
 
        if (lock && down_interruptible(&ai->sem))
@@ -2745,6 +2737,9 @@ struct net_device *_init_airo_card( unsigned short irq, int port,
                SET_NETDEV_DEV(dev, &pci->dev);
        }
 
+       if (test_bit(FLAG_MPI,&ai->flags))
+               reset_mpi_card (dev, 1);
+
        rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev );
        if (rc) {
                printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc );
@@ -2781,7 +2776,8 @@ struct net_device *_init_airo_card( unsigned short irq, int port,
                printk(KERN_ERR "airo: Couldn't register_netdev\n");
                goto err_out_map;
        }
-       ai->wifidev = init_wifidev(ai, dev);
+       if (!test_bit(FLAG_MPI,&ai->flags))
+               ai->wifidev = init_wifidev(ai, dev);
 
        set_bit(FLAG_REGISTERED,&ai->flags);
        printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
@@ -2844,7 +2840,7 @@ int reset_airo_card( struct net_device *dev )
        int i;
        struct airo_info *ai = dev->priv;
 
-       if (reset_card (dev, 1))
+       if (reset_mpi_card (dev, 1))
                return -1;
 
        if ( setup_card(ai, dev->dev_addr, 1 ) != SUCCESS ) {
@@ -3105,10 +3101,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
                        u16 *buffer;
 
                        if (test_bit(FLAG_MPI,&apriv->flags)) {
-                               if (test_bit(FLAG_802_11, &apriv->flags))
-                                       mpi_receive_802_11(apriv);
-                               else
-                                       mpi_receive_802_3(apriv);
+                               mpi_receive_802_3(apriv);
                                OUT4500(apriv, EVACK, EV_RX);
                                goto exitrx;
                        }
@@ -3490,112 +3483,6 @@ badrx:
        }
 }
 
-void mpi_receive_802_11 (struct airo_info *ai)
-{
-       RxFid rxd;
-       struct sk_buff *skb = NULL;
-       u16 fc, len, hdrlen = 0;
-#pragma pack(1)
-       struct {
-               u16 status, len;
-               u8 rssi[2];
-               u8 rate;
-               u8 freq;
-               u16 tmp[4];
-       } hdr;
-#pragma pack()
-       u16 gap;
-       u16 *buffer;
-       char *ptr = ai->rxfids[0].virtual_host_addr+4;
-
-       memcpy ((char *)&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
-       memcpy ((char *)&hdr, ptr, sizeof(hdr));
-       ptr += sizeof(hdr);
-       /* Bad CRC. Ignore packet */
-       if (le16_to_cpu(hdr.status) & 2)
-               hdr.len = 0;
-       if (ai->wifidev == NULL)
-               hdr.len = 0;
-       len = le16_to_cpu(hdr.len);
-       if (len > 2312) {
-               printk( KERN_ERR "airo: Bad size %d\n", len );
-               goto badrx;
-       }
-       if (len == 0)
-               goto badrx;
-
-       memcpy ((char *)&fc, ptr, sizeof(fc));
-       fc = le16_to_cpu(fc);
-       switch (fc & 0xc) {
-               case 4:
-                       if ((fc & 0xe0) == 0xc0)
-                               hdrlen = 10;
-                       else
-                               hdrlen = 16;
-                       break;
-               case 8:
-                       if ((fc&0x300)==0x300){
-                               hdrlen = 30;
-                               break;
-                       }
-               default:
-                       hdrlen = 24;
-       }
-
-       skb = dev_alloc_skb( len + hdrlen + 2 );
-       if ( !skb ) {
-               ai->stats.rx_dropped++;
-               goto badrx;
-       }
-       buffer = (u16*)skb_put (skb, len + hdrlen);
-       memcpy ((char *)buffer, ptr, hdrlen);
-       ptr += hdrlen;
-       if (hdrlen == 24)
-               ptr += 6;
-       memcpy ((char *)&gap, ptr, sizeof(gap));
-       ptr += sizeof(gap);
-       gap = le16_to_cpu(gap);
-       if (gap) {
-               if (gap <= 8)
-                       ptr += gap;
-               else
-                       printk(KERN_ERR
-                           "airo: gaplen too big. Problems will follow...\n");
-       }
-       memcpy ((char *)buffer + hdrlen, ptr, len);
-       ptr += len;
-#ifdef IW_WIRELESS_SPY   /* defined in iw_handler.h */
-       if (ai->spy_data.spy_number > 0) {
-               char *sa;
-               struct iw_quality wstats;
-               /* Prepare spy data : addr + qual */
-               sa = (char*)buffer + 10;
-               wstats.qual = hdr.rssi[0];
-               if (ai->rssi)
-                       wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
-               else
-                       wstats.level = (hdr.rssi[1] + 321) / 2;
-               wstats.updated = 3;
-               /* Update spy records */
-               wireless_spy_update(ai->dev, sa, &wstats);
-       }
-#endif /* IW_WIRELESS_SPY */
-       skb->mac.raw = skb->data;
-       skb->pkt_type = PACKET_OTHERHOST;
-       skb->dev = ai->wifidev;
-       skb->protocol = htons(ETH_P_802_2);
-       skb->dev->last_rx = jiffies;
-       skb->ip_summed = CHECKSUM_NONE;
-       netif_rx( skb );
-badrx:
-       if (rxd.valid == 0) {
-               rxd.valid = 1;
-               rxd.rdy = 0;
-               rxd.len = PKTSIZE;
-               memcpy (ai->rxfids[0].card_ram_off, (char *)&rxd, sizeof(rxd));
-       }
-}
-
 static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
 {
        Cmd cmd;
@@ -3663,16 +3550,10 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
                status = readCapabilityRid(ai, &cap_rid, lock);
                if ( status != SUCCESS ) return ERROR;
 
-               /*
-                * This driver supports MPI350 firmwares up to, and
-                * including 5.30.17
-                */
                if (test_bit(FLAG_MPI, &ai->flags) &&
-                   strncmp (cap_rid.prodVer, "5.00.", 5) &&
-                   strncmp (cap_rid.prodVer, "5b00.", 5) &&
-                   strncmp (cap_rid.prodVer, "5.02.", 5) &&
-                   strncmp (cap_rid.prodVer, "5.20.", 5) &&
-                   strncmp (cap_rid.prodVer, "5.30.", 5))
+                   strcmp (cap_rid.prodVer, "5.00.01") &&
+                   strcmp (cap_rid.prodVer, "5.00.03") &&
+                   strcmp (cap_rid.prodVer, "5b00.08"))
                        printk(KERN_ERR "airo: Firmware version %s is not supported. Use it at your own risk!\n", cap_rid.prodVer);
 
                status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
@@ -4053,7 +3934,7 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid,
                memset(&rsp, 0, sizeof(rsp));
 
                ai->config_desc.rid_desc.valid = 1;
-               ai->config_desc.rid_desc.len = *((u16 *)pBuf);
+               ai->config_desc.rid_desc.len = RIDSIZE;
                ai->config_desc.rid_desc.rid = 0;
 
                cmd.cmd = CMD_WRITERID;
@@ -5497,6 +5378,7 @@ static int airo_pci_resume(struct pci_dev *pdev)
        struct net_device *dev = pci_get_drvdata(pdev);
        struct airo_info *ai = dev->priv;
        Resp rsp;
+       int err;
 
        printk(KERN_DEBUG "%s: airo_mpi waking up\n", dev->name);
 
@@ -5504,6 +5386,13 @@ static int airo_pci_resume(struct pci_dev *pdev)
                return 0;
 
        if (ai->power > 1) {
+               err = reset_mpi_card(dev, 0);
+               if (err) {
+                       printk(KERN_ERR "%s: Error %d resetting on %s()\n",
+                              dev->name, err, __FUNCTION__);
+                       return err;
+               }
+               schedule_timeout (HZ/2);
                mpi_init_descriptors(ai);
                setup_card(ai, dev->dev_addr, 0);
                clear_bit(FLAG_RADIO_OFF, &ai->flags);
@@ -6897,10 +6786,7 @@ static int airo_config_commit(struct net_device *dev,
 
                readAPListRid(local, &APList_rid);
                readSsidRid(local, &SSID_rid);
-               if (test_bit(FLAG_MPI,&local->flags))
-                       setup_card(local, dev->dev_addr, 1 );
-               else
-                       reset_airo_card(dev);
+               reset_airo_card(dev);
                disable_MAC(local, 1);
                writeSsidRid(local, &SSID_rid, 1);
                writeAPListRid(local, &APList_rid, 1);
@@ -7060,15 +6946,9 @@ static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
                /* Separate R/W functions bracket legality here
                 */
-               if ( com.command == AIRORSWVERSION ) {
-                       if (copy_to_user(com.data, swversion, sizeof(swversion)))
-                               rc = -EFAULT;
-                       else
-                               rc = 0;
-               }
-               else if ( com.command <= AIRORRID)
+               if ( com.command <= AIRORRID )
                        rc = readrids(dev,&com);
-               else if ( com.command >= AIROPCAP && com.command <= (AIROPLEAPUSR+2) )
+               else if ( com.command >= AIROPCAP && com.command <= AIROPLEAPUSR )
                        rc = writerids(dev,&com);
                else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
                        rc = flashcard(dev,&com);
@@ -7198,7 +7078,7 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) {
                        return -EFAULT;
                return 0;
 #endif
-       case AIRORRID:      ridcode = comp->ridnum;     break;
+       case AIRORRID:      ridcode = comp->len;        break;
        default:
                return -EINVAL;
                break;
@@ -7212,7 +7092,10 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) {
         * then return it to the user
         * 9/22/2000 Honor user given length
         */
-       len = comp->len;
+       if (comp->command == AIRORRID)
+               len = le16_to_cpu(*(unsigned short *)iobuf); /* Yuck! */
+       else
+               len = comp->len;
 
        if (copy_to_user(comp->data, iobuf, min(len, (int)RIDSIZE))) {
                kfree (iobuf);
@@ -7258,8 +7141,6 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) {
        case AIROPLEAPPWD:  ridcode = RID_LEAPPASSWORD; break;
        case AIROPWEPKEY:   ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
                break;
-       case AIROPLEAPUSR+1: ridcode = 0xFF2A;          break;
-       case AIROPLEAPUSR+2: ridcode = 0xFF2B;          break;
 
                /* this is not really a rid but a command given to the card
                 * same with MAC off
index 2e669a6..dd50660 100644 (file)
 #include <linux/types.h>
 #include <linux/delay.h>
 
-#include "isl_38xx.h"
-#include <linux/firmware.h>
-
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-#include <linux/config.h>
-#if !defined(CONFIG_FW_LOADER) && !defined(CONFIG_FW_LOADER_MODULE)
-#error No Firmware Loading configured in the kernel !
-#endif
-
+#include "prismcompat.h"
+#include "isl_38xx.h"
 #include "islpci_dev.h"
 #include "islpci_mgt.h"
 
@@ -235,130 +229,6 @@ isl38xx_enable_common_interrupts(void *device_base) {
        udelay(ISL38XX_WRITEIO_DELAY);
 }
 
-int
-isl38xx_upload_firmware(char *fw_id, _REQ_FW_DEV_T dev, void *device_base,
-                       dma_addr_t host_address)
-{
-       u32 reg, rc;
-
-#if VERBOSE > SHOW_ERROR_MESSAGES
-       DEBUG(SHOW_ERROR_MESSAGES, "isl38xx_upload_firmware(0x%lx, 0x%lx)\n",
-             (long) device_base, (long) host_address);
-#endif
-
-       /* clear the RAMBoot and the Reset bit */
-       reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
-       reg &= ~ISL38XX_CTRL_STAT_RESET;
-       reg &= ~ISL38XX_CTRL_STAT_RAMBOOT;
-       writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
-       wmb();
-       udelay(ISL38XX_WRITEIO_DELAY);
-
-       /* set the Reset bit without reading the register ! */
-       reg |= ISL38XX_CTRL_STAT_RESET;
-       writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
-       wmb();
-       udelay(ISL38XX_WRITEIO_DELAY);
-
-       /* clear the Reset bit */
-       reg &= ~ISL38XX_CTRL_STAT_RESET;
-       writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
-       wmb();
-
-       /* wait a while for the device to reboot */
-       mdelay(50);
-
-       {
-               const struct firmware *fw_entry = 0;
-               long fw_len;
-               const u32 *fw_ptr;
-
-               rc = request_firmware(&fw_entry, fw_id, dev);
-               if (rc) {
-                       printk(KERN_ERR
-                              "%s: request_firmware() failed for '%s'\n",
-                              "prism54", fw_id);
-                       return rc;
-               }
-               /* prepare the Direct Memory Base register */
-               reg = ISL38XX_DEV_FIRMWARE_ADDRES;
-
-               fw_ptr = (u32 *) fw_entry->data;
-               fw_len = fw_entry->size;
-
-               if (fw_len % 4) {
-                       printk(KERN_ERR
-                              "%s: firmware '%s' size is not multiple of 32bit, aborting!\n",
-                              "prism54", fw_id);
-                       release_firmware(fw_entry);
-                       return EILSEQ; /* Illegal byte sequence  */;
-               }
-
-               while (fw_len > 0) {
-                       long _fw_len =
-                           (fw_len >
-                            ISL38XX_MEMORY_WINDOW_SIZE) ?
-                           ISL38XX_MEMORY_WINDOW_SIZE : fw_len;
-                       u32 *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN;
-
-                       /* set the cards base address for writting the data */
-                       isl38xx_w32_flush(device_base, reg,
-                                         ISL38XX_DIR_MEM_BASE_REG);
-                       wmb();  /* be paranoid */
-
-                       /* increment the write address for next iteration */
-                       reg += _fw_len;
-                       fw_len -= _fw_len;
-
-                       /* write the data to the Direct Memory Window 32bit-wise */
-                       /* memcpy_toio() doesn't guarantee 32bit writes :-| */
-                       while (_fw_len > 0) {
-                               /* use non-swapping writel() */
-                               __raw_writel(*fw_ptr, dev_fw_ptr);
-                               fw_ptr++, dev_fw_ptr++;
-                               _fw_len -= 4;
-                       }
-
-                       /* flush PCI posting */
-                       (void) readl(device_base + ISL38XX_PCI_POSTING_FLUSH);
-                       wmb();  /* be paranoid again */
-
-                       BUG_ON(_fw_len != 0);
-               }
-
-               BUG_ON(fw_len != 0);
-
-               release_firmware(fw_entry);
-       }
-
-       /* now reset the device
-        * clear the Reset & ClkRun bit, set the RAMBoot bit */
-       reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
-       reg &= ~ISL38XX_CTRL_STAT_CLKRUN;
-       reg &= ~ISL38XX_CTRL_STAT_RESET;
-       reg |= ISL38XX_CTRL_STAT_RAMBOOT;
-       isl38xx_w32_flush(device_base, reg, ISL38XX_CTRL_STAT_REG);
-       wmb();
-       udelay(ISL38XX_WRITEIO_DELAY);
-
-       /* set the reset bit latches the host override and RAMBoot bits
-        * into the device for operation when the reset bit is reset */
-       reg |= ISL38XX_CTRL_STAT_RESET;
-       writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
-       /* don't do flush PCI posting here! */
-       wmb();
-       udelay(ISL38XX_WRITEIO_DELAY);
-
-       /* clear the reset bit should start the whole circus */
-       reg &= ~ISL38XX_CTRL_STAT_RESET;
-       writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
-       /* don't do flush PCI posting here! */
-       wmb();
-       udelay(ISL38XX_WRITEIO_DELAY);
-
-       return 0;
-}
-
 int
 isl38xx_in_queue(isl38xx_control_block *cb, int queue)
 {
index 5f64483..0bd5ff6 100644 (file)
 
 #include <linux/version.h>
 #include <asm/io.h>
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,75))
-#include <linux/device.h>
-# define _REQ_FW_DEV_T struct device *
-#else
-# define _REQ_FW_DEV_T char *
-#endif
-
 #include <asm/byteorder.h>
 
 #define ISL38XX_CB_RX_QSIZE                     8
@@ -174,6 +166,4 @@ void isl38xx_handle_wakeup(isl38xx_control_block *, int *, void *);
 void isl38xx_trigger_device(int, void *);
 void isl38xx_interface_reset(void *, dma_addr_t);
 
-int isl38xx_upload_firmware(char *, _REQ_FW_DEV_T, void *, dma_addr_t);
-
 #endif                         /* _ISL_38XX_H */
index 426fc2e..dc84928 100644 (file)
 #include <linux/kernel.h>
 #include <linux/if_arp.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
 
 #include <asm/uaccess.h>
 
+#include "prismcompat.h"
 #include "isl_ioctl.h"
 #include "islpci_mgt.h"
 #include "isl_oid.h"           /* additional types and defs for isl38xx fw */
@@ -166,21 +166,13 @@ prism54_mib_init(islpci_private *priv)
         * for it save old values */
        if (init_mode > IW_MODE_MONITOR || init_mode < IW_MODE_AUTO) {
                printk(KERN_DEBUG "%s(): You passed a non-valid init_mode. "
-                               "Using default mode\n", __FUNCTION__);
+                      "Using default mode\n", __FUNCTION__);
                init_mode = CARD_DEFAULT_IW_MODE;
        }
        /* This sets all of the mode-dependent values */
        prism54_mib_mode_helper(priv, init_mode);
 }
 
-void
-prism54_mib_init_work(islpci_private *priv)
-{
-       down_write(&priv->mib_sem);
-       mgt_commit(priv);
-       up_write(&priv->mib_sem);
-}
-
 /* this will be executed outside of atomic context thanks to
  * schedule_work(), thus we can as well use sleeping semaphore
  * locking */
@@ -195,16 +187,9 @@ prism54_update_stats(islpci_private *priv)
        if (down_interruptible(&priv->stats_sem))
                return;
 
-/* missing stats are :
- *  iwstatistics.qual.updated
- *  iwstatistics.discard.nwid      
- *  iwstatistics.discard.fragment          
- *  iwstatistics.discard.misc
- *  iwstatistics.miss.beacon */
-
 /* Noise floor.
  * I'm not sure if the unit is dBm.
- * Note : If we are not connected, this value seems to be irrevelant. */
+ * Note : If we are not connected, this value seems to be irrelevant. */
 
        mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
        priv->local_iwstatistics.qual.noise = r.u;
@@ -216,8 +201,7 @@ prism54_update_stats(islpci_private *priv)
        data = r.ptr;
 
        /* copy this MAC to the bss */
-       for (j = 0; j < 6; j++)
-               bss.address[j] = data[j];
+       memcpy(bss.address, data, 6);
        kfree(data);
 
        /* now ask for the corresponding bss */
@@ -426,7 +410,6 @@ prism54_set_sens(struct net_device *ndev, struct iw_request_info *info,
        /* by default  the card sets this to 20. */
        sens = vwrq->disabled ? 20 : vwrq->value;
 
-       /* set the ed threshold. */
        return mgt_set_request(priv, DOT11_OID_EDTHRESHOLD, 0, &sens);
 }
 
@@ -505,7 +488,7 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
                return 0;
 
        /* Request the device for the supported frequencies
-        * not really revelant since some devices will report the 5 GHz band
+        * not really relevant since some devices will report the 5 GHz band
         * frequencies even if they don't support them.
         */
        rvalue =
@@ -515,21 +498,12 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
        range->num_channels = freq->nr;
        range->num_frequency = freq->nr;
 
-       /* Frequencies are not listed in the right order. The reordering is probably
-        * firmware dependant and thus should work for everyone.
-        */
        m = min(IW_MAX_FREQUENCIES, (int) freq->nr);
-       for (i = 0; i < m - 12; i++) {
-               range->freq[i].m = freq->mhz[12 + i];
+       for (i = 0; i < m; i++) {
+               range->freq[i].m = freq->mhz[i];
                range->freq[i].e = 6;
-               range->freq[i].i = i + 1;
+               range->freq[i].i = channel_of_freq(freq->mhz[i]);
        }
-       for (i = m - 12; i < m; i++) {
-               range->freq[i].m = freq->mhz[i - m + 12];
-               range->freq[i].e = 6;
-               range->freq[i].i = i + 23;
-       }
-
        kfree(freq);
 
        rvalue |= mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r);
@@ -544,9 +518,7 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
                i++;
                data++;
        }
-
        range->num_bitrates = i;
-
        kfree(r.ptr);
 
        return rvalue;
@@ -585,7 +557,6 @@ prism54_get_wap(struct net_device *ndev, struct iw_request_info *info,
        int rvalue;
 
        rvalue = mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r);
-
        memcpy(awrq->sa_data, r.ptr, 6);
        awrq->sa_family = ARPHRD_ETHER;
        kfree(r.ptr);
@@ -658,8 +629,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
        current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL);
 
        /* Add frequency. (short) bss->channel is the frequency in MHz */
-       iwe.u.freq.m = bss->channel;
-       iwe.u.freq.e = 6;
+       iwe.u.freq.m = channel_of_freq(bss->channel);
+       iwe.u.freq.e = 0;
        iwe.cmd = SIOCGIWFREQ;
        current_ev =
            iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
@@ -695,7 +666,6 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
                        kfree(buf);
                }
        }
-
        return current_ev;
 }
 
@@ -722,7 +692,7 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
 
        /* Ask the device for a list of known bss. We can report at most
         * IW_MAX_AP=64 to the range struct. But the device won't repport anything
-        * if you change the value of MAXBSS=24. Anyway 24 AP It is probably enough.
+        * if you change the value of IWMAX_BSS=24.
         */
        rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
        bsslist = r.ptr;
@@ -757,7 +727,7 @@ prism54_set_essid(struct net_device *ndev, struct iw_request_info *info,
                memcpy(essid.octets, extra, dwrq->length);
        } else
                essid.length = 0;
-       
+
        if (priv->iw_mode != IW_MODE_MONITOR)
                return mgt_set_request(priv, DOT11_OID_SSID, 0, &essid);
 
@@ -843,21 +813,21 @@ prism54_set_rate(struct net_device *ndev,
        char *data;
        int ret, i;
        union oid_res_t r;
-       
+
        if (vwrq->value == -1) {
                /* auto mode. No limit. */
                profile = 1;
                return mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
        }
-       
+
        if ((ret =
             mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r)))
                return ret;
-               
+
        rate = (u32) (vwrq->value / 500000);
        data = r.ptr;
        i = 0;
-       
+
        while (data[i]) {
                if (rate && (data[i] == rate)) {
                        break;
@@ -868,14 +838,14 @@ prism54_set_rate(struct net_device *ndev,
                data[i] |= 0x80;
                i++;
        }
-               
+
        if (!data[i]) {
                return -EINVAL;
        }
-       
+
        data[i] |= 0x80;
        data[i + 1] = 0;
-       
+
        /* Now, check if we want a fixed or auto value */
        if (vwrq->fixed) {
                data[0] = data[i];
@@ -890,14 +860,14 @@ prism54_set_rate(struct net_device *ndev,
                i++;
        }
        printk("0\n");
-*/     
+*/
        profile = -1;
        ret = mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
        ret |= mgt_set_request(priv, DOT11_OID_EXTENDEDRATES, 0, data);
        ret |= mgt_set_request(priv, DOT11_OID_RATES, 0, data);
-       
+
        kfree(r.ptr);
-       
+
        return ret;
 }
 
@@ -923,7 +893,7 @@ prism54_get_rate(struct net_device *ndev,
        data = r.ptr;
        vwrq->fixed = (data[0] != 0) && (data[1] == 0);
        kfree(r.ptr);
-       
+
        return 0;
 }
 
@@ -979,8 +949,6 @@ prism54_get_frag(struct net_device *ndev, struct iw_request_info *info,
  * small frame <=>  smaller than the rts threshold
  * This is not really the behavior expected by the wireless tool but it seems
  * to be a common behavior in other drivers.
- * 
- * It seems that playing with this tends to hang the card -> DISABLED
  */
 
 static int
@@ -1012,18 +980,16 @@ prism54_set_retry(struct net_device *ndev, struct iw_request_info *info,
                lifetime = vwrq->value / 1024;
 
        /* now set what is requested */
-
-       if (slimit != 0)
+       if (slimit)
                rvalue =
                    mgt_set_request(priv, DOT11_OID_SHORTRETRIES, 0, &slimit);
-       if (llimit != 0)
+       if (llimit)
                rvalue |=
                    mgt_set_request(priv, DOT11_OID_LONGRETRIES, 0, &llimit);
-       if (lifetime != 0)
+       if (lifetime)
                rvalue |=
                    mgt_set_request(priv, DOT11_OID_MAXTXLIFETIME, 0,
                                    &lifetime);
-
        return rvalue;
 }
 
@@ -1119,8 +1085,7 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
                        }
                }
        }
-
-       /* now read the flags     */
+       /* now read the flags */
        if (dwrq->flags & IW_ENCODE_DISABLED) {
                /* Encoding disabled, 
                 * authen = DOT11_AUTH_OS;
@@ -1269,13 +1234,8 @@ prism54_get_oid(struct net_device *ndev, struct iw_request_info *info,
 
 static int
 prism54_set_u32(struct net_device *ndev, struct iw_request_info *info,
-                  __u32 * uwrq, char *extra)
+               __u32 * uwrq, char *extra)
 {
-       /*
-          u32 *i = (int *) extra;
-          int param = *i;
-          int u = *(i + 1);
-        */
        u32 oid = uwrq[0], u = uwrq[1];
 
        return mgt_set_request((islpci_private *) ndev->priv, oid, 0, &u);
@@ -1846,9 +1806,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
                                     0);
                break;
 
-               /* Note : the following should never happen since we don't run the card in
-                * extended mode.
-                * Note : "mlme" is actually a "struct obj_mlmeex *" here, but this
+               /* Note : "mlme" is actually a "struct obj_mlmeex *" here, but this
                 * is backward compatible layout-wise with "struct obj_mlme".
                 */
 
@@ -1893,7 +1851,8 @@ prism54_process_trap(void *data)
        struct net_device *ndev = frame->ndev;
        enum oid_num_t n = mgt_oidtonum(frame->header->oid);
 
-       prism54_process_trap_helper(netdev_priv(ndev), n, frame->data);
+       if (n != OID_NUM_LAST)
+               prism54_process_trap_helper(netdev_priv(ndev), n, frame->data);
        islpci_mgt_release(frame);
 }
 
@@ -1965,66 +1924,12 @@ prism54_get_prismhdr(struct net_device *ndev, struct iw_request_info *info,
        return 0;
 }
 
-int
-prism54_set_maxframeburst(struct net_device *ndev, struct iw_request_info *info,
-                         __u32 * uwrq, char *extra)
-{
-       islpci_private *priv = netdev_priv(ndev);
-       u32 max_burst;
-
-       max_burst = (*uwrq) ? *uwrq : CARD_DEFAULT_MAXFRAMEBURST;
-       mgt_set_request(priv, DOT11_OID_MAXFRAMEBURST, 0, &max_burst);
-
-       return -EINPROGRESS; /* Call commit handler */
-}
-
-int
-prism54_get_maxframeburst(struct net_device *ndev, struct iw_request_info *info,
-                         __u32 * uwrq, char *extra)
-{
-       islpci_private *priv = netdev_priv(ndev);
-       union oid_res_t r;
-       int rvalue;
-       
-       rvalue = mgt_get_request(priv, DOT11_OID_MAXFRAMEBURST, 0, NULL, &r);
-       *uwrq = r.u;
-       
-       return rvalue;
-}
-
-int
-prism54_set_profile(struct net_device *ndev, struct iw_request_info *info,
-                   __u32 * uwrq, char *extra)
-{
-       islpci_private *priv = netdev_priv(ndev);
-       u32 profile;
-
-       profile = (*uwrq) ? *uwrq : CARD_DEFAULT_PROFILE;
-       mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
-       
-       return -EINPROGRESS; /* Call commit handler */
-}
-
-int
-prism54_get_profile(struct net_device *ndev, struct iw_request_info *info,
-                   __u32 * uwrq, char *extra)
-{
-       islpci_private *priv = netdev_priv(ndev);
-       union oid_res_t r;
-       int rvalue;
-
-       rvalue = mgt_get_request(priv, DOT11_OID_PROFILES, 0, NULL, &r);
-       *uwrq = r.u;
-
-       return rvalue;
-}
-
 int
 prism54_debug_oid(struct net_device *ndev, struct iw_request_info *info,
                  __u32 * uwrq, char *extra)
 {
        islpci_private *priv = netdev_priv(ndev);
-       
+
        priv->priv_oid = *uwrq;
        printk("%s: oid 0x%08X\n", ndev->name, *uwrq);
 
@@ -2033,15 +1938,15 @@ prism54_debug_oid(struct net_device *ndev, struct iw_request_info *info,
 
 int
 prism54_debug_get_oid(struct net_device *ndev, struct iw_request_info *info,
-               struct iw_point *data, char *extra)
+                     struct iw_point *data, char *extra)
 {
        islpci_private *priv = netdev_priv(ndev);
        struct islpci_mgmtframe *response = NULL;
        int ret = -EIO, response_op = PIMFOR_OP_ERROR;
-       
+
        printk("%s: get_oid 0x%08X\n", ndev->name, priv->priv_oid);
        data->length = 0;
-       
+
        if (islpci_get_state(priv) >= PRV_STATE_INIT) {
                ret =
                    islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,
@@ -2065,21 +1970,21 @@ prism54_debug_get_oid(struct net_device *ndev, struct iw_request_info *info,
                        printk("%s: len: %i\n", ndev->name, data->length);
                }
        }
-       
+
        return ret;
 }
 
 int
 prism54_debug_set_oid(struct net_device *ndev, struct iw_request_info *info,
-               struct iw_point *data, char *extra)
+                     struct iw_point *data, char *extra)
 {
        islpci_private *priv = netdev_priv(ndev);
        struct islpci_mgmtframe *response = NULL;
        int ret = 0, response_op = PIMFOR_OP_ERROR;
-       
+
        printk("%s: set_oid 0x%08X\tlen: %d\n", ndev->name, priv->priv_oid,
               data->length);
-       
+
        if (islpci_get_state(priv) >= PRV_STATE_INIT) {
                ret =
                    islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET,
@@ -2094,11 +1999,11 @@ prism54_debug_set_oid(struct net_device *ndev, struct iw_request_info *info,
                }
                if (ret || response_op == PIMFOR_OP_ERROR) {
                        printk("%s: EIO\n", ndev->name);
-                       ret = -EIO;
+                       ret = -EIO;
                }
        }
-       
-       return ret;
+
+       return (ret ? ret : -EINPROGRESS);
 }
 
 static int
@@ -2196,7 +2101,7 @@ static const iw_handler prism54_handler[] = {
 #define PRISM54_DBG_GET_OID    SIOCIWFIRSTPRIV+15
 #define PRISM54_DBG_SET_OID    SIOCIWFIRSTPRIV+16
 
-#define PRISM54_GET_OID           SIOCIWFIRSTPRIV+17
+#define PRISM54_GET_OID                SIOCIWFIRSTPRIV+17
 #define PRISM54_SET_OID_U32    SIOCIWFIRSTPRIV+18
 #define        PRISM54_SET_OID_STR     SIOCIWFIRSTPRIV+20
 #define        PRISM54_SET_OID_ADDR    SIOCIWFIRSTPRIV+22
@@ -2204,16 +2109,16 @@ static const iw_handler prism54_handler[] = {
 #define PRISM54_GET_PRISMHDR   SIOCIWFIRSTPRIV+23
 #define PRISM54_SET_PRISMHDR   SIOCIWFIRSTPRIV+24
 
-#define IWPRIV_SET_U32(n,x)    { n, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x }
-#define IWPRIV_SET_SSID(n,x)   { n, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x }
-#define IWPRIV_SET_ADDR(n,x)   { n, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x }
-#define IWPRIV_GET(n,x)        { n, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, "get_"x }
+#define IWPRIV_SET_U32(n,x)    { n, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x }
+#define IWPRIV_SET_SSID(n,x)   { n, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x }
+#define IWPRIV_SET_ADDR(n,x)   { n, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x }
+#define IWPRIV_GET(n,x)        { n, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, "g_"x }
 
 #define IWPRIV_U32(n,x)                IWPRIV_SET_U32(n,x), IWPRIV_GET(n,x)
 #define IWPRIV_SSID(n,x)       IWPRIV_SET_SSID(n,x), IWPRIV_GET(n,x)
 #define IWPRIV_ADDR(n,x)       IWPRIV_SET_ADDR(n,x), IWPRIV_GET(n,x)
 
-/* Note : limited to 128 private ioctls */
+/* Note : limited to 128 private ioctls (wireless tools 26) */
 
 static const struct iw_priv_args prism54_private_args[] = {
 /*{ cmd, set_args, get_args, name } */
@@ -2241,7 +2146,7 @@ static const struct iw_priv_args prism54_private_args[] = {
        {PRISM54_DBG_OID, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
         "dbg_oid"},
        {PRISM54_DBG_GET_OID, 0, IW_PRIV_TYPE_BYTE | 256, "dbg_get_oid"},
-       {PRISM54_DBG_SET_OID, IW_PRIV_TYPE_BYTE | 256, 0, "dbg_get_oid"},
+       {PRISM54_DBG_SET_OID, IW_PRIV_TYPE_BYTE | 256, 0, "dbg_set_oid"},
        /* --- sub-ioctls handlers --- */
        {PRISM54_GET_OID,
         0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, ""},
@@ -2268,7 +2173,7 @@ static const struct iw_priv_args prism54_private_args[] = {
        IWPRIV_U32(DOT11_OID_AUTHENABLE, "authenable"),
        IWPRIV_U32(DOT11_OID_PRIVACYINVOKED, "privinvok"),
        IWPRIV_U32(DOT11_OID_EXUNENCRYPTED, "exunencrypt"),
-       
+
        IWPRIV_U32(DOT11_OID_REKEYTHRESHOLD, "rekeythresh"),
 
        IWPRIV_U32(DOT11_OID_MAXTXLIFETIME, "maxtxlife"),
@@ -2351,5 +2256,6 @@ const struct iw_handler_def prism54_handler_def = {
 int
 prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 {
+
        return -EOPNOTSUPP;
 }
index d5170c4..3320338 100644 (file)
@@ -30,7 +30,6 @@
 #define SUPPORTED_WIRELESS_EXT                  16
 
 void prism54_mib_init(islpci_private *);
-void prism54_mib_init_work(islpci_private *);
 
 struct iw_statistics *prism54_get_wireless_stats(struct net_device *);
 void prism54_update_stats(islpci_private *);
index 1571939..b980edc 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <asm/io.h>
 
+#include "prismcompat.h"
 #include "isl_38xx.h"
 #include "isl_ioctl.h"
 #include "islpci_dev.h"
 #include "islpci_eth.h"
 #include "oid_mgt.h"
 
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-#define prism54_synchronize_irq(irq) synchronize_irq()
-#else
-#define prism54_synchronize_irq(irq) synchronize_irq(irq)
-#endif
-
 #define ISL3877_IMAGE_FILE     "isl3877"
 #define ISL3890_IMAGE_FILE     "isl3890"
 
  * ndev->set_mac_address. Jean II */
 const unsigned char    dummy_mac[6] = { 0x00, 0x30, 0xB4, 0x00, 0x00, 0x00 };
 
+static int
+isl_upload_firmware(islpci_private *priv)
+{
+       u32 reg, rc;
+       void *device_base = priv->device_base;
+
+       /* clear the RAMBoot and the Reset bit */
+       reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
+       reg &= ~ISL38XX_CTRL_STAT_RESET;
+       reg &= ~ISL38XX_CTRL_STAT_RAMBOOT;
+       writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+       wmb();
+       udelay(ISL38XX_WRITEIO_DELAY);
+
+       /* set the Reset bit without reading the register ! */
+       reg |= ISL38XX_CTRL_STAT_RESET;
+       writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+       wmb();
+       udelay(ISL38XX_WRITEIO_DELAY);
+
+       /* clear the Reset bit */
+       reg &= ~ISL38XX_CTRL_STAT_RESET;
+       writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+       wmb();
+
+       /* wait a while for the device to reboot */
+       mdelay(50);
+
+       {
+               const struct firmware *fw_entry = 0;
+               long fw_len;
+               const u32 *fw_ptr;
+
+               rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV);
+               if (rc) {
+                       printk(KERN_ERR
+                              "%s: request_firmware() failed for '%s'\n",
+                              "prism54", priv->firmware);
+                       return rc;
+               }
+               /* prepare the Direct Memory Base register */
+               reg = ISL38XX_DEV_FIRMWARE_ADDRES;
+
+               fw_ptr = (u32 *) fw_entry->data;
+               fw_len = fw_entry->size;
+
+               if (fw_len % 4) {
+                       printk(KERN_ERR
+                              "%s: firmware '%s' size is not multiple of 32bit, aborting!\n",
+                              "prism54", priv->firmware);
+                       release_firmware(fw_entry);
+                       return EILSEQ; /* Illegal byte sequence  */;
+               }
+
+               while (fw_len > 0) {
+                       long _fw_len =
+                           (fw_len >
+                            ISL38XX_MEMORY_WINDOW_SIZE) ?
+                           ISL38XX_MEMORY_WINDOW_SIZE : fw_len;
+                       u32 *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN;
+
+                       /* set the cards base address for writting the data */
+                       isl38xx_w32_flush(device_base, reg,
+                                         ISL38XX_DIR_MEM_BASE_REG);
+                       wmb();  /* be paranoid */
+
+                       /* increment the write address for next iteration */
+                       reg += _fw_len;
+                       fw_len -= _fw_len;
+
+                       /* write the data to the Direct Memory Window 32bit-wise */
+                       /* memcpy_toio() doesn't guarantee 32bit writes :-| */
+                       while (_fw_len > 0) {
+                               /* use non-swapping writel() */
+                               __raw_writel(*fw_ptr, dev_fw_ptr);
+                               fw_ptr++, dev_fw_ptr++;
+                               _fw_len -= 4;
+                       }
+
+                       /* flush PCI posting */
+                       (void) readl(device_base + ISL38XX_PCI_POSTING_FLUSH);
+                       wmb();  /* be paranoid again */
+
+                       BUG_ON(_fw_len != 0);
+               }
+
+               BUG_ON(fw_len != 0);
+
+               release_firmware(fw_entry);
+       }
+
+       /* now reset the device
+        * clear the Reset & ClkRun bit, set the RAMBoot bit */
+       reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
+       reg &= ~ISL38XX_CTRL_STAT_CLKRUN;
+       reg &= ~ISL38XX_CTRL_STAT_RESET;
+       reg |= ISL38XX_CTRL_STAT_RAMBOOT;
+       isl38xx_w32_flush(device_base, reg, ISL38XX_CTRL_STAT_REG);
+       wmb();
+       udelay(ISL38XX_WRITEIO_DELAY);
+
+       /* set the reset bit latches the host override and RAMBoot bits
+        * into the device for operation when the reset bit is reset */
+       reg |= ISL38XX_CTRL_STAT_RESET;
+       writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+       /* don't do flush PCI posting here! */
+       wmb();
+       udelay(ISL38XX_WRITEIO_DELAY);
+
+       /* clear the reset bit should start the whole circus */
+       reg &= ~ISL38XX_CTRL_STAT_RESET;
+       writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+       /* don't do flush PCI posting here! */
+       wmb();
+       udelay(ISL38XX_WRITEIO_DELAY);
+
+       return 0;
+}
+
 /******************************************************************************
     Device Interrupt Handler
 ******************************************************************************/
@@ -74,7 +188,9 @@ islpci_interrupt(int irq, void *config, struct pt_regs *regs)
        if (reg & ISL38XX_CTRL_STAT_SLEEPMODE)
                /* device is in sleep mode, IRQ was generated by someone else */
        {
-               printk(KERN_DEBUG "Assuming someone else called the IRQ\n");
+#if VERBOSE > SHOW_ERROR_MESSAGES
+               DEBUG(SHOW_TRACING, "Assuming someone else called the IRQ\n");
+#endif
                return IRQ_NONE;
        }
 
@@ -324,14 +440,7 @@ islpci_upload_fw(islpci_private *priv)
 
        printk(KERN_DEBUG "%s: uploading firmware...\n", priv->ndev->name);
 
-       rc = isl38xx_upload_firmware(priv->firmware,
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,75))
-               &priv->pdev->dev,
-#else
-               pci_name(priv->pdev),
-#endif
-               priv->device_base,
-               priv->device_host_address);
+       rc = isl_upload_firmware(priv);
        if (rc) {
                /* error uploading the firmware */
                printk(KERN_ERR "%s: could not upload firmware ('%s')\n",
@@ -357,15 +466,8 @@ islpci_reset_if(islpci_private *priv)
        int result = -ETIME;
        int count;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-       /* This is 2.6 specific, nicer, shorter, but not in 2.4 yet */
        DEFINE_WAIT(wait);
        prepare_to_wait(&priv->reset_done, &wait, TASK_UNINTERRUPTIBLE);
-#else
-       DECLARE_WAITQUEUE(wait, current);
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       add_wait_queue(&priv->reset_done, &wait);
-#endif
        
        /* now the last step is to reset the interface */
        isl38xx_interface_reset(priv->device_base, priv->device_host_address);
@@ -390,13 +492,7 @@ islpci_reset_if(islpci_private *priv)
 
        }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-       /* 2.6 specific too */
        finish_wait(&priv->reset_done, &wait);
-#else
-       remove_wait_queue(&priv->reset_done, &wait);
-       set_current_state(TASK_RUNNING);
-#endif
 
        if(result)
                return result;
@@ -410,7 +506,9 @@ islpci_reset_if(islpci_private *priv)
         * the IRQ line until we know for sure the reset went through */
        isl38xx_enable_common_interrupts(priv->device_base);
 
-       prism54_mib_init_work(priv);
+       down_write(&priv->mib_sem);
+       mgt_commit(priv);
+       up_write(&priv->mib_sem);
 
        islpci_set_state(priv, PRV_STATE_READY);
 
@@ -448,9 +546,9 @@ islpci_reset(islpci_private *priv, int reload_firmware)
        /* reset the mgmt receive queue */
        for (counter = 0; counter < ISL38XX_CB_MGMT_QSIZE; counter++) {
                isl38xx_fragment *frag = &cb->rx_data_mgmt[counter];
-               frag->size = MGMT_FRAME_SIZE;
+               frag->size = cpu_to_le16(MGMT_FRAME_SIZE);
                frag->flags = 0;
-               frag->address = priv->mgmt_rx[counter].pci_addr;
+               frag->address = cpu_to_le32(priv->mgmt_rx[counter].pci_addr);
        }
 
        for (counter = 0; counter < ISL38XX_CB_RX_QSIZE; counter++) {
@@ -580,6 +678,7 @@ islpci_alloc_memory(islpci_private *priv)
                        skb = NULL;
                        goto out_free;
                }
+               skb_reserve(skb, (4 - (long) skb->data) & 0x03);
                /* add the new allocated sk_buff to the buffer array */
                priv->data_low_rx[counter] = skb;
 
index de92b4e..19fbd6b 100644 (file)
 #include <net/iw_handler.h>
 #include <linux/list.h>
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
-# include <linux/workqueue.h>
-#else
-# include <linux/tqueue.h>
-# define work_struct tq_struct
-# define INIT_WORK INIT_TQUEUE
-# define schedule_work schedule_task
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23)
-#define free_netdev(x) kfree(x) 
-#define pci_name(x) x->slot_name 
-#endif
-
 #include "isl_38xx.h"
 #include "isl_oid.h"
 #include "islpci_mgt.h"
@@ -187,7 +173,7 @@ typedef struct {
        islpci_state_t state;
        int state_off;          /* enumeration of off-state, if 0 then
                                 * we're not in any off-state */
-       
+
        /* WPA stuff */
        int wpa; /* WPA mode enabled */
        struct list_head bss_wpa_list;
@@ -210,12 +196,6 @@ islpci_state_t islpci_set_state(islpci_private *priv, islpci_state_t new_state);
 
 #define ISLPCI_TX_TIMEOUT               (2*HZ)
 
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,75))
-# define irqreturn_t void
-# define IRQ_HANDLED
-# define IRQ_NONE
-#endif
-
 irqreturn_t islpci_interrupt(int, void *, struct pt_regs *);
 
 int prism54_post_setup(islpci_private *, int);
index c18c42d..4f82bfa 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 
+#include "prismcompat.h"
 #include "isl_38xx.h"
 #include "islpci_eth.h"
 #include "islpci_mgt.h"
@@ -104,7 +105,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
 
        /* check whether the destination queue has enough fragments for the frame */
        curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ]);
-       if (curr_frag - priv->free_data_tx >= ISL38XX_CB_TX_QSIZE) {
+       if (unlikely(curr_frag - priv->free_data_tx >= ISL38XX_CB_TX_QSIZE)) {
                printk(KERN_ERR "%s: transmit device queue full when awake\n",
                       ndev->name);
                netif_stop_queue(ndev);
@@ -120,7 +121,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
        /* Check alignment and WDS frame formatting. The start of the packet should
         * be aligned on a 4-byte boundary. If WDS is enabled add another 6 bytes
         * and add WDS address information */
-       if (((long) skb->data & 0x03) | init_wds) {
+       if (unlikely(((long) skb->data & 0x03) | init_wds)) {
                /* get the number of bytes to add and re-allign */
                offset = (4 - (long) skb->data) & 0x03;
                offset += init_wds ? 6 : 0;
@@ -191,7 +192,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
        pci_map_address = pci_map_single(priv->pdev,
                                         (void *) skb->data, skb->len,
                                         PCI_DMA_TODEVICE);
-       if (pci_map_address == 0) {
+       if (unlikely(pci_map_address == 0)) {
                printk(KERN_WARNING "%s: cannot map buffer to PCI\n",
                       ndev->name);
 
@@ -207,7 +208,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
        priv->data_low_tx[index] = skb;
        /* set the proper fragment start address and size information */
        fragment->size = cpu_to_le16(frame_size);
-       fragment->flags = cpu_to_le16(0);  /* set to 1 if more fragments */
+       fragment->flags = cpu_to_le16(0);       /* set to 1 if more fragments */
        fragment->address = cpu_to_le32(pci_map_address);
        curr_frag++;
 
@@ -217,7 +218,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
        cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ] = cpu_to_le32(curr_frag);
 
        if (curr_frag - priv->free_data_tx + ISL38XX_MIN_QTHRESHOLD
-                                                  > ISL38XX_CB_TX_QSIZE) {
+           > ISL38XX_CB_TX_QSIZE) {
                /* stop sends from upper layers */
                netif_stop_queue(ndev);
 
@@ -238,7 +239,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
 
        return 0;
 
- drop_free:
     drop_free:
        /* free the skbuf structure before aborting */
        dev_kfree_skb(skb);
        skb = NULL;
@@ -261,9 +262,9 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
        if (priv->ndev->type == ARPHRD_IEEE80211_PRISM) {
                struct avs_80211_1_header *avs;
                /* extract the relevant data from the header */
-               u32 clock = hdr->clock;
+               u32 clock = le32_to_cpu(hdr->clock);
                u8 rate = hdr->rate;
-               u16 freq = be16_to_cpu(hdr->freq);
+               u16 freq = le16_to_cpu(hdr->freq);
                u8 rssi = hdr->rssi;
 
                skb_pull(*skb, sizeof (struct rfmon_header));
@@ -274,7 +275,7 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
                                                                         avs_80211_1_header),
                                                                 0, GFP_ATOMIC);
                        if (newskb) {
-                               kfree_skb(*skb);
+                               dev_kfree_skb_irq(*skb);
                                *skb = newskb;
                        } else
                                return -1;
@@ -286,21 +287,21 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
                    (struct avs_80211_1_header *) skb_push(*skb,
                                                           sizeof (struct
                                                                   avs_80211_1_header));
-
-               avs->version = htonl(P80211CAPTURE_VERSION);
-               avs->length = htonl(sizeof (struct avs_80211_1_header));
-               avs->mactime = __cpu_to_be64(clock);
-               avs->hosttime = __cpu_to_be64(jiffies);
-               avs->phytype = htonl(6);        /*OFDM: 6 for (g), 8 for (a) */
-               avs->channel = htonl(channel_of_freq(freq));
-               avs->datarate = htonl(rate * 5);
-               avs->antenna = htonl(0);        /*unknown */
-               avs->priority = htonl(0);       /*unknown */
-               avs->ssi_type = htonl(2);       /*2: dBm, 3: raw RSSI */
-               avs->ssi_signal = htonl(rssi);
-               avs->ssi_noise = htonl(priv->local_iwstatistics.qual.noise);    /*better than 'undefined', I assume */
-               avs->preamble = htonl(0);       /*unknown */
-               avs->encoding = htonl(0);       /*unknown */
+               
+               avs->version = cpu_to_be32(P80211CAPTURE_VERSION);
+               avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header));
+               avs->mactime = cpu_to_be64(le64_to_cpu(clock));
+               avs->hosttime = cpu_to_be64(jiffies);
+               avs->phytype = cpu_to_be32(6);  /*OFDM: 6 for (g), 8 for (a) */
+               avs->channel = cpu_to_be32(channel_of_freq(freq));
+               avs->datarate = cpu_to_be32(rate * 5);
+               avs->antenna = cpu_to_be32(0);  /*unknown */
+               avs->priority = cpu_to_be32(0); /*unknown */
+               avs->ssi_type = cpu_to_be32(3); /*2: dBm, 3: raw RSSI */
+               avs->ssi_signal = cpu_to_be32(rssi & 0x7f);
+               avs->ssi_noise = cpu_to_be32(priv->local_iwstatistics.qual.noise);      /*better than 'undefined', I assume */
+               avs->preamble = cpu_to_be32(0); /*unknown */
+               avs->encoding = cpu_to_be32(0); /*unknown */
        } else
                skb_pull(*skb, sizeof (struct rfmon_header));
 
@@ -381,10 +382,10 @@ islpci_eth_receive(islpci_private *priv)
        skb->dev = ndev;
 
        /* take care of monitor mode and spy monitoring. */
-       if (priv->iw_mode == IW_MODE_MONITOR)
+       if (unlikely(priv->iw_mode == IW_MODE_MONITOR))
                discard = islpci_monitor_rx(priv, &skb);
        else {
-               if (skb->data[2 * ETH_ALEN] == 0) {
+               if (unlikely(skb->data[2 * ETH_ALEN] == 0)) {
                        /* The packet has a rx_annex. Read it for spy monitoring, Then
                         * remove it, while keeping the 2 leading MAC addr.
                         */
@@ -417,8 +418,8 @@ islpci_eth_receive(islpci_private *priv)
             skb->data[0], skb->data[1], skb->data[2], skb->data[3],
             skb->data[4], skb->data[5]);
 #endif
-       if (discard) {
-               dev_kfree_skb(skb);
+       if (unlikely(discard)) {
+               dev_kfree_skb_irq(skb);
                skb = NULL;
        } else
                netif_rx(skb);
@@ -433,11 +434,13 @@ islpci_eth_receive(islpci_private *priv)
               index - priv->free_data_rx < ISL38XX_CB_RX_QSIZE) {
                /* allocate an sk_buff for received data frames storage
                 * include any required allignment operations */
-               if (skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2), skb == NULL) {
+               skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2);
+               if (unlikely(skb == NULL)) {
                        /* error allocating an sk_buff structure elements */
                        DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb \n");
                        break;
                }
+               skb_reserve(skb, (4 - (long) skb->data) & 0x03);
                /* store the new skb structure pointer */
                index = index % ISL38XX_CB_RX_QSIZE;
                priv->data_low_rx[index] = skb;
@@ -453,13 +456,13 @@ islpci_eth_receive(islpci_private *priv)
                    pci_map_single(priv->pdev, (void *) skb->data,
                                   MAX_FRAGMENT_SIZE_RX + 2,
                                   PCI_DMA_FROMDEVICE);
-               if (priv->pci_map_rx_address[index] == (dma_addr_t) NULL) {
+               if (unlikely(priv->pci_map_rx_address[index] == (dma_addr_t) NULL)) {
                        /* error mapping the buffer to device accessable memory address */
                        DEBUG(SHOW_ERROR_MESSAGES,
                              "Error mapping DMA address\n");
 
                        /* free the skbuf structure before aborting */
-                       dev_kfree_skb((struct sk_buff *) skb);
+                       dev_kfree_skb_irq((struct sk_buff *) skb);
                        skb = NULL;
                        break;
                }
@@ -484,10 +487,10 @@ islpci_eth_receive(islpci_private *priv)
 void
 islpci_do_reset_and_wake(void *data)
 {
-       islpci_private *priv = (islpci_private *) data;
-       islpci_reset(priv, 1);
-       netif_wake_queue(priv->ndev);
-       priv->reset_task_pending = 0;
+       islpci_private *priv = (islpci_private *) data;
+       islpci_reset(priv, 1);
+       netif_wake_queue(priv->ndev);
+       priv->reset_task_pending = 0;
 }
 
 void
index 34b3b59..3fe59fb 100644 (file)
 #include <linux/delay.h>
 #include <linux/init.h> /* For __init, __exit */
 
+#include "prismcompat.h"
 #include "islpci_dev.h"
 #include "islpci_mgt.h"                /* for pc_debug */
 #include "isl_oid.h"
 
 #define DRV_NAME       "prism54"
-#define DRV_VERSION    "1.1"
+#define DRV_VERSION    "1.2"
 
 MODULE_AUTHOR("[Intersil] R.Bastings and W.Termorshuizen, The prism54.org Development Team <prism54-devel@prism54.org>");
 MODULE_DESCRIPTION("The Prism54 802.11 Wireless LAN adapter");
index bdf77d6..58cd358 100644 (file)
 #include <linux/netdevice.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
 #include <linux/if_arp.h>
 
+#include "prismcompat.h"
 #include "isl_38xx.h"
 #include "islpci_mgt.h"
 #include "isl_oid.h"           /* additional types and defs for isl38xx fw */
@@ -63,7 +63,6 @@ display_buffer(char *buffer, int length)
     Queue handling for management frames
 ******************************************************************************/
 
-  
 /*
  * Helper function to create a PIMFOR management frame header.
  */
@@ -86,8 +85,8 @@ pimfor_decode_header(void *data, int len)
 {
        pimfor_header_t *h = data;
 
-        while ((void *) h < data + len) {
-               if(h->flags & PIMFOR_FLAG_LITTLE_ENDIAN) {
+       while ((void *) h < data + len) {
+               if (h->flags & PIMFOR_FLAG_LITTLE_ENDIAN) {
                        le32_to_cpus(&h->oid);
                        le32_to_cpus(&h->length);
                } else {
@@ -108,8 +107,8 @@ int
 islpci_mgmt_rx_fill(struct net_device *ndev)
 {
        islpci_private *priv = netdev_priv(ndev);
-       isl38xx_control_block *cb =    /* volatile not needed */
-               (isl38xx_control_block *) priv->control_block;
+       isl38xx_control_block *cb =     /* volatile not needed */
+           (isl38xx_control_block *) priv->control_block;
        u32 curr = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ]);
 
 #if VERBOSE > SHOW_ERROR_MESSAGES
@@ -124,7 +123,8 @@ islpci_mgmt_rx_fill(struct net_device *ndev)
                if (buf->mem == NULL) {
                        buf->mem = kmalloc(MGMT_FRAME_SIZE, GFP_ATOMIC);
                        if (!buf->mem) {
-                               printk(KERN_WARNING "Error allocating management frame.\n");
+                               printk(KERN_WARNING
+                                      "Error allocating management frame.\n");
                                return -ENOMEM;
                        }
                        buf->size = MGMT_FRAME_SIZE;
@@ -133,24 +133,24 @@ islpci_mgmt_rx_fill(struct net_device *ndev)
                        buf->pci_addr = pci_map_single(priv->pdev, buf->mem,
                                                       MGMT_FRAME_SIZE,
                                                       PCI_DMA_FROMDEVICE);
-                       if(!buf->pci_addr) {
-                               printk(KERN_WARNING "Failed to make memory DMA'able\n.");
+                       if (!buf->pci_addr) {
+                               printk(KERN_WARNING
+                                      "Failed to make memory DMA'able\n.");
                                return -ENOMEM;
                        }
                }
 
-                /* be safe: always reset control block information */
+               /* be safe: always reset control block information */
                frag->size = cpu_to_le16(MGMT_FRAME_SIZE);
                frag->flags = 0;
                frag->address = cpu_to_le32(buf->pci_addr);
                curr++;
 
-                /* The fragment address in the control block must have
-                 * been written before announcing the frame buffer to
-                 * device */
+               /* The fragment address in the control block must have
+                * been written before announcing the frame buffer to
+                * device */
                wmb();
-               cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] =
-                       cpu_to_le32(curr);
+               cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] = cpu_to_le32(curr);
        }
        return 0;
 }
@@ -168,7 +168,7 @@ islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid,
 {
        islpci_private *priv = netdev_priv(ndev);
        isl38xx_control_block *cb =
-               (isl38xx_control_block *) priv->control_block;
+           (isl38xx_control_block *) priv->control_block;
        void *p;
        int err = -EINVAL;
        unsigned long flags;
@@ -242,25 +242,25 @@ islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid,
        priv->mgmt_tx[index] = buf;
        frag = &cb->tx_data_mgmt[index];
        frag->size = cpu_to_le16(frag_len);
-       frag->flags = 0;   /* for any other than the last fragment, set to 1 */
+       frag->flags = 0;        /* for any other than the last fragment, set to 1 */
        frag->address = cpu_to_le32(buf.pci_addr);
 
        /* The fragment address in the control block must have
         * been written before announcing the frame buffer to
         * device */
        wmb();
-       cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ] = cpu_to_le32(curr_frag+1);
+       cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ] = cpu_to_le32(curr_frag + 1);
        spin_unlock_irqrestore(&priv->slock, flags);
 
        /* trigger the device */
        islpci_trigger(priv);
        return 0;
 
- error_unlock:
     error_unlock:
        spin_unlock_irqrestore(&priv->slock, flags);
- error_free:
     error_free:
        kfree(buf.mem);
- error:
     error:
        return err;
 }
 
@@ -274,50 +274,49 @@ islpci_mgt_receive(struct net_device *ndev)
 {
        islpci_private *priv = netdev_priv(ndev);
        isl38xx_control_block *cb =
-               (isl38xx_control_block *) priv->control_block;
+           (isl38xx_control_block *) priv->control_block;
        u32 curr_frag;
 
 #if VERBOSE > SHOW_ERROR_MESSAGES
        DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive \n");
 #endif
 
-
-        /* Only once per interrupt, determine fragment range to
-         * process.  This avoids an endless loop (i.e. lockup) if
-         * frames come in faster than we can process them. */
+       /* Only once per interrupt, determine fragment range to
+        * process.  This avoids an endless loop (i.e. lockup) if
+        * frames come in faster than we can process them. */
        curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_RX_MGMTQ]);
        barrier();
 
-       for ( ; priv->index_mgmt_rx < curr_frag; priv->index_mgmt_rx++) {
+       for (; priv->index_mgmt_rx < curr_frag; priv->index_mgmt_rx++) {
                pimfor_header_t *header;
                u32 index = priv->index_mgmt_rx % ISL38XX_CB_MGMT_QSIZE;
                struct islpci_membuf *buf = &priv->mgmt_rx[index];
                u16 frag_len;
                int size;
                struct islpci_mgmtframe *frame;
-              
-                /* I have no idea (and no documentation) if flags != 0
-                 * is possible.  Drop the frame, reuse the buffer. */
-                if(le16_to_cpu(cb->rx_data_mgmt[index].flags) != 0) {
-                        printk(KERN_WARNING "%s: unknown flags 0x%04x\n",
-                               ndev->name,
-                               le16_to_cpu(cb->rx_data_mgmt[index].flags));
-                        continue;
-                }
+
+               /* I have no idea (and no documentation) if flags != 0
+                * is possible.  Drop the frame, reuse the buffer. */
+               if (le16_to_cpu(cb->rx_data_mgmt[index].flags) != 0) {
+                       printk(KERN_WARNING "%s: unknown flags 0x%04x\n",
+                              ndev->name,
+                              le16_to_cpu(cb->rx_data_mgmt[index].flags));
+                       continue;
+               }
 
                /* The device only returns the size of the header(s) here. */
                frag_len = le16_to_cpu(cb->rx_data_mgmt[index].size);
 
                /*
-                 * We appear to have no way to tell the device the
-                 * size of a receive buffer.  Thus, if this check
-                 * triggers, we likely have kernel heap corruption. */
-                if (frag_len > MGMT_FRAME_SIZE) {
-                        printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\
-n",
-                               ndev->name, frag_len, frag_len);
-                        frag_len = MGMT_FRAME_SIZE;
-                }
+                * We appear to have no way to tell the device the
+                * size of a receive buffer.  Thus, if this check
+                * triggers, we likely have kernel heap corruption. */
+               if (frag_len > MGMT_FRAME_SIZE) {
+                       printk(KERN_WARNING
+                               "%s: Bogus packet size of %d (%#x).\n",
+                               ndev->name, frag_len, frag_len);
+                       frag_len = MGMT_FRAME_SIZE;
+               }
 
                /* Ensure the results of device DMA are visible to the CPU. */
                pci_dma_sync_single(priv->pdev, buf->pci_addr,
@@ -339,30 +338,32 @@ n",
 #if VERBOSE > SHOW_ERROR_MESSAGES
                DEBUG(SHOW_PIMFOR_FRAMES,
                      "PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x \n",
-                     header->operation, header->oid, header->device_id, 
+                     header->operation, header->oid, header->device_id,
                      header->flags, header->length);
 
                /* display the buffer contents for debugging */
                display_buffer((char *) header, PIMFOR_HEADER_SIZE);
-               display_buffer((char *) header + PIMFOR_HEADER_SIZE, header->length);
+               display_buffer((char *) header + PIMFOR_HEADER_SIZE,
+                              header->length);
 #endif
 
                /* nobody sends these */
                if (header->flags & PIMFOR_FLAG_APPLIC_ORIGIN) {
-                       printk(KERN_DEBUG "%s: errant PIMFOR application frame\n",
+                       printk(KERN_DEBUG
+                              "%s: errant PIMFOR application frame\n",
                               ndev->name);
                        continue;
                }
 
                /* Determine frame size, skipping OID_INL_TUNNEL headers. */
                size = PIMFOR_HEADER_SIZE + header->length;
-               frame = kmalloc(sizeof(struct islpci_mgmtframe) + size,
+               frame = kmalloc(sizeof (struct islpci_mgmtframe) + size,
                                GFP_ATOMIC);
                if (!frame) {
-                       printk(KERN_WARNING "%s: Out of memory, cannot handle oid 0x%08x\n",
-
+                       printk(KERN_WARNING
+                              "%s: Out of memory, cannot handle oid 0x%08x\n",
                               ndev->name, header->oid);
-                       continue;        
+                       continue;
                }
                frame->ndev = ndev;
                memcpy(&frame->buf, header, size);
@@ -382,7 +383,7 @@ n",
                               header->oid, header->device_id, header->flags,
                               header->length);
 #endif
-                      
+
                        /* Create work to handle trap out of interrupt
                         * context. */
                        INIT_WORK(&frame->ws, prism54_process_trap, frame);
@@ -392,14 +393,13 @@ n",
                        /* Signal the one waiting process that a response
                         * has been received. */
                        if ((frame = xchg(&priv->mgmt_received, frame)) != NULL) {
-                               printk(KERN_WARNING "%s: mgmt response not collected\n",
+                               printk(KERN_WARNING
+                                      "%s: mgmt response not collected\n",
                                       ndev->name);
                                kfree(frame);
                        }
-                              
 #if VERBOSE > SHOW_ERROR_MESSAGES
-                       DEBUG(SHOW_TRACING,
-                             "Wake up Mgmt Queue\n");
+                       DEBUG(SHOW_TRACING, "Wake up Mgmt Queue\n");
 #endif
                        wake_up(&priv->mgmt_wqueue);
                }
@@ -416,22 +416,22 @@ void
 islpci_mgt_cleanup_transmit(struct net_device *ndev)
 {
        islpci_private *priv = netdev_priv(ndev);
-       isl38xx_control_block *cb =    /* volatile not needed */
-               (isl38xx_control_block *) priv->control_block;
+       isl38xx_control_block *cb =     /* volatile not needed */
+           (isl38xx_control_block *) priv->control_block;
        u32 curr_frag;
 
 #if VERBOSE > SHOW_ERROR_MESSAGES
-        DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_cleanup_transmit\n");
+       DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_cleanup_transmit\n");
 #endif
 
        /* Only once per cleanup, determine fragment range to
         * process.  This avoids an endless loop (i.e. lockup) if
         * the device became confused, incrementing device_curr_frag
         * rapidly. */
-       curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_TX_MGMTQ]); 
+       curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_TX_MGMTQ]);
        barrier();
 
-       for ( ; priv->index_mgmt_tx < curr_frag; priv->index_mgmt_tx++) {
+       for (; priv->index_mgmt_tx < curr_frag; priv->index_mgmt_tx++) {
                int index = priv->index_mgmt_tx % ISL38XX_CB_MGMT_QSIZE;
                struct islpci_membuf *buf = &priv->mgmt_tx[index];
                pci_unmap_single(priv->pdev, buf->pci_addr, buf->size,
@@ -456,23 +456,14 @@ islpci_mgt_transaction(struct net_device *ndev,
        const long wait_cycle_jiffies = (ISL38XX_WAIT_CYCLE * 10 * HZ) / 1000;
        long timeout_left = ISL38XX_MAX_WAIT_CYCLES * wait_cycle_jiffies;
        int err;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
        DEFINE_WAIT(wait);
-#else
-       DECLARE_WAITQUEUE(wait, current);
-#endif
 
        if (down_interruptible(&priv->mgmt_sem))
                return -ERESTARTSYS;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
        prepare_to_wait(&priv->mgmt_wqueue, &wait, TASK_UNINTERRUPTIBLE);
-#else
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       add_wait_queue(&priv->mgmt_wqueue, &wait);
-#endif
        err = islpci_mgt_transmit(ndev, operation, oid, senddata, sendlen);
-       if(err)
+       if (err)
                goto out;
 
        err = -ETIMEDOUT;
@@ -483,13 +474,24 @@ islpci_mgt_transaction(struct net_device *ndev,
                timeleft = schedule_timeout(wait_cycle_jiffies);
                frame = xchg(&priv->mgmt_received, NULL);
                if (frame) {
-                       *recvframe = frame;
-                       err = 0;
-                       goto out;
+                       if (frame->header->oid == oid) {
+                               *recvframe = frame;
+                               err = 0;
+                               goto out;
+                       } else {
+                               printk(KERN_DEBUG
+                                      "%s: expecting oid 0x%x, received 0x%x.\n",
+                                      ndev->name, (unsigned int) oid,
+                                      frame->header->oid);
+                               kfree(frame);
+                               frame = NULL;
+                       }
                }
-               if(timeleft == 0) {
-                       printk(KERN_DEBUG "%s: timeout waiting for mgmt response %lu, trigging device\n",
-                              ndev->name, timeout_left);
+               if (timeleft == 0) {
+                       printk(KERN_DEBUG
+                               "%s: timeout waiting for mgmt response %lu, "
+                               "triggering device\n",
+                               ndev->name, timeout_left);
                        islpci_trigger(priv);
                }
                timeout_left += timeleft - wait_cycle_jiffies;
@@ -499,12 +501,7 @@ islpci_mgt_transaction(struct net_device *ndev,
 
        /* TODO: we should reset the device here */     
  out:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
        finish_wait(&priv->mgmt_wqueue, &wait);
-#else
-       remove_wait_queue(&priv->mgmt_wqueue, &wait);
-       set_current_state(TASK_RUNNING);
-#endif
        up(&priv->mgmt_sem);
        return err;
 }
index 80337f9..72cb87a 100644 (file)
 #include <linux/wireless.h>
 #include <linux/skbuff.h>
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
-# include <linux/workqueue.h>
-#else
-# include <linux/tqueue.h>
-# define work_struct tq_struct
-# define INIT_WORK INIT_TQUEUE
-# define schedule_work schedule_task
-#endif
-
 /*
  *  Function definitions
  */
@@ -43,7 +34,7 @@
 #define TRACE(devname)   K_DEBUG(SHOW_TRACING, VERBOSE, "%s:  -> " __FUNCTION__ "()\n", devname)
 
 extern int pc_debug;
-static const int init_wds = 0; /* help compiler optimize away dead code */
+#define init_wds 0     /* help compiler optimize away dead code */
 
 
 /* General driver definitions */
index cfa541c..470466d 100644 (file)
@@ -16,6 +16,7 @@
  *
  */
 
+#include "prismcompat.h"
 #include "islpci_dev.h"
 #include "islpci_mgt.h"
 #include "isl_oid.h"
@@ -39,17 +40,13 @@ channel_of_freq(int f)
        if ((f >= 2412) && (f <= 2484)) {
                while ((c < 14) && (f != frequency_list_bg[c]))
                        c++;
-               if (c >= 14)
-                       return 0;
+               return (c >= 14) ? 0 : ++c;
        } else if ((f >= (int) 5170) && (f <= (int) 5320)) {
                while ((c < 12) && (f != frequency_list_a[c]))
                        c++;
-               if (c >= 12)
-                       return 0;
+               return (c >= 12) ? 0 : (c + 37);
        } else
                return 0;
-
-       return ++c;
 }
 
 #define OID_STRUCT(name,oid,s,t) [name] = {oid, 0, sizeof(s), t}
@@ -449,7 +446,7 @@ mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data)
        if (cache)
                down_write(&priv->mib_sem);
 
-       if (islpci_get_state(priv) >= PRV_STATE_INIT) {
+       if (islpci_get_state(priv) >= PRV_STATE_READY) {
                ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid,
                                             _data, dlen, &response);
                if (!ret) {
@@ -457,7 +454,7 @@ mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data)
                        islpci_mgt_release(response);
                }
                if (ret || response_op == PIMFOR_OP_ERROR)
-                       ret = -EIO;
+                       ret = -EIO;
        } else if (!cache)
                ret = -EIO;
 
@@ -482,7 +479,7 @@ mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data,
        int ret = -EIO;
        int reslen = 0;
        struct islpci_mgmtframe *response = NULL;
-       
+
        int dlen;
        void *cache, *_res = NULL;
        u32 oid;
@@ -503,11 +500,11 @@ mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data,
        if (cache)
                down_read(&priv->mib_sem);
 
-       if (islpci_get_state(priv) >= PRV_STATE_INIT) {
+       if (islpci_get_state(priv) >= PRV_STATE_READY) {
                ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,
                                             oid, data, dlen, &response);
                if (ret || !response ||
-                       response->header->operation == PIMFOR_OP_ERROR) {
+                   response->header->operation == PIMFOR_OP_ERROR) {
                        if (response)
                                islpci_mgt_release(response);
                        ret = -EIO;
@@ -542,9 +539,9 @@ mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data,
        if (reslen > isl_oid[n].size)
                printk(KERN_DEBUG
                       "mgt_get_request(0x%x): received data length was bigger "
-                      "than expected (%d > %d). Memory is probably corrupted... ",
+                      "than expected (%d > %d). Memory is probably corrupted...",
                       oid, reslen, isl_oid[n].size);
-       
+
        return ret;
 }
 
@@ -564,11 +561,11 @@ mgt_commit_list(islpci_private *priv, enum oid_num_t *l, int n)
                while (j <= t->range) {
                        response = NULL;
                        ret |= islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET,
-                                                     oid, data, t->size,
+                                                     oid, data, t->size,
                                                      &response);
                        if (response) {
                                ret |= (response->header->operation ==
-                                       PIMFOR_OP_ERROR);
+                                       PIMFOR_OP_ERROR);
                                islpci_mgt_release(response);
                        }
                        j++;
@@ -625,12 +622,32 @@ static enum oid_num_t commit_part2[] = {
        OID_INL_OUTPUTPOWER,
 };
 
+/* update the MAC addr. */
+static int
+mgt_update_addr(islpci_private *priv)
+{
+       struct islpci_mgmtframe *res;
+       int ret;
+
+       ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,
+                                    isl_oid[GEN_OID_MACADDRESS].oid, NULL,
+                                    isl_oid[GEN_OID_MACADDRESS].size, &res);
+
+       if ((ret == 0) && res && (res->header->operation != PIMFOR_OP_ERROR))
+               memcpy(priv->ndev->dev_addr, res->data, 6);
+       else
+               ret = -EIO;
+       if (res)
+               islpci_mgt_release(res);
+
+       return ret;
+}
+
 void
 mgt_commit(islpci_private *priv)
 {
        int rvalue;
        u32 u;
-       union oid_res_t r;
 
        if (islpci_get_state(priv) < PRV_STATE_INIT)
                return;
@@ -646,21 +663,14 @@ mgt_commit(islpci_private *priv)
 
        u = OID_INL_MODE;
        rvalue |= mgt_commit_list(priv, &u, 1);
+       rvalue |= mgt_update_addr(priv);
 
        if (rvalue) {
                /* some request have failed. The device might be in an
                   incoherent state. We should reset it ! */
                printk(KERN_DEBUG "%s: mgt_commit has failed. Restart the "
-                "device \n", priv->ndev->name);
+                      "device \n", priv->ndev->name);
        }
-
-       /* update the MAC addr. As it's not cached, no lock will be acquired by
-        * the mgt_get_request
-        */
-       mgt_get_request(priv, GEN_OID_MACADDRESS, 0, NULL, &r);
-       memcpy(priv->ndev->dev_addr, r.ptr, 6);
-       kfree(r.ptr);
-
 }
 
 /* This will tell you if you are allowed to answer a mlme(ex) request .*/
@@ -687,13 +697,13 @@ mgt_oidtonum(u32 oid)
 {
        int i;
 
-       for (i = 0; i < OID_NUM_LAST - 1; i++)
+       for (i = 0; i < OID_NUM_LAST; i++)
                if (isl_oid[i].oid == oid)
                        return i;
 
        printk(KERN_DEBUG "looking for an unknown oid 0x%x", oid);
 
-       return 0;
+       return OID_NUM_LAST;
 }
 
 int
@@ -713,8 +723,11 @@ mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str)
        case OID_TYPE_BSS:{
                        struct obj_bss *bss = r->ptr;
                        return snprintf(str, PRIV_STR_SIZE,
-                                       "age=%u\nchannel=%u\n\
-                                       capinfo=0x%X\nrates=0x%X\nbasic_rates=0x%X\n", bss->age, bss->channel, bss->capinfo, bss->rates, bss->basic_rates);
+                                       "age=%u\nchannel=%u\n"
+                                       "capinfo=0x%X\nrates=0x%X\n"
+                                       "basic_rates=0x%X\n", bss->age,
+                                       bss->channel, bss->capinfo,
+                                       bss->rates, bss->basic_rates);
                }
                break;
        case OID_TYPE_BSSLIST:{
@@ -723,7 +736,9 @@ mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str)
                        k = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", list->nr);
                        for (i = 0; i < list->nr; i++)
                                k += snprintf(str + k, PRIV_STR_SIZE - k,
-                                             "bss[%u] : \nage=%u\nchannel=%u\ncapinfo=0x%X\nrates=0x%X\nbasic_rates=0x%X\n",
+                                             "bss[%u] : \nage=%u\nchannel=%u\n"
+                                             "capinfo=0x%X\nrates=0x%X\n"
+                                             "basic_rates=0x%X\n",
                                              i, list->bsslist[i].age,
                                              list->bsslist[i].channel,
                                              list->bsslist[i].capinfo,
@@ -745,16 +760,17 @@ mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str)
                break;
        case OID_TYPE_MLME:{
                        struct obj_mlme *mlme = r->ptr;
-                       return snprintf(str, PRIV_STR_SIZE, "id=0x%X\nstate=0x%X\n\
-                                code=0x%X\n", mlme->id, mlme->state,
-                                       mlme->code);
+                       return snprintf(str, PRIV_STR_SIZE,
+                                       "id=0x%X\nstate=0x%X\ncode=0x%X\n",
+                                       mlme->id, mlme->state, mlme->code);
                }
                break;
        case OID_TYPE_MLMEEX:{
                        struct obj_mlmeex *mlme = r->ptr;
-                       return snprintf(str, PRIV_STR_SIZE, "id=0x%X\nstate=0x%X\n\
-                                code=0x%X\nsize=0x%X\n", mlme->id, mlme->state,
-                                       mlme->code, mlme->size);
+                       return snprintf(str, PRIV_STR_SIZE,
+                                       "id=0x%X\nstate=0x%X\n"
+                                       "code=0x%X\nsize=0x%X\n", mlme->id,
+                                       mlme->state, mlme->code, mlme->size);
                }
                break;
        case OID_TYPE_SSID:{
index cd8167e..caf5eb3 100644 (file)
@@ -38,7 +38,7 @@ void mgt_le_to_cpu(int, void *);
 int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
 
 int mgt_get_request(islpci_private *, enum oid_num_t, int, void *,
-                    union oid_res_t *);
+                   union oid_res_t *);
 
 int mgt_commit_list(islpci_private *, enum oid_num_t *, int);
 
index ee328d5..5eb32a9 100644 (file)
@@ -1841,7 +1841,7 @@ wl_his_gather(struct net_device * dev,
 #endif /* HISTOGRAM */
 
 static inline int
-wl_netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+wl_netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
        u32 ethcmd;
 
@@ -2764,7 +2764,7 @@ wavelan_ioctl(struct net_device * dev,    /* Device on wich the ioctl apply */
   switch(cmd)
     {
     case SIOCETHTOOL:
-      ret = wl_netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+      ret = wl_netdev_ethtool_ioctl(dev, rq->ifr_data);
       break;
 
       /* ------------------- OTHER IOCTL ------------------- */
index ed4acc1..4e62fa6 100644 (file)
@@ -1487,7 +1487,7 @@ struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev)
        return wstats;
 }
 
-static inline int wl3501_ethtool_ioctl(struct net_device *dev, void *uaddr)
+static inline int wl3501_ethtool_ioctl(struct net_device *dev, void __user *uaddr)
 {
        u32 ethcmd;
        int rc = -EFAULT;
@@ -1532,7 +1532,7 @@ static int wl3501_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        if (netif_device_present(dev)) {
                rc = -EOPNOTSUPP;
                if (cmd == SIOCETHTOOL)
-                       rc = wl3501_ethtool_ioctl(dev, (void *)rq->ifr_data);
+                       rc = wl3501_ethtool_ioctl(dev, rq->ifr_data);
        }
        return rc;
 }
index 9994de2..ef0c797 100644 (file)
@@ -448,7 +448,7 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev,
 
        np = dev->priv;
 
-       if (pci_request_regions(pdev, dev->name))
+       if (pci_request_regions(pdev, DRV_NAME))
                goto err_out_free_netdev;
 
        pci_set_master (pdev);
@@ -1201,13 +1201,8 @@ static int yellowfin_rx(struct net_device *dev)
                                        break;
                                skb->dev = dev;
                                skb_reserve(skb, 2);    /* 16 byte align the IP header */
-#if HAS_IP_COPYSUM
                                eth_copy_and_sum(skb, rx_skb->tail, pkt_len, 0);
                                skb_put(skb, pkt_len);
-#else
-                               memcpy(skb_put(skb, pkt_len), 
-                                       rx_skb->tail, pkt_len);
-#endif
                                pci_dma_sync_single_for_device(yp->pci_dev, desc->addr,
                                                                                           yp->rx_buf_sz,
                                                                                           PCI_DMA_FROMDEVICE);
@@ -1405,7 +1400,7 @@ static void set_rx_mode(struct net_device *dev)
        outw(cfg_value | 0x1000, ioaddr + Cnfg);
 }
 
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
        struct yellowfin_private *np = dev->priv;
        u32 ethcmd;
@@ -1433,11 +1428,11 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct yellowfin_private *np = dev->priv;
        long ioaddr = dev->base_addr;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+       struct mii_ioctl_data *data = if_mii(rq);
 
        switch(cmd) {
        case SIOCETHTOOL:
-               return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+               return netdev_ethtool_ioctl(dev, rq->ifr_data);
        case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
                data->phy_id = np->phys[0] & 0x1f;
                /* Fall Through */
index d721fc6..8ab6e12 100644 (file)
@@ -36,6 +36,8 @@
 #include "8390.h"
 
 
+#define DRV_NAME       "zorro8390"
+
 #define NE_BASE                (dev->base_addr)
 #define NE_CMD         (0x00*2)
 #define NE_DATAPORT    (0x10*2)        /* NatSemi-defined port window offset. */
@@ -115,7 +117,7 @@ static int __devinit zorro8390_init_one(struct zorro_dev *z,
     if (!dev)
        return -ENOMEM;
     SET_MODULE_OWNER(dev);
-    if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, dev->name)) {
+    if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, DRV_NAME)) {
        free_netdev(dev);
        return -EBUSY;
     }
@@ -198,7 +200,7 @@ static int __devinit zorro8390_init(struct net_device *dev,
     dev->irq = IRQ_AMIGA_PORTS;
 
     /* Install the Interrupt handler */
-    i = request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, dev->name, dev);
+    i = request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, DRV_NAME, dev);
     if (i) return i;
 
     for(i = 0; i < ETHER_ADDR_LEN; i++) {
index c4f3482..e853f34 100644 (file)
@@ -44,7 +44,6 @@
 #include <asm/byteorder.h>
 #include <asm/cache.h>         /* for L1_CACHE_BYTES */
 #include <asm/uaccess.h>
-#include <asm/pgalloc.h>
 #include <asm/page.h>
 #include <asm/dma.h>
 #include <asm/io.h>
index bd21c5f..57e6385 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/pci.h>
 
 #include <asm/uaccess.h>
-#include <asm/pgalloc.h>
 
 #include <asm/io.h>
 #include <asm/hardware.h>
index b3f33a1..6e4965e 100644 (file)
        1676  NetXtreme BCM5750 Gigabit Ethernet
        1677  NetXtreme BCM5751 Gigabit Ethernet
        167c  NetXtreme BCM5750M Gigabit Ethernet
+       167d  NetXtreme BCM5751M Gigabit Ethernet
+       167e  NetXtreme BCM5751F Gigabit Ethernet
        1696  NetXtreme BCM5782 Gigabit Ethernet
                103c 12bc  HP d530 CMT (DG746A)
                14e4 000d  NetXtreme BCM5782 1000Base-T
        169c  NetXtreme BCM5788 Gigabit Ethernet
+       169d  NetXtreme BCM5789 Gigabit Ethernet
        16a6  NetXtreme BCM5702X Gigabit Ethernet
                0e11 00bb  NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
                1028 0126  BCM5702 1000Base-T
index 7e93bfc..d5d487e 100644 (file)
@@ -797,7 +797,7 @@ out:
 
 /*====================================================================*/
 
-static ssize_t ds_read(struct file *file, char *buf,
+static ssize_t ds_read(struct file *file, char __user *buf,
                       size_t count, loff_t *ppos)
 {
     struct pcmcia_bus_socket *s;
@@ -819,14 +819,14 @@ static ssize_t ds_read(struct file *file, char *buf,
 
     ret = wait_event_interruptible(s->queue, !queue_empty(user));
     if (ret == 0)
-       ret = put_user(get_queued_event(user), (int *)buf) ? -EFAULT : 4;
+       ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
 
     return ret;
 } /* ds_read */
 
 /*====================================================================*/
 
-static ssize_t ds_write(struct file *file, const char *buf,
+static ssize_t ds_write(struct file *file, const char __user *buf,
                        size_t count, loff_t *ppos)
 {
     struct pcmcia_bus_socket *s;
@@ -849,7 +849,7 @@ static ssize_t ds_write(struct file *file, const char *buf,
 
     if (s->req_pending) {
        s->req_pending--;
-       get_user(s->req_result, (int *)buf);
+       get_user(s->req_result, (int __user *)buf);
        if ((s->req_result != 0) || (s->req_pending == 0))
            wake_up_interruptible(&s->request);
     } else
@@ -888,6 +888,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
                    u_int cmd, u_long arg)
 {
     struct pcmcia_bus_socket *s;
+    void __user *uarg = (char __user *)arg;
     u_int size;
     int ret, err;
     ds_ioctl_arg_t buf;
@@ -911,14 +912,14 @@ static int ds_ioctl(struct inode * inode, struct file * file,
        return -EPERM;
        
     if (cmd & IOC_IN) {
-       err = verify_area(VERIFY_READ, (char *)arg, size);
+       err = verify_area(VERIFY_READ, uarg, size);
        if (err) {
            ds_dbg(3, "ds_ioctl(): verify_read = %d\n", err);
            return err;
        }
     }
     if (cmd & IOC_OUT) {
-       err = verify_area(VERIFY_WRITE, (char *)arg, size);
+       err = verify_area(VERIFY_WRITE, uarg, size);
        if (err) {
            ds_dbg(3, "ds_ioctl(): verify_write = %d\n", err);
            return err;
@@ -927,7 +928,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
     
     err = ret = 0;
     
-    if (cmd & IOC_IN) __copy_from_user((char *)&buf, (char *)arg, size);
+    if (cmd & IOC_IN) __copy_from_user((char *)&buf, uarg, size);
     
     switch (cmd) {
     case DS_ADJUST_RESOURCE_INFO:
@@ -1042,7 +1043,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
        }
     }
 
-    if (cmd & IOC_OUT) __copy_to_user((char *)arg, (char *)&buf, size);
+    if (cmd & IOC_OUT) __copy_to_user(uarg, (char *)&buf, size);
 
     return err;
 } /* ds_ioctl */
index e98adb1..120569b 100644 (file)
@@ -1372,8 +1372,15 @@ static int __init init_i82365(void)
 {
     int i, ret;
 
-    if (driver_register(&i82365_driver))
-       return -1;
+    ret = driver_register(&i82365_driver);
+    if (ret)
+       return ret;
+
+    ret = platform_device_register(&i82365_device);
+    if (ret) {
+       driver_unregister(&i82365_driver);
+       return ret;
+    }
 
     printk(KERN_INFO "Intel ISA PCIC probe: ");
     sockets = 0;
@@ -1382,12 +1389,11 @@ static int __init init_i82365(void)
 
     if (sockets == 0) {
        printk("not found.\n");
+       platform_device_unregister(&i82365_device);
        driver_unregister(&i82365_driver);
        return -ENODEV;
     }
 
-    platform_device_register(&i82365_device);
-
     /* Set up interrupt handler(s) */
     if (grab_irq != 0)
        request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
index ef574af..491d11b 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/cpufreq.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
-#include <linux/notifier.h>
 #include <linux/spinlock.h>
 
 #include <asm/hardware.h>
@@ -133,6 +132,39 @@ static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
        return pxa2xx_pcmcia_set_mcxx(skt, clk);
 }
 
+#ifdef CONFIG_CPU_FREQ
+
+static int
+pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
+                              unsigned long val,
+                              struct cpufreq_freqs *freqs)
+{
+#warning "it's not clear if this is right since the core CPU (N) clock has no effect on the memory (L) clock"
+       switch (val) {
+       case CPUFREQ_PRECHANGE:
+               if (freqs->new > freqs->old) {
+                       debug(skt, 2, "new frequency %u.%uMHz > %u.%uMHz, "
+                              "pre-updating\n",
+                              freqs->new / 1000, (freqs->new / 100) % 10,
+                              freqs->old / 1000, (freqs->old / 100) % 10);
+                       pxa2xx_pcmcia_set_mcxx(skt, freqs->new);
+               }
+               break;
+
+       case CPUFREQ_POSTCHANGE:
+               if (freqs->new < freqs->old) {
+                       debug(skt, 2, "new frequency %u.%uMHz < %u.%uMHz, "
+                              "post-updating\n",
+                              freqs->new / 1000, (freqs->new / 100) % 10,
+                              freqs->old / 1000, (freqs->old / 100) % 10);
+                       pxa2xx_pcmcia_set_mcxx(skt, freqs->new);
+               }
+               break;
+       }
+       return 0;
+}
+#endif
+
 int pxa2xx_drv_pcmcia_probe(struct device *dev)
 {
        int ret;
@@ -181,6 +213,9 @@ int pxa2xx_drv_pcmcia_probe(struct device *dev)
 
        /* Provide our PXA2xx specific timing routines. */
        ops->set_timing  = pxa2xx_pcmcia_set_timing;
+#ifdef CONFIG_CPU_FREQ
+       ops->frequency_change = pxa2xx_pcmcia_frequency_change;
+#endif
 
        ret = soc_common_drv_pcmcia_probe(dev, ops, first, nr);
 
@@ -227,101 +262,13 @@ static struct device_driver pxa2xx_pcmcia_driver = {
        .bus            = &platform_bus_type,
 };
 
-#ifdef CONFIG_CPU_FREQ
-
-/*
- * When pxa2xx_pcmcia_notifier() decides that a MC{IO,MEM,ATT} adjustment (due
- * to a core clock frequency change) is needed, this routine establishes
- * new values consistent with the clock speed `clock'.
- */
-static void pxa2xx_pcmcia_update_mcxx(unsigned int clock)
-{
-       struct soc_pcmcia_socket *skt;
-
-       down(&soc_sockets_lock);
-       list_for_each_entry(skt, &soc_sockets, node) {
-               pxa2xx_pcmcia_set_mcxx(skt, clock);
-       }
-       up(&soc_sockets_lock);
-}
-
-/*
- * When changing the processor L clock frequency, it is necessary
- * to adjust the MCXX timings accordingly. We've recorded the timings
- * requested by Card Services, so this is just a matter of finding
- * out what our current speed is, and then recomputing the new MCXX
- * values.
- *
- * Returns: 0 on success, -1 on error
- */
-static int
-pxa2xx_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
-{
-       struct cpufreq_freqs *freqs = data;
-
-#warning "it's not clear if this is right since the core CPU (N) clock has no effect on the memory (L) clock"
-       switch (val) {
-               case CPUFREQ_PRECHANGE:
-                       if (freqs->new > freqs->old) {
-                               debug( 2, "new frequency %u.%uMHz > %u.%uMHz, "
-                                               "pre-updating\n",
-                                               freqs->new / 1000, (freqs->new / 100) % 10,
-                                               freqs->old / 1000, (freqs->old / 100) % 10);
-                               pxa2xx_pcmcia_update_mcxx(freqs->new);
-                       }
-                       break;
-
-               case CPUFREQ_POSTCHANGE:
-                       if (freqs->new < freqs->old) {
-                               debug( 2, "new frequency %u.%uMHz < %u.%uMHz, "
-                                               "post-updating\n",
-                                               freqs->new / 1000, (freqs->new / 100) % 10,
-                                               freqs->old / 1000, (freqs->old / 100) % 10);
-                               pxa2xx_pcmcia_update_mcxx(freqs->new);
-                       }
-                       break;
-       }
-
-       return 0;
-}
-
-static struct notifier_block pxa2xx_pcmcia_notifier_block = {
-       .notifier_call  = pxa2xx_pcmcia_notifier
-};
-
-static int __init pxa2xx_pcmcia_cpufreq_init(void)
-{
-       int ret;
-
-       ret = cpufreq_register_notifier(&pxa2xx_pcmcia_notifier_block,
-                                       CPUFREQ_TRANSITION_NOTIFIER);
-       if (ret < 0)
-               printk(KERN_ERR "Unable to register CPU frequency change "
-                               "notifier for PCMCIA (%d)\n", ret);
-       return ret;
-}
-
-static void __exit pxa2xx_pcmcia_cpufreq_exit(void)
-{
-       cpufreq_unregister_notifier(&pxa2xx_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
-}
-
-#else
-#define pxa2xx_pcmcia_cpufreq_init()
-#define pxa2xx_pcmcia_cpufreq_exit()
-#endif
-
 static int __init pxa2xx_pcmcia_init(void)
 {
-       int ret = driver_register(&pxa2xx_pcmcia_driver);
-       if (ret == 0)
-               pxa2xx_pcmcia_cpufreq_init();
-       return ret;
+       return driver_register(&pxa2xx_pcmcia_driver);
 }
 
 static void __exit pxa2xx_pcmcia_exit(void)
 {
-       pxa2xx_pcmcia_cpufreq_exit();
        driver_unregister(&pxa2xx_pcmcia_driver);
 }
 
index c18f286..e22a57a 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/hardware.h>
 #include <asm/hardware/sa1111.h>
 #include <asm/mach-types.h>
+#include <asm/arch/lubbock.h>
 
 #include "sa1111_generic.h"
 
index af85842..fe62a59 100644 (file)
@@ -24,6 +24,8 @@
 #include <asm/hardware.h>
 #include <asm/irq.h>
 
+#include <asm/arch/mainstone.h>
+
 #include "soc_common.h"
 
 
index fb634ab..db04ffb 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/cpufreq.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
-#include <linux/notifier.h>
 #include <linux/spinlock.h>
 
 #include <asm/hardware.h>
@@ -111,6 +110,32 @@ sa1100_pcmcia_set_mecr(struct soc_pcmcia_socket *skt, unsigned int cpu_clock)
        return 0;
 }
 
+#ifdef CONFIG_CPU_FREQ
+static int
+sa1100_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
+                              unsigned long val,
+                              struct cpufreq_freqs *freqs)
+{
+       switch (val) {
+       case CPUFREQ_PRECHANGE:
+               if (freqs->new > freqs->old)
+                       sa1100_pcmcia_set_mecr(skt, freqs->new);
+               break;
+
+       case CPUFREQ_POSTCHANGE:
+               if (freqs->new < freqs->old)
+                       sa1100_pcmcia_set_mecr(skt, freqs->new);
+               break;
+       case CPUFREQ_RESUMECHANGE:
+               sa1100_pcmcia_set_mecr(skt, freqs->new);
+               break;
+       }
+
+       return 0;
+}
+
+#endif
+
 static int
 sa1100_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
 {
@@ -152,90 +177,23 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
        /* Provide our SA11x0 specific timing routines. */
        ops->set_timing  = sa1100_pcmcia_set_timing;
        ops->show_timing = sa1100_pcmcia_show_timing;
+#ifdef CONFIG_CPU_FREQ
+       ops->frequency_change = sa1100_pcmcia_frequency_change;
+#endif
 
        return soc_common_drv_pcmcia_probe(dev, ops, first, nr);
 }
 EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
 
-#ifdef CONFIG_CPU_FREQ
-
-/* sa1100_pcmcia_update_mecr()
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * When sa1100_pcmcia_notifier() decides that a MECR adjustment (due
- * to a core clock frequency change) is needed, this routine establishes
- * new BS_xx values consistent with the clock speed `clock'.
- */
-static void sa1100_pcmcia_update_mecr(unsigned int clock)
-{
-       struct soc_pcmcia_socket *skt;
-
-       down(&soc_pcmcia_sockets_lock);
-       list_for_each_entry(skt, &soc_pcmcia_sockets, node)
-               sa1100_pcmcia_set_mecr(skt, clock);
-       up(&soc_pcmcia_sockets_lock);
-}
-
-/* sa1100_pcmcia_notifier()
- * ^^^^^^^^^^^^^^^^^^^^^^^^
- * When changing the processor core clock frequency, it is necessary
- * to adjust the MECR timings accordingly. We've recorded the timings
- * requested by Card Services, so this is just a matter of finding
- * out what our current speed is, and then recomputing the new MECR
- * values.
- *
- * Returns: 0 on success, -1 on error
- */
-static int
-sa1100_pcmcia_notifier(struct notifier_block *nb, unsigned long val,
-                      void *data)
-{
-       struct cpufreq_freqs *freqs = data;
-
-       switch (val) {
-       case CPUFREQ_PRECHANGE:
-               if (freqs->new > freqs->old)
-                       sa1100_pcmcia_update_mecr(freqs->new);
-               break;
-
-       case CPUFREQ_POSTCHANGE:
-               if (freqs->new < freqs->old)
-                       sa1100_pcmcia_update_mecr(freqs->new);
-               break;
-       case CPUFREQ_RESUMECHANGE:
-               sa1100_pcmcia_update_mecr(freqs->new);
-               break;
-       }
-
-       return 0;
-}
-
-static struct notifier_block sa1100_pcmcia_notifier_block = {
-       .notifier_call  = sa1100_pcmcia_notifier
-};
-
 static int __init sa11xx_pcmcia_init(void)
 {
-       int ret;
-
-       printk(KERN_INFO "SA11xx PCMCIA\n");
-
-       ret = cpufreq_register_notifier(&sa1100_pcmcia_notifier_block,
-                                       CPUFREQ_TRANSITION_NOTIFIER);
-       if (ret < 0)
-               printk(KERN_ERR "Unable to register CPU frequency change "
-                       "notifier (%d)\n", ret);
-
-       return ret;
+       return 0;
 }
 module_init(sa11xx_pcmcia_init);
 
-static void __exit sa11xx_pcmcia_exit(void)
-{
-       cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
-}
+static void __exit sa11xx_pcmcia_exit(void) {}
 
 module_exit(sa11xx_pcmcia_exit);
-#endif
 
 MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
 MODULE_DESCRIPTION("Linux PCMCIA Card Services: SA-11xx core socket driver");
index ff8b521..6d393e7 100644 (file)
@@ -31,6 +31,7 @@
 ======================================================================*/
 
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
@@ -39,6 +40,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
+#include <linux/cpufreq.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -614,6 +616,49 @@ struct skt_dev_info {
 #define SKT_DEV_INFO_SIZE(n) \
        (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
 
+#ifdef CONFIG_CPU_FREQ
+static int
+soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
+{
+       struct soc_pcmcia_socket *skt;
+       struct cpufreq_freqs *freqs = data;
+       int ret = 0;
+
+       down(&soc_pcmcia_sockets_lock);
+       list_for_each_entry(skt, &soc_pcmcia_sockets, node)
+               if ( skt->ops->frequency_change )
+                       ret += skt->ops->frequency_change(skt, val, freqs);
+       up(&soc_pcmcia_sockets_lock);
+
+       return ret;
+}
+
+static struct notifier_block soc_pcmcia_notifier_block = {
+       .notifier_call  = soc_pcmcia_notifier
+};
+
+static int soc_pcmcia_cpufreq_register(void)
+{
+       int ret;
+
+       ret = cpufreq_register_notifier(&soc_pcmcia_notifier_block,
+                                       CPUFREQ_TRANSITION_NOTIFIER);
+       if (ret < 0)
+               printk(KERN_ERR "Unable to register CPU frequency change "
+                               "notifier for PCMCIA (%d)\n", ret);
+       return ret;
+}
+
+static void soc_pcmcia_cpufreq_unregister(void)
+{
+       cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+#else
+#define soc_pcmcia_cpufreq_register()
+#define soc_pcmcia_cpufreq_unregister()
+#endif
+
 int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
 {
        struct skt_dev_info *sinfo;
@@ -692,6 +737,9 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
                        goto out_err_5;
                }
 
+               if ( list_empty(&soc_pcmcia_sockets) )
+                       soc_pcmcia_cpufreq_register();
+
                list_add(&skt->node, &soc_pcmcia_sockets);
 
                /*
@@ -789,6 +837,9 @@ int soc_common_drv_pcmcia_remove(struct device *dev)
                release_resource(&skt->res_io);
                release_resource(&skt->res_skt);
        }
+       if ( list_empty(&soc_pcmcia_sockets) )
+               soc_pcmcia_cpufreq_unregister();
+
        up(&soc_pcmcia_sockets_lock);
 
        kfree(sinfo);
index 60e3019..f77923c 100644 (file)
@@ -10,6 +10,7 @@
 #define _ASM_ARCH_PCMCIA
 
 /* include the world */
+#include <linux/cpufreq.h>
 #include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -103,6 +104,13 @@ struct pcmcia_low_level {
        unsigned int (*get_timing)(struct soc_pcmcia_socket *, unsigned int, unsigned int);
        int (*set_timing)(struct soc_pcmcia_socket *);
        int (*show_timing)(struct soc_pcmcia_socket *, char *);
+
+#ifdef CONFIG_CPU_FREQ
+       /*
+        * CPUFREQ support.
+        */
+       int (*frequency_change)(struct soc_pcmcia_socket *, unsigned long, struct cpufreq_freqs *);
+#endif
 };
 
 
index b0d716e..767b2c1 100644 (file)
@@ -1078,6 +1078,7 @@ static struct pci_device_id yenta_table [] = {
        CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1451A, TI12XX),
        CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1510, TI12XX),
        CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, TI12XX),
+       CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1620, TI12XX),
        CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4410, TI12XX),
        CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4450, TI12XX),
        CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4451, TI12XX),
index 5adaac6..ee6d1ed 100644 (file)
@@ -68,13 +68,8 @@ MODULE_PARM(isapnp_verbose, "i");
 MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
 MODULE_LICENSE("GPL");
 
-#ifdef CONFIG_X86_PC9800
-#define _PIDXR         0x259
-#define _PNPWRP                0xa59
-#else
 #define _PIDXR         0x279
 #define _PNPWRP                0xa79
-#endif
 
 /* short tags */
 #define _STAG_PNPVERNO         0x01
index 0a94ee9..cf54b0a 100644 (file)
@@ -55,7 +55,7 @@ static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence)
        return (file->f_pos = new);
 }
 
-static ssize_t isapnp_proc_bus_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+static ssize_t isapnp_proc_bus_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
        struct inode *ino = file->f_dentry->d_inode;
        struct proc_dir_entry *dp = PDE(ino);
index 063ae5e..88fcd16 100644 (file)
@@ -176,7 +176,7 @@ static int proc_read_node(char *buf, char **start, off_t pos,
        return len;
 }
 
-static int proc_write_node(struct file *file, const char *buf,
+static int proc_write_node(struct file *file, const char __user *buf,
                            unsigned long count, void *data)
 {
        struct pnp_bios_node *node;
index 9d30ebf..6997d61 100644 (file)
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.141 $
+ * $Revision: 1.142 $
  */
 
 #include <linux/config.h>
@@ -37,6 +37,7 @@
  * SECTION: exported variables of dasd.c
  */
 debug_info_t *dasd_debug_area;
+struct dasd_discipline *dasd_diag_discipline_pointer;
 
 MODULE_AUTHOR("Holger Smolinski <Holger.Smolinski@de.ibm.com>");
 MODULE_DESCRIPTION("Linux on S/390 DASD device driver,"
@@ -1990,6 +1991,8 @@ dasd_init(void)
 
        DBF_EVENT(DBF_EMERG, "%s", "debug area created");
 
+       dasd_diag_discipline_pointer = NULL;
+
        rc = devfs_mk_dir("dasd");
        if (rc)
                goto failed;
@@ -2022,6 +2025,7 @@ module_init(dasd_init);
 module_exit(dasd_exit);
 
 EXPORT_SYMBOL(dasd_debug_area);
+EXPORT_SYMBOL(dasd_diag_discipline_pointer);
 
 EXPORT_SYMBOL(dasd_add_request_head);
 EXPORT_SYMBOL(dasd_add_request_tail);
index 8139ffd..ed1ab47 100644 (file)
@@ -58,7 +58,7 @@ static int
 dasd_ioctl_readall_cmb(struct block_device *bdev, int no, long args)
 {
        struct dasd_device *device;
-       struct cmbdata * __user udata;
+       struct cmbdata __user *udata;
        struct cmbdata data;
        size_t size;
        int ret;
@@ -66,7 +66,7 @@ dasd_ioctl_readall_cmb(struct block_device *bdev, int no, long args)
        device = bdev->bd_disk->private_data;
        if (!device)
                return -EINVAL;
-       udata = (void *) args;
+       udata = (void __user *) args;
        size = _IOC_SIZE(no);
 
        if (!access_ok(VERIFY_WRITE, udata, size))
index 67a896c..888aeb3 100644 (file)
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.34 $
+ * $Revision: 1.36 $
  */
 
 #include <linux/config.h>
@@ -35,6 +35,8 @@
 
 MODULE_LICENSE("GPL");
 
+struct dasd_discipline dasd_diag_discipline;
+
 struct dasd_diag_private {
        struct dasd_diag_characteristics rdc_data;
        struct dasd_diag_rw_io iob;
@@ -292,7 +294,7 @@ dasd_diag_check_device(struct dasd_device *device)
                mdsk_term_io(device);
        }
        if (bsize <= PAGE_SIZE && label[3] == bsize &&
-           label[0] == 0xc3d4e2f1 && label[13] != 0) {
+           label[0] == 0xc3d4e2f1) {
                device->blocks = label[7];
                device->bp_block = bsize;
                device->s2b_shift = 0;  /* bits to shift 512 to get a block */
@@ -489,6 +491,7 @@ dasd_diag_init(void)
 
        ctl_set_bit(0, 9);
        register_external_interrupt(0x2603, dasd_ext_handler);
+       dasd_diag_discipline_pointer = &dasd_diag_discipline;
        return 0;
 }
 
@@ -503,6 +506,7 @@ dasd_diag_cleanup(void)
        }
        unregister_external_interrupt(0x2603, dasd_ext_handler);
        ctl_clear_bit(0, 9);
+       dasd_diag_discipline_pointer = NULL;
 }
 
 module_init(dasd_diag_init);
index 0853202..9b667cd 100644 (file)
@@ -1289,7 +1289,7 @@ dasd_eckd_performance(struct block_device *bdev, int no, long args)
                /* Prepare for Read Subsystem Data */
                prssdp = (struct dasd_psf_prssd_data *) cqr->data;
                stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
-               rc = copy_to_user((long *) args, (long *) stats,
+               rc = copy_to_user((long __user *) args, (long *) stats,
                                  sizeof(struct dasd_rssd_perf_stats_t));
        }
        dasd_sfree_request(cqr, cqr->device);
@@ -1319,10 +1319,10 @@ dasd_eckd_get_attrib (struct block_device *bdev, int no, long args)
 
         private = (struct dasd_eckd_private *) device->private;
         attrib = private->attrib;
-       
-        rc = copy_to_user((long *) args, (long *) &attrib,
+
+        rc = copy_to_user((long __user *) args, (long *) &attrib,
                          sizeof (struct attrib_data_t));
-       
+
        return rc;
 }
 
@@ -1346,7 +1346,7 @@ dasd_eckd_set_attrib(struct block_device *bdev, int no, long args)
        if (device == NULL)
                return -ENODEV;
 
-       if (copy_from_user(&attrib, (void *) args,
+       if (copy_from_user(&attrib, (void __user *) args,
                           sizeof (struct attrib_data_t))) {
                return -EFAULT;
        }
index 9967c08..b222f95 100644 (file)
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.57 $
+ * $Revision: 1.58 $
  */
 
 #ifndef DASD_INT_H
@@ -260,12 +260,7 @@ struct dasd_discipline {
        int (*fill_info) (struct dasd_device *, struct dasd_information2_t *);
 };
 
-extern struct dasd_discipline dasd_diag_discipline;
-#ifdef CONFIG_DASD_DIAG
-#define dasd_diag_discipline_pointer (&dasd_diag_discipline)
-#else
-#define dasd_diag_discipline_pointer (0)
-#endif
+extern struct dasd_discipline *dasd_diag_discipline_pointer;
 
 struct dasd_device {
        /* Block device stuff. */
index 3efdcad..8cbddce 100644 (file)
@@ -120,7 +120,7 @@ static int
 dasd_ioctl_api_version(struct block_device *bdev, int no, long args)
 {
        int ver = DASD_API_VERSION;
-       return put_user(ver, (int *) args);
+       return put_user(ver, (int __user *) args);
 }
 
 /*
@@ -305,7 +305,7 @@ dasd_ioctl_format(struct block_device *bdev, int no, long args)
                return -ENODEV;
        if (test_bit(DASD_FLAG_RO, &device->flags))
                return -EROFS;
-       if (copy_from_user(&fdata, (void *) args,
+       if (copy_from_user(&fdata, (void __user *) args,
                           sizeof (struct format_data_t)))
                return -EFAULT;
        if (bdev != bdev->bd_contains) {
@@ -348,7 +348,7 @@ dasd_ioctl_read_profile(struct block_device *bdev, int no, long args)
        if (device == NULL)
                return -ENODEV;
 
-       if (copy_to_user((long *) args, (long *) &device->profile,
+       if (copy_to_user((long __user *) args, (long *) &device->profile,
                         sizeof (struct dasd_profile_info_t)))
                return -EFAULT;
        return 0;
@@ -441,9 +441,9 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args)
                spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
                                       flags);
        }
-       
+
        rc = 0;
-       if (copy_to_user((long *) args, (long *) dasd_info,
+       if (copy_to_user((long __user *) args, (long *) dasd_info,
                         ((no == (unsigned int) BIODASDINFO2) ?
                          sizeof (struct dasd_information2_t) :
                          sizeof (struct dasd_information_t))))
@@ -466,7 +466,7 @@ dasd_ioctl_set_ro(struct block_device *bdev, int no, long args)
        if (bdev != bdev->bd_contains)
                // ro setting is not allowed for partitions
                return -EINVAL;
-       if (get_user(intval, (int *) args))
+       if (get_user(intval, (int __user *) args))
                return -EFAULT;
        device =  bdev->bd_disk->private_data;
        if (device == NULL)
@@ -499,7 +499,7 @@ dasd_ioctl_getgeo(struct block_device *bdev, int no, long args)
        geo = (struct hd_geometry) {};
        device->discipline->fill_geometry(device, &geo);
        geo.start = get_start_sect(bdev) >> device->s2b_shift;
-       if (copy_to_user((struct hd_geometry *) args, &geo,
+       if (copy_to_user((struct hd_geometry __user *) args, &geo,
                         sizeof (struct hd_geometry)))
                return -EFAULT;
 
index 70d6136..7cbc854 100644 (file)
@@ -30,7 +30,7 @@ static struct proc_dir_entry *dasd_devices_entry = NULL;
 static struct proc_dir_entry *dasd_statistics_entry = NULL;
 
 static inline char *
-dasd_get_user_string(const char *user_buf, size_t user_len)
+dasd_get_user_string(const char __user *user_buf, size_t user_len)
 {
        char *buffer;
 
@@ -239,7 +239,7 @@ dasd_statistics_read(char *page, char **start, off_t off,
 }
 
 static int
-dasd_statistics_write(struct file *file, const char *user_buf,
+dasd_statistics_write(struct file *file, const char __user *user_buf,
                      unsigned long user_len, void *data)
 {
 #ifdef CONFIG_DASD_PROFILE
index 8a30b52..ca83f9b 100644 (file)
@@ -76,8 +76,7 @@ struct dcssblk_dev_info {
 };
 
 static struct list_head dcssblk_devices = LIST_HEAD_INIT(dcssblk_devices);
-static rwlock_t dcssblk_devices_lock = RW_LOCK_UNLOCKED;
-
+static struct rw_semaphore dcssblk_devices_sem;
 
 /*
  * release function for segment device.
@@ -92,8 +91,8 @@ dcssblk_release_segment(struct device *dev)
 
 /*
  * get a minor number. needs to be called with
- * write_lock(&dcssblk_devices_lock) and the
- * device needs to be enqueued before the lock is
+ * down_write(&dcssblk_devices_sem) and the
+ * device needs to be enqueued before the semaphore is
  * freed.
  */
 static inline int
@@ -121,7 +120,7 @@ dcssblk_assign_free_minor(struct dcssblk_dev_info *dev_info)
 /*
  * get the struct dcssblk_dev_info from dcssblk_devices
  * for the given name.
- * read_lock(&dcssblk_devices_lock) must be held.
+ * down_read(&dcssblk_devices_sem) must be held.
  */
 static struct dcssblk_dev_info *
 dcssblk_get_device_by_name(char *name)
@@ -136,31 +135,6 @@ dcssblk_get_device_by_name(char *name)
        return NULL;
 }
 
-/*
- * register the device that represents a segment in sysfs,
- * also add the attributes for the device
- */
-static inline int
-dcssblk_register_segment_device(struct device *dev)
-{
-       int rc;
-
-       rc = device_register(dev);
-       if (rc)
-               return rc;
-       rc = device_create_file(dev, &dev_attr_shared);
-       if (rc)
-               goto unregister_dev;
-       rc = device_create_file(dev, &dev_attr_save);
-       if (rc)
-               goto unregister_dev;
-       return rc;
-
-unregister_dev:
-       device_unregister(dev);
-       return rc;
-}
-
 /*
  * device attribute for switching shared/nonshared (exclusive)
  * operation (show + store)
@@ -184,24 +158,24 @@ dcssblk_shared_store(struct device *dev, const char *inbuf, size_t count)
                PRINT_WARN("Invalid value, must be 0 or 1\n");
                return -EINVAL;
        }
-       write_lock(&dcssblk_devices_lock);
+       down_write(&dcssblk_devices_sem);
        dev_info = container_of(dev, struct dcssblk_dev_info, dev);
        if (atomic_read(&dev_info->use_count)) {
                PRINT_ERR("share: segment %s is busy!\n",
                          dev_info->segment_name);
-               write_unlock(&dcssblk_devices_lock);
+               up_write(&dcssblk_devices_sem);
                return -EBUSY;
        }
        if ((inbuf[0] == '1') && (dev_info->is_shared == 1)) {
                PRINT_WARN("Segment %s already loaded in shared mode!\n",
                           dev_info->segment_name);
-               write_unlock(&dcssblk_devices_lock);
+               up_write(&dcssblk_devices_sem);
                return count;
        }
        if ((inbuf[0] == '0') && (dev_info->is_shared == 0)) {
                PRINT_WARN("Segment %s already loaded in exclusive mode!\n",
                           dev_info->segment_name);
-               write_unlock(&dcssblk_devices_lock);
+               up_write(&dcssblk_devices_sem);
                return count;
        }
        if (inbuf[0] == '1') {
@@ -231,7 +205,7 @@ dcssblk_shared_store(struct device *dev, const char *inbuf, size_t count)
                PRINT_INFO("Segment %s reloaded, exclusive (read-write) mode.\n",
                           dev_info->segment_name);
        } else {
-               write_unlock(&dcssblk_devices_lock);
+               up_write(&dcssblk_devices_sem);
                PRINT_WARN("Invalid value, must be 0 or 1\n");
                return -EINVAL;
        }
@@ -262,14 +236,13 @@ dcssblk_shared_store(struct device *dev, const char *inbuf, size_t count)
                                dev_info->segment_name);
                rc = -EPERM;
        }
-       write_unlock(&dcssblk_devices_lock);
+       up_write(&dcssblk_devices_sem);
        goto out;
 
 removeseg:
        PRINT_ERR("Could not reload segment %s, removing it now!\n",
                        dev_info->segment_name);
        list_del(&dev_info->lh);
-       write_unlock(&dcssblk_devices_lock);
 
        del_gendisk(dev_info->gd);
        blk_put_queue(dev_info->dcssblk_queue);
@@ -277,6 +250,7 @@ removeseg:
        put_disk(dev_info->gd);
        device_unregister(dev);
        put_device(dev);
+       up_write(&dcssblk_devices_sem);
 out:
        return rc;
 }
@@ -308,7 +282,7 @@ dcssblk_save_store(struct device *dev, const char *inbuf, size_t count)
        }
        dev_info = container_of(dev, struct dcssblk_dev_info, dev);
 
-       write_lock(&dcssblk_devices_lock);
+       down_write(&dcssblk_devices_sem);
        if (inbuf[0] == '1') {
                if (atomic_read(&dev_info->use_count) == 0) {
                        // device is idle => we save immediately
@@ -332,11 +306,11 @@ dcssblk_save_store(struct device *dev, const char *inbuf, size_t count)
                                        dev_info->segment_name);
                }
        } else {
-               write_unlock(&dcssblk_devices_lock);
+               up_write(&dcssblk_devices_sem);
                PRINT_WARN("Invalid value, must be 0 or 1\n");
                return -EINVAL;
        }
-       write_unlock(&dcssblk_devices_lock);
+       up_write(&dcssblk_devices_sem);
        return count;
 }
 
@@ -375,9 +349,9 @@ dcssblk_add_store(struct device *dev, const char *buf, size_t count)
        /*
         * already loaded?
         */
-       read_lock(&dcssblk_devices_lock);
+       down_read(&dcssblk_devices_sem);
        dev_info = dcssblk_get_device_by_name(local_buf);
-       read_unlock(&dcssblk_devices_lock);
+       up_read(&dcssblk_devices_sem);
        if (dev_info != NULL) {
                PRINT_WARN("Segment %s already loaded!\n", local_buf);
                rc = -EEXIST;
@@ -433,10 +407,10 @@ dcssblk_add_store(struct device *dev, const char *buf, size_t count)
        /*
         * get minor, add to list
         */
-       write_lock(&dcssblk_devices_lock);
+       down_write(&dcssblk_devices_sem);
        rc = dcssblk_assign_free_minor(dev_info);
        if (rc) {
-               write_unlock(&dcssblk_devices_lock);
+               up_write(&dcssblk_devices_sem);
                PRINT_ERR("No free minor number available! "
                          "Unloading segment...\n");
                goto unload_seg;
@@ -444,22 +418,29 @@ dcssblk_add_store(struct device *dev, const char *buf, size_t count)
        sprintf(dev_info->gd->disk_name, "dcssblk%d",
                dev_info->gd->first_minor);
        list_add_tail(&dev_info->lh, &dcssblk_devices);
+
+       if (!try_module_get(THIS_MODULE)) {
+               rc = -ENODEV;
+               goto list_del;
+       }
        /*
         * register the device
         */
-       rc = dcssblk_register_segment_device(&dev_info->dev);
+       rc = device_register(&dev_info->dev);
        if (rc) {
                PRINT_ERR("Segment %s could not be registered RC=%d\n",
                                local_buf, rc);
+               module_put(THIS_MODULE);
                goto list_del;
        }
-
-       if (!try_module_get(THIS_MODULE)) {
-               rc = -ENODEV;
-               goto list_del;
-       }
-
        get_device(&dev_info->dev);
+       rc = device_create_file(&dev_info->dev, &dev_attr_shared);
+       if (rc)
+               goto unregister_dev;
+       rc = device_create_file(&dev_info->dev, &dev_attr_save);
+       if (rc)
+               goto unregister_dev;
+
        add_disk(dev_info->gd);
 
        blk_queue_make_request(dev_info->dcssblk_queue, dcssblk_make_request);
@@ -476,13 +457,24 @@ dcssblk_add_store(struct device *dev, const char *buf, size_t count)
                        break;
        }
        PRINT_DEBUG("Segment %s loaded successfully\n", local_buf);
-       write_unlock(&dcssblk_devices_lock);
+       up_write(&dcssblk_devices_sem);
        rc = count;
        goto out;
 
+unregister_dev:
+       PRINT_ERR("device_create_file() failed!\n");
+       list_del(&dev_info->lh);
+       blk_put_queue(dev_info->dcssblk_queue);
+       dev_info->gd->queue = NULL;
+       put_disk(dev_info->gd);
+       device_unregister(&dev_info->dev);
+       segment_unload(dev_info->segment_name);
+       put_device(&dev_info->dev);
+       up_write(&dcssblk_devices_sem);
+       goto out;
 list_del:
        list_del(&dev_info->lh);
-       write_unlock(&dcssblk_devices_lock);
+       up_write(&dcssblk_devices_sem);
 unload_seg:
        segment_unload(local_buf);
 dealloc_gendisk:
@@ -526,22 +518,21 @@ dcssblk_remove_store(struct device *dev, const char *buf, size_t count)
                goto out_buf;
        }
 
-       write_lock(&dcssblk_devices_lock);
+       down_write(&dcssblk_devices_sem);
        dev_info = dcssblk_get_device_by_name(local_buf);
        if (dev_info == NULL) {
-               write_unlock(&dcssblk_devices_lock);
+               up_write(&dcssblk_devices_sem);
                PRINT_WARN("Segment %s is not loaded!\n", local_buf);
                rc = -ENODEV;
                goto out_buf;
        }
        if (atomic_read(&dev_info->use_count) != 0) {
-               write_unlock(&dcssblk_devices_lock);
+               up_write(&dcssblk_devices_sem);
                PRINT_WARN("Segment %s is in use!\n", local_buf);
                rc = -EBUSY;
                goto out_buf;
        }
        list_del(&dev_info->lh);
-       write_unlock(&dcssblk_devices_lock);
 
        del_gendisk(dev_info->gd);
        blk_put_queue(dev_info->dcssblk_queue);
@@ -552,6 +543,8 @@ dcssblk_remove_store(struct device *dev, const char *buf, size_t count)
        PRINT_DEBUG("Segment %s unloaded successfully\n",
                        dev_info->segment_name);
        put_device(&dev_info->dev);
+       up_write(&dcssblk_devices_sem);
+
        rc = count;
 out_buf:
        kfree(local_buf);
@@ -587,7 +580,7 @@ dcssblk_release(struct inode *inode, struct file *filp)
                rc = -ENODEV;
                goto out;
        }
-       write_lock(&dcssblk_devices_lock);
+       down_write(&dcssblk_devices_sem);
        if (atomic_dec_and_test(&dev_info->use_count)
            && (dev_info->save_pending)) {
                PRINT_INFO("Segment %s became idle and is being saved now\n",
@@ -595,7 +588,7 @@ dcssblk_release(struct inode *inode, struct file *filp)
                segment_replace(dev_info->segment_name);
                dev_info->save_pending = 0;
        }
-       write_unlock(&dcssblk_devices_lock);
+       up_write(&dcssblk_devices_sem);
        rc = 0;
 out:
        return rc;
@@ -616,7 +609,7 @@ dcssblk_make_request(request_queue_t *q, struct bio *bio)
        dev_info = bio->bi_bdev->bd_disk->private_data;
        if (dev_info == NULL)
                goto fail;
-       if ((bio->bi_sector & 3) != 0 || (bio->bi_size & 4095) != 0)
+       if ((bio->bi_sector & 7) != 0 || (bio->bi_size & 4095) != 0)
                /* Request is not page-aligned. */
                goto fail;
        if (((bio->bi_size >> 9) + bio->bi_sector)
@@ -695,6 +688,7 @@ dcssblk_init(void)
                return rc;
        }
        dcssblk_major = rc;
+       init_rwsem(&dcssblk_devices_sem);
        PRINT_DEBUG("...finished!\n");
        return 0;
 }
index 00885b0..312057e 100644 (file)
@@ -155,7 +155,7 @@ static int xpram_page_in (unsigned long page_addr, unsigned int xpage_index)
 {
        int cc;
 
-       __asm__ __volatile(
+       __asm__ __volatile__ (
                "   lhi   %0,2\n"  /* return unused cc 2 if pgin traps */
                "   .insn rre,0xb22e0000,%1,%2\n"  /* pgin %1,%2 */
                 "0: ipm   %0\n"
@@ -203,7 +203,7 @@ static long xpram_page_out (unsigned long page_addr, unsigned int xpage_index)
 {
        int cc;
 
-       __asm__ __volatile(
+       __asm__ __volatile__ (
                "   lhi   %0,2\n"  /* return unused cc 2 if pgout traps */
                "   .insn rre,0xb22f0000,%1,%2\n"  /* pgout %1,%2 */
                 "0: ipm   %0\n"
@@ -290,7 +290,7 @@ static int xpram_make_request(request_queue_t *q, struct bio *bio)
        unsigned long bytes;
        int i;
 
-       if ((bio->bi_sector & 3) != 0 || (bio->bi_size & 4095) != 0)
+       if ((bio->bi_sector & 7) != 0 || (bio->bi_size & 4095) != 0)
                /* Request is not page-aligned. */
                goto fail;
        if ((bio->bi_size >> 12) > xdev->size)
@@ -332,16 +332,16 @@ fail:
 static int xpram_ioctl (struct inode *inode, struct file *filp,
                 unsigned int cmd, unsigned long arg)
 {
-       struct hd_geometry *geo;
+       struct hd_geometry __user *geo;
        unsigned long size;
-       if (cmd != HDIO_GETGEO)
+       if (cmd != HDIO_GETGEO)
                return -EINVAL;
        /*
         * get geometry: we have to fake one...  trim the size to a
         * multiple of 64 (32k): tell we have 16 sectors, 4 heads,
         * whatever cylinders. Tell also that data starts at sector. 4.
         */
-       geo = (struct hd_geometry *) arg;
+       geo = (struct hd_geometry __user *) arg;
        size = (xpram_pages * 8) & ~0x3f;
        put_user(size >> 6, &geo->cylinders);
        put_user(4, &geo->heads);
@@ -423,7 +423,7 @@ static int __init xpram_setup_sizes(unsigned long pages)
        return 0;
 }
 
-static struct request_queue xpram_queue;
+static struct request_queue *xpram_queue;
 
 static int __init xpram_setup_blkdev(void)
 {
@@ -450,8 +450,13 @@ static int __init xpram_setup_blkdev(void)
         * Assign the other needed values: make request function, sizes and
         * hardsect size. All the minor devices feature the same value.
         */
-       blk_queue_make_request(&xpram_queue, xpram_make_request);
-       blk_queue_hardsect_size(&xpram_queue, 4096);
+       xpram_queue = blk_alloc_queue(GFP_KERNEL);
+       if (!xpram_queue) {
+               rc = -ENOMEM;
+               goto out_unreg;
+       }
+       blk_queue_make_request(xpram_queue, xpram_make_request);
+       blk_queue_hardsect_size(xpram_queue, 4096);
 
        /*
         * Setup device structures.
@@ -467,7 +472,7 @@ static int __init xpram_setup_blkdev(void)
                disk->first_minor = i;
                disk->fops = &xpram_devops;
                disk->private_data = &xpram_devices[i];
-               disk->queue = &xpram_queue;
+               disk->queue = xpram_queue;
                sprintf(disk->disk_name, "slram%d", i);
                sprintf(disk->devfs_name, "slram/%d", i);
                set_capacity(disk, xpram_sizes[i] << 1);
@@ -475,6 +480,9 @@ static int __init xpram_setup_blkdev(void)
        }
 
        return 0;
+out_unreg:
+       devfs_remove("slram");
+       unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
 out:
        while (i--)
                put_disk(xpram_disks[i]);
@@ -493,6 +501,7 @@ static void __exit xpram_exit(void)
        }
        unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
        devfs_remove("slram");
+       blk_cleanup_queue(xpram_queue);
        sysdev_unregister(&xpram_sys_device);
        sysdev_class_unregister(&xpram_sysclass);
 }
index 0e724c8..e92bb94 100644 (file)
@@ -1002,7 +1002,8 @@ tty3215_write(struct tty_struct * tty, int from_user,
        ret = 0;
        while (count > 0) {
                length = count < 80 ? count : 80;
-               length -= copy_from_user(raw->ubuffer, buf, length);
+               length -= copy_from_user(raw->ubuffer,
+                               (const unsigned char __user *)buf, length);
                if (length == 0) {
                        if (!ret)
                                ret = -EFAULT;
index b124ebb..5e35728 100644 (file)
@@ -338,7 +338,7 @@ kbd_keycode(struct kbd_data *kbd, unsigned int keycode)
  * Ioctl stuff.
  */
 static int
-do_kdsk_ioctl(struct kbd_data *kbd, struct kbentry *user_kbe,
+do_kdsk_ioctl(struct kbd_data *kbd, struct kbentry __user *user_kbe,
              int cmd, int perm)
 {
        struct kbentry tmp;
@@ -410,7 +410,7 @@ do_kdsk_ioctl(struct kbd_data *kbd, struct kbentry *user_kbe,
 }
 
 static int
-do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry *u_kbs,
+do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs,
               int cmd, int perm)
 {
        unsigned char kb_func;
@@ -464,9 +464,12 @@ int
 kbd_ioctl(struct kbd_data *kbd, struct file *file,
          unsigned int cmd, unsigned long arg)
 {
-       struct kbdiacrs *a;
+       struct kbdiacrs __user *a;
+       void __user *argp;
        int ct, perm;
 
+       argp = (void __user *)arg;
+
        /*
         * To have permissions to do most of the vt ioctls, we either have
         * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
@@ -474,15 +477,15 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file,
        perm = current->signal->tty == kbd->tty || capable(CAP_SYS_TTY_CONFIG);
        switch (cmd) {
        case KDGKBTYPE:
-               return put_user(KB_101, (char*) arg);
+               return put_user(KB_101, (char __user *)argp);
        case KDGKBENT:
        case KDSKBENT:
-               return do_kdsk_ioctl(kbd, (struct kbentry *)arg, cmd, perm);
+               return do_kdsk_ioctl(kbd, argp, cmd, perm);
        case KDGKBSENT:
        case KDSKBSENT:
-               return do_kdgkb_ioctl(kbd, (struct kbsentry *)arg, cmd, perm);
+               return do_kdgkb_ioctl(kbd, argp, cmd, perm);
        case KDGKBDIACR:
-               a = (struct kbdiacrs *) arg;
+               a = argp;
 
                if (put_user(kbd->accent_table_size, &a->kb_cnt))
                        return -EFAULT;
@@ -492,7 +495,7 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file,
                        return -EFAULT;
                return 0;
        case KDSKBDIACR:
-               a = (struct kbdiacrs *) arg;
+               a = argp;
                if (!perm)
                        return -EPERM;
                if (get_user(ct, &a->kb_cnt))
index 1035707..a1ad375 100644 (file)
@@ -112,46 +112,46 @@ sclp_tty_ioctl(struct tty_struct *tty, struct file * file,
        switch (cmd) {
        case TIOCSCLPSHTAB:
                /* set width of horizontal tab  */
-               if (get_user(sclp_ioctls.htab, (unsigned short *) arg))
+               if (get_user(sclp_ioctls.htab, (unsigned short __user *) arg))
                        rc = -EFAULT;
                else
                        check = 1;
                break;
        case TIOCSCLPGHTAB:
                /* get width of horizontal tab  */
-               if (put_user(sclp_ioctls.htab, (unsigned short *) arg))
+               if (put_user(sclp_ioctls.htab, (unsigned short __user *) arg))
                        rc = -EFAULT;
                break;
        case TIOCSCLPSECHO:
                /* enable/disable echo of input */
-               if (get_user(sclp_ioctls.echo, (unsigned char *) arg))
+               if (get_user(sclp_ioctls.echo, (unsigned char __user *) arg))
                        rc = -EFAULT;
                break;
        case TIOCSCLPGECHO:
                /* Is echo of input enabled ?  */
-               if (put_user(sclp_ioctls.echo, (unsigned char *) arg))
+               if (put_user(sclp_ioctls.echo, (unsigned char __user *) arg))
                        rc = -EFAULT;
                break;
        case TIOCSCLPSCOLS:
                /* set number of columns for output  */
-               if (get_user(sclp_ioctls.columns, (unsigned short *) arg))
+               if (get_user(sclp_ioctls.columns, (unsigned short __user *) arg))
                        rc = -EFAULT;
                else
                        check = 1;
                break;
        case TIOCSCLPGCOLS:
                /* get number of columns for output  */
-               if (put_user(sclp_ioctls.columns, (unsigned short *) arg))
+               if (put_user(sclp_ioctls.columns, (unsigned short __user *) arg))
                        rc = -EFAULT;
                break;
        case TIOCSCLPSNL:
                /* enable/disable writing without final new line character  */
-               if (get_user(sclp_ioctls.final_nl, (signed char *) arg))
+               if (get_user(sclp_ioctls.final_nl, (signed char __user *) arg))
                        rc = -EFAULT;
                break;
        case TIOCSCLPGNL:
                /* Is writing without final new line character enabled ?  */
-               if (put_user(sclp_ioctls.final_nl, (signed char *) arg))
+               if (put_user(sclp_ioctls.final_nl, (signed char __user *) arg))
                        rc = -EFAULT;
                break;
        case TIOCSCLPSOBUF:
@@ -160,7 +160,7 @@ sclp_tty_ioctl(struct tty_struct *tty, struct file * file,
                 * up to next 4kB boundary and stored as number of SCCBs
                 * (4kB Buffers) limitation: 256 x 4kB
                 */
-               if (get_user(obuf, (unsigned int *) arg) == 0) {
+               if (get_user(obuf, (unsigned int __user *) arg) == 0) {
                        if (obuf & 0xFFF)
                                sclp_ioctls.max_sccb = (obuf >> 12) + 1;
                        else
@@ -171,22 +171,22 @@ sclp_tty_ioctl(struct tty_struct *tty, struct file * file,
        case TIOCSCLPGOBUF:
                /* get the maximum buffers size for output  */
                obuf = sclp_ioctls.max_sccb << 12;
-               if (put_user(obuf, (unsigned int *) arg))
+               if (put_user(obuf, (unsigned int __user *) arg))
                        rc = -EFAULT;
                break;
        case TIOCSCLPGKBUF:
                /* get the number of buffers got from kernel at startup */
-               if (put_user(sclp_ioctls.kmem_sccb, (unsigned short *) arg))
+               if (put_user(sclp_ioctls.kmem_sccb, (unsigned short __user *) arg))
                        rc = -EFAULT;
                break;
        case TIOCSCLPSCASE:
                /* enable/disable conversion from upper to lower case */
-               if (get_user(sclp_ioctls.tolower, (unsigned char *) arg))
+               if (get_user(sclp_ioctls.tolower, (unsigned char __user *) arg))
                        rc = -EFAULT;
                break;
        case TIOCSCLPGCASE:
                /* Is conversion from upper to lower case of input enabled? */
-               if (put_user(sclp_ioctls.tolower, (unsigned char *) arg))
+               if (put_user(sclp_ioctls.tolower, (unsigned char __user *) arg))
                        rc = -EFAULT;
                break;
        case TIOCSCLPSDELIM:
@@ -194,7 +194,7 @@ sclp_tty_ioctl(struct tty_struct *tty, struct file * file,
                 * set special character used for separating upper and
                 * lower case, 0x00 disables this feature
                 */
-               if (get_user(sclp_ioctls.delim, (unsigned char *) arg))
+               if (get_user(sclp_ioctls.delim, (unsigned char __user *) arg))
                        rc = -EFAULT;
                break;
        case TIOCSCLPGDELIM:
@@ -202,7 +202,7 @@ sclp_tty_ioctl(struct tty_struct *tty, struct file * file,
                 * get special character used for separating upper and
                 * lower case, 0x00 disables this feature
                 */
-               if (put_user(sclp_ioctls.delim, (unsigned char *) arg))
+               if (put_user(sclp_ioctls.delim, (unsigned char __user *) arg))
                        rc = -EFAULT;
                break;
        case TIOCSCLPSINIT:
@@ -415,7 +415,8 @@ sclp_tty_write(struct tty_struct *tty, int from_user,
        while (count > 0) {
                length = count < SCLP_TTY_BUF_SIZE ?
                        count : SCLP_TTY_BUF_SIZE;
-               length -= copy_from_user(sclp_tty_chars, buf, length);
+               length -= copy_from_user(sclp_tty_chars,
+                               (const unsigned char __user *)buf, length);
                if (length == 0) {
                        if (!ret)
                                ret = -EFAULT;
index 32d4397..22760a1 100644 (file)
@@ -490,7 +490,8 @@ sclp_vt220_write(struct tty_struct *tty, int from_user,
        while (count > 0) {
                length = count < SCLP_VT220_BUF_SIZE ?
                         count : SCLP_VT220_BUF_SIZE;
-               length -= copy_from_user(tty->driver_data, buf, length);
+               length -= copy_from_user(tty->driver_data,
+                               (const unsigned char __user *)buf, length);
                if (length == 0) {
                        if (!ret)
                                return -EFAULT;
index 272bd1c..d04e6c2 100644 (file)
@@ -32,7 +32,7 @@ struct gendisk;
 #ifdef  DBF_LIKE_HELL
 #define DBF_LH(level, str, ...) \
 do { \
-       debug_sprintf_event(tape_dbf_area, level, str, ## __VA_ARGS__); \
+       debug_sprintf_event(TAPE_DBF_AREA, level, str, ## __VA_ARGS__); \
 } while (0)
 #else
 #define DBF_LH(level, str, ...) do {} while(0)
@@ -43,12 +43,12 @@ do { \
  */
 #define DBF_EVENT(d_level, d_str...) \
 do { \
-       debug_sprintf_event(tape_dbf_area, d_level, d_str); \
+       debug_sprintf_event(TAPE_DBF_AREA, d_level, d_str); \
 } while (0)
 
 #define DBF_EXCEPTION(d_level, d_str...) \
 do { \
-       debug_sprintf_exception(tape_dbf_area, d_level, d_str); \
+       debug_sprintf_exception(TAPE_DBF_AREA, d_level, d_str); \
 } while (0)
 
 #define TAPE_VERSION_MAJOR 2
@@ -313,7 +313,7 @@ extern void tape_dump_sense_dbf(struct tape_device *, struct tape_request *,
 extern void tape_med_state_set(struct tape_device *, enum tape_medium_state);
 
 /* The debug area */
-extern debug_info_t *tape_dbf_area;
+extern debug_info_t *TAPE_DBF_AREA;
 
 /* functions for building ccws */
 static inline struct ccw1 *
index e738c4d..480ec87 100644 (file)
 #include <linux/bio.h>
 #include <linux/workqueue.h>
 
+#define TAPE_DBF_AREA  tape_34xx_dbf
+
 #include "tape.h"
 #include "tape_std.h"
 
 #define PRINTK_HEADER "TAPE_34XX: "
 
+/*
+ * Pointer to debug area.
+ */
+debug_info_t *TAPE_DBF_AREA = NULL;
+EXPORT_SYMBOL(TAPE_DBF_AREA);
+
 enum tape_34xx_type {
        tape_3480,
        tape_3490,
@@ -885,7 +893,7 @@ tape_34xx_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg)
        if (cmd == TAPE390_DISPLAY) {
                struct display_struct disp;
 
-               if (copy_from_user(&disp, (char *) arg, sizeof(disp)) != 0)
+               if (copy_from_user(&disp, (char __user *) arg, sizeof(disp)) != 0)
                        return -EFAULT;
 
                return tape_std_display(device, &disp);
@@ -1343,7 +1351,13 @@ tape_34xx_init (void)
 {
        int rc;
 
-       DBF_EVENT(3, "34xx init: $Revision: 1.20 $\n");
+       TAPE_DBF_AREA = debug_register ( "tape_34xx", 1, 2, 4*sizeof(long));
+       debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);
+#ifdef DBF_LIKE_HELL
+       debug_set_level(TAPE_DBF_AREA, 6);
+#endif
+
+       DBF_EVENT(3, "34xx init: $Revision: 1.21 $\n");
        /* Register driver for 3480/3490 tapes. */
        rc = ccw_driver_register(&tape_34xx_driver);
        if (rc)
@@ -1357,12 +1371,14 @@ static void
 tape_34xx_exit(void)
 {
        ccw_driver_unregister(&tape_34xx_driver);
+
+       debug_unregister(TAPE_DBF_AREA);
 }
 
 MODULE_DEVICE_TABLE(ccw, tape_34xx_ids);
 MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH");
 MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape "
-                  "device driver ($Revision: 1.20 $)");
+                  "device driver ($Revision: 1.21 $)");
 MODULE_LICENSE("GPL");
 
 module_init(tape_34xx_init);
index 7f4ab64..b7f4e7b 100644 (file)
@@ -19,6 +19,8 @@
 
 #include <asm/debug.h>
 
+#define TAPE_DBF_AREA  tape_core_dbf
+
 #include "tape.h"
 
 #define PRINTK_HEADER "TAPE_BLOCK: "
index ccbe214..0d0343b 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <asm/uaccess.h>
 
+#define TAPE_DBF_AREA  tape_core_dbf
+
 #include "tape.h"
 #include "tape_std.h"
 #include "tape_class.h"
@@ -29,8 +31,8 @@
 /*
  * file operation structure for tape character frontend
  */
-static ssize_t tapechar_read(struct file *, char *, size_t, loff_t *);
-static ssize_t tapechar_write(struct file *, const char *, size_t, loff_t *);
+static ssize_t tapechar_read(struct file *, char __user *, size_t, loff_t *);
+static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *);
 static int tapechar_open(struct inode *,struct file *);
 static int tapechar_release(struct inode *,struct file *);
 static int tapechar_ioctl(struct inode *, struct file *, unsigned int,
@@ -134,7 +136,7 @@ tapechar_check_idalbuffer(struct tape_device *device, size_t block_size)
  * Tape device read function
  */
 ssize_t
-tapechar_read (struct file *filp, char *data, size_t count, loff_t *ppos)
+tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
 {
        struct tape_device *device;
        struct tape_request *request;
@@ -208,7 +210,7 @@ tapechar_read (struct file *filp, char *data, size_t count, loff_t *ppos)
  * Tape device write function
  */
 ssize_t
-tapechar_write(struct file *filp, const char *data, size_t count, loff_t *ppos)
+tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t *ppos)
 {
        struct tape_device *device;
        struct tape_request *request;
@@ -389,7 +391,7 @@ tapechar_ioctl(struct inode *inp, struct file *filp,
        if (no == MTIOCTOP) {
                struct mtop op;
 
-               if (copy_from_user(&op, (char *) data, sizeof(op)) != 0)
+               if (copy_from_user(&op, (char __user *) data, sizeof(op)) != 0)
                        return -EFAULT;
                if (op.mt_count < 0)
                        return -EINVAL;
@@ -436,7 +438,7 @@ tapechar_ioctl(struct inode *inp, struct file *filp,
                if (rc < 0)
                        return rc;
                pos.mt_blkno = rc;
-               if (copy_to_user((char *) data, &pos, sizeof(pos)) != 0)
+               if (copy_to_user((char __user *) data, &pos, sizeof(pos)) != 0)
                        return -EFAULT;
                return 0;
        }
@@ -466,7 +468,7 @@ tapechar_ioctl(struct inode *inp, struct file *filp,
                        get.mt_blkno = rc;
                }
 
-               if (copy_to_user((char *) data, &get, sizeof(get)) != 0)
+               if (copy_to_user((char __user *) data, &get, sizeof(get)) != 0)
                        return -EFAULT;
 
                return 0;
index 6d7c5c0..668fe3f 100644 (file)
@@ -20,6 +20,8 @@
 
 #include <asm/types.h>      // for variable types
 
+#define TAPE_DBF_AREA  tape_core_dbf
+
 #include "tape.h"
 #include "tape_std.h"
 
@@ -39,7 +41,8 @@ static rwlock_t tape_device_lock = RW_LOCK_UNLOCKED;
 /*
  * Pointer to debug area.
  */
-debug_info_t *tape_dbf_area = NULL;
+debug_info_t *TAPE_DBF_AREA = NULL;
+EXPORT_SYMBOL(TAPE_DBF_AREA);
 
 /*
  * Printable strings for tape enumerations.
@@ -1176,12 +1179,12 @@ tape_mtop(struct tape_device *device, int mt_op, int mt_count)
 static int
 tape_init (void)
 {
-       tape_dbf_area = debug_register ( "tape", 1, 2, 4*sizeof(long));
-       debug_register_view(tape_dbf_area, &debug_sprintf_view);
+       TAPE_DBF_AREA = debug_register ( "tape", 1, 2, 4*sizeof(long));
+       debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);
 #ifdef DBF_LIKE_HELL
-       debug_set_level(tape_dbf_area, 6);
+       debug_set_level(TAPE_DBF_AREA, 6);
 #endif
-       DBF_EVENT(3, "tape init: ($Revision: 1.49 $)\n");
+       DBF_EVENT(3, "tape init: ($Revision: 1.50 $)\n");
        tape_proc_init();
        tapechar_init ();
        tapeblock_init ();
@@ -1200,19 +1203,18 @@ tape_exit(void)
        tapechar_exit();
        tapeblock_exit();
        tape_proc_cleanup();
-       debug_unregister (tape_dbf_area);
+       debug_unregister (TAPE_DBF_AREA);
 }
 
 MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and "
              "Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)");
 MODULE_DESCRIPTION("Linux on zSeries channel attached "
-                  "tape device driver ($Revision: 1.49 $)");
+                  "tape device driver ($Revision: 1.50 $)");
 MODULE_LICENSE("GPL");
 
 module_init(tape_init);
 module_exit(tape_exit);
 
-EXPORT_SYMBOL(tape_dbf_area);
 EXPORT_SYMBOL(tape_generic_remove);
 EXPORT_SYMBOL(tape_generic_probe);
 EXPORT_SYMBOL(tape_generic_online);
index 11d56de..801d17c 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/vmalloc.h>
 #include <linux/seq_file.h>
 
+#define TAPE_DBF_AREA  tape_core_dbf
+
 #include "tape.h"
 
 #define PRINTK_HEADER "TAPE_PROC: "
index afa014f..2f9fe30 100644 (file)
@@ -22,6 +22,8 @@
 #include <asm/ebcdic.h>
 #include <asm/tape390.h>
 
+#define TAPE_DBF_AREA  tape_core_dbf
+
 #include "tape.h"
 #include "tape_std.h"
 
index 71c03c8..3720e77 100644 (file)
@@ -2,7 +2,7 @@
  *  drivers/s390/cio/airq.c
  *   S/390 common I/O routines -- support for adapter interruptions
  *
- *   $Revision: 1.11 $
+ *   $Revision: 1.12 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *                           IBM Corporation
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/rcupdate.h>
 
 #include "cio_debug.h"
 #include "airq.h"
 
-static spinlock_t adapter_lock = SPIN_LOCK_UNLOCKED;
 static adapter_int_handler_t adapter_handler;
 
 /*
@@ -40,23 +40,17 @@ s390_register_adapter_interrupt (adapter_int_handler_t handler)
 
        CIO_TRACE_EVENT (4, "rgaint");
 
-       spin_lock (&adapter_lock);
-
        if (handler == NULL)
                ret = -EINVAL;
-       else if (adapter_handler)
-               ret = -EBUSY;
-       else {
-               adapter_handler = handler;
-               ret = 0;
-       }
-
-       spin_unlock (&adapter_lock);
+       else
+               ret = (cmpxchg(&adapter_handler, NULL, handler) ? -EBUSY : 0);
+       if (!ret)
+               synchronize_kernel();
 
        sprintf (dbf_txt, "ret:%d", ret);
        CIO_TRACE_EVENT (4, dbf_txt);
 
-       return (ret);
+       return ret;
 }
 
 int
@@ -67,38 +61,26 @@ s390_unregister_adapter_interrupt (adapter_int_handler_t handler)
 
        CIO_TRACE_EVENT (4, "urgaint");
 
-       spin_lock (&adapter_lock);
-
        if (handler == NULL)
                ret = -EINVAL;
-       else if (handler != adapter_handler)
-               ret = -EINVAL;
        else {
                adapter_handler = NULL;
+               synchronize_kernel();
                ret = 0;
        }
-
-       spin_unlock (&adapter_lock);
-
        sprintf (dbf_txt, "ret:%d", ret);
        CIO_TRACE_EVENT (4, dbf_txt);
 
-       return (ret);
+       return ret;
 }
 
 void
 do_adapter_IO (void)
 {
-       CIO_TRACE_EVENT (4, "doaio");
-
-       spin_lock (&adapter_lock);
+       CIO_TRACE_EVENT (6, "doaio");
 
        if (adapter_handler)
                (*adapter_handler) ();
-
-       spin_unlock (&adapter_lock);
-
-       return;
 }
 
 EXPORT_SYMBOL (s390_register_adapter_interrupt);
index 0589933..29000d5 100644 (file)
@@ -308,7 +308,7 @@ static int cio_ignore_read (char *page, char **start, off_t off,
        return len;
 }
 
-static int cio_ignore_write (struct file *file, const char *user_buf,
+static int cio_ignore_write(struct file *file, const char __user *user_buf,
                             unsigned long user_len, void *data)
 {
        char *buf;
index 6d0179f..9b86522 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/ccwgroup.c
  *  bus driver for ccwgroup
- *   $Revision: 1.27 $
+ *   $Revision: 1.28 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *                       IBM Corporation
@@ -179,12 +179,12 @@ ccwgroup_create(struct device *root,
                    || gdev->cdev[i]->id.driver_info !=
                    gdev->cdev[0]->id.driver_info) {
                        rc = -EINVAL;
-                       goto error;
+                       goto free_dev;
                }
                /* Don't allow a device to belong to more than one group. */
                if (gdev->cdev[i]->dev.driver_data) {
                        rc = -EINVAL;
-                       goto error;
+                       goto free_dev;
                }
        }
        for (i = 0; i < argc; i++)
@@ -207,8 +207,8 @@ ccwgroup_create(struct device *root,
        rc = device_register(&gdev->dev);
        
        if (rc)
-               goto error;
-
+               goto free_dev;
+       get_device(&gdev->dev);
        rc = device_create_file(&gdev->dev, &dev_attr_ungroup);
 
        if (rc) {
@@ -217,12 +217,21 @@ ccwgroup_create(struct device *root,
        }
 
        rc = __ccwgroup_create_symlinks(gdev);
-       if (!rc)
+       if (!rc) {
+               put_device(&gdev->dev);
                return 0;
-
+       }
        device_remove_file(&gdev->dev, &dev_attr_ungroup);
        device_unregister(&gdev->dev);
 error:
+       for (i = 0; i < argc; i++)
+               if (gdev->cdev[i]) {
+                       put_device(&gdev->cdev[i]->dev);
+                       gdev->cdev[i]->dev.driver_data = NULL;
+               }
+       put_device(&gdev->dev);
+       return rc;
+free_dev:
        for (i = 0; i < argc; i++)
                if (gdev->cdev[i]) {
                        put_device(&gdev->cdev[i]->dev);
@@ -230,7 +239,6 @@ error:
                                gdev->cdev[i]->dev.driver_data = NULL;
                }
        kfree(gdev);
-
        return rc;
 }
 
index 4a26cf1..4c8d6df 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/chsc.c
  *   S/390 common I/O routines -- channel subsystem call
- *   $Revision: 1.110 $
+ *   $Revision: 1.112 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *                           IBM Corporation
@@ -24,7 +24,6 @@
 #include "ioasm.h"
 #include "chsc.h"
 
-#define CHPID_LONGS (256 / (8 * sizeof(long))) /* 256 chpids */
 static struct channel_path *chps[NR_CHPIDS];
 
 static void *sei_page;
@@ -62,11 +61,11 @@ chpid_is_actually_online(int chp)
        int state;
 
        state = get_chp_status(chp);
-       if (state < 0)
-               new_channel_path(chp);
-       else
+       if (state < 0) {
+               need_rescan = 1;
+               queue_work(slow_path_wq, &slow_path_work);
+       } else
                WARN_ON(!state);
-       /* FIXME: should notify other subchannels here */
 }
 
 /* FIXME: this is _always_ called for every subchannel. shouldn't we
@@ -285,8 +284,10 @@ out_unlock:
 out_unreg:
        spin_unlock(&sch->lock);
        sch->lpm = 0;
-       /* We can't block here. */
-       device_call_nopath_notify(sch);
+       if (css_enqueue_subchannel_slow(sch->irq)) {
+               css_clear_subchannel_slow_list();
+               need_rescan = 1;
+       }
        return 0;
 }
 
@@ -303,6 +304,9 @@ s390_set_chpid_offline( __u8 chpid)
 
        bus_for_each_dev(&css_bus_type, NULL, &chpid,
                         s390_subchannel_remove_chpid);
+
+       if (need_rescan || css_slow_subchannels_exist())
+               queue_work(slow_path_wq, &slow_path_work);
 }
 
 static int
@@ -737,10 +741,12 @@ __s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on)
                         * can successfully terminate, even using the
                         * just varied off path. Then kill it.
                         */
-                       if (!__check_for_io_and_kill(sch, chp) && !sch->lpm)
-                               /* Get over with it now. */
-                               device_call_nopath_notify(sch);
-                       else if (sch->driver && sch->driver->verify)
+                       if (!__check_for_io_and_kill(sch, chp) && !sch->lpm) {
+                               if (css_enqueue_subchannel_slow(sch->irq)) {
+                                       css_clear_subchannel_slow_list();
+                                       need_rescan = 1;
+                               }
+                       } else if (sch->driver && sch->driver->verify)
                                sch->driver->verify(&sch->dev);
                }
                break;
@@ -773,11 +779,6 @@ s390_subchannel_vary_chpid_on(struct device *dev, void *data)
        return 0;
 }
 
-extern void css_trigger_slow_path(void);
-typedef void (*workfunc)(void *);
-static DECLARE_WORK(varyonoff_work, (workfunc)css_trigger_slow_path,
-                   NULL);
-
 /*
  * Function: s390_vary_chpid
  * Varies the specified chpid online or offline
@@ -813,7 +814,7 @@ s390_vary_chpid( __u8 chpid, int on)
                         s390_subchannel_vary_chpid_on :
                         s390_subchannel_vary_chpid_off);
        if (!on)
-               return 0;
+               goto out;
        /* Scan for new devices on varied on path. */
        for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
                struct schib schib;
@@ -835,8 +836,9 @@ s390_vary_chpid( __u8 chpid, int on)
                        need_rescan = 1;
                }
        }
+out:
        if (need_rescan || css_slow_subchannels_exist())
-               schedule_work(&varyonoff_work);
+               queue_work(slow_path_wq, &slow_path_work);
        return 0;
 }
 
index 6f02ac0..90f5a9e 100644 (file)
@@ -23,5 +23,4 @@ extern struct channel_path *chps[];
 extern void s390_process_css( void );
 extern void chsc_validate_chpids(struct subchannel *);
 extern void chpid_is_actually_online(int);
-extern int is_chpid_online(int);
 #endif
index 3c78670..a16f061 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/cio.c
  *   S/390 common I/O routines -- low level i/o calls
- *   $Revision: 1.121 $
+ *   $Revision: 1.123 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *                           IBM Corporation
@@ -67,17 +67,17 @@ cio_debug_init (void)
        if (!cio_debug_msg_id)
                goto out_unregister;
        debug_register_view (cio_debug_msg_id, &debug_sprintf_view);
-       debug_set_level (cio_debug_msg_id, 6);
+       debug_set_level (cio_debug_msg_id, 2);
        cio_debug_trace_id = debug_register ("cio_trace", 4, 4, 8);
        if (!cio_debug_trace_id)
                goto out_unregister;
        debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view);
-       debug_set_level (cio_debug_trace_id, 6);
+       debug_set_level (cio_debug_trace_id, 2);
        cio_debug_crw_id = debug_register ("cio_crw", 2, 4, 16*sizeof (long));
        if (!cio_debug_crw_id)
                goto out_unregister;
        debug_register_view (cio_debug_crw_id, &debug_sprintf_view);
-       debug_set_level (cio_debug_crw_id, 6);
+       debug_set_level (cio_debug_crw_id, 2);
        pr_debug("debugging initialized\n");
        return 0;
 
index ed8507e..f996528 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/css.c
  *  driver for channel subsystem
- *   $Revision: 1.74 $
+ *   $Revision: 1.77 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *                      IBM Corporation
@@ -166,10 +166,12 @@ css_get_subchannel_status(struct subchannel *sch, int schid)
        if (sch && sch->schib.pmcw.dnv &&
            (schib.pmcw.dev != sch->schib.pmcw.dev))
                return CIO_REVALIDATE;
+       if (sch && !sch->lpm)
+               return CIO_NO_PATH;
        return CIO_OPER;
 }
        
-static inline int
+static int
 css_evaluate_subchannel(int irq, int slow)
 {
        int event, ret, disc;
@@ -188,7 +190,11 @@ css_evaluate_subchannel(int irq, int slow)
                return -EAGAIN; /* Will be done on the slow path. */
        }
        event = css_get_subchannel_status(sch, irq);
+       CIO_MSG_EVENT(4, "Evaluating schid %04x, event %d, %s, %s path.\n",
+                     irq, event, sch?(disc?"disconnected":"normal"):"unknown",
+                     slow?"slow":"fast");
        switch (event) {
+       case CIO_NO_PATH:
        case CIO_GONE:
                if (!sch) {
                        /* Never used this subchannel. Ignore. */
@@ -196,7 +202,8 @@ css_evaluate_subchannel(int irq, int slow)
                        break;
                }
                if (sch->driver && sch->driver->notify &&
-                   sch->driver->notify(&sch->dev, CIO_GONE)) {
+                   sch->driver->notify(&sch->dev, event)) {
+                       cio_disable_subchannel(sch);
                        device_set_disconnected(sch);
                        ret = 0;
                        break;
@@ -205,6 +212,7 @@ css_evaluate_subchannel(int irq, int slow)
                 * Unregister subchannel.
                 * The device will be killed automatically.
                 */
+               cio_disable_subchannel(sch);
                device_unregister(&sch->dev);
                /* Reset intparm to zeroes. */
                sch->schib.pmcw.intparm = 0;
@@ -266,23 +274,44 @@ css_rescan_devices(void)
        }
 }
 
-static void
-css_evaluate_slow_subchannel(unsigned long schid)
-{
-       css_evaluate_subchannel(schid, 1);
-}
+struct slow_subchannel {
+       struct list_head slow_list;
+       unsigned long schid;
+};
 
-void
+static LIST_HEAD(slow_subchannels_head);
+static spinlock_t slow_subchannel_lock = SPIN_LOCK_UNLOCKED;
+
+static void
 css_trigger_slow_path(void)
 {
+       CIO_TRACE_EVENT(4, "slowpath");
+
        if (need_rescan) {
                need_rescan = 0;
                css_rescan_devices();
                return;
        }
-       css_walk_subchannel_slow_list(css_evaluate_slow_subchannel);
+
+       spin_lock_irq(&slow_subchannel_lock);
+       while (!list_empty(&slow_subchannels_head)) {
+               struct slow_subchannel *slow_sch =
+                       list_entry(slow_subchannels_head.next,
+                                  struct slow_subchannel, slow_list);
+
+               list_del_init(slow_subchannels_head.next);
+               spin_unlock_irq(&slow_subchannel_lock);
+               css_evaluate_subchannel(slow_sch->schid, 1);
+               spin_lock_irq(&slow_subchannel_lock);
+               kfree(slow_sch);
+       }
+       spin_unlock_irq(&slow_subchannel_lock);
 }
 
+typedef void (*workfunc)(void *);
+DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL);
+struct workqueue_struct *slow_path_wq;
+
 /*
  * Rescan for new devices. FIXME: This is slow.
  * This function is called when we have lost CRWs due to overflows and we have
@@ -443,14 +472,6 @@ s390_root_dev_unregister(struct device *dev)
                device_unregister(dev);
 }
 
-struct slow_subchannel {
-       struct list_head slow_list;
-       unsigned long schid;
-};
-
-static LIST_HEAD(slow_subchannels_head);
-static spinlock_t slow_subchannel_lock = SPIN_LOCK_UNLOCKED;
-
 int
 css_enqueue_subchannel_slow(unsigned long schid)
 {
@@ -484,25 +505,7 @@ css_clear_subchannel_slow_list(void)
        spin_unlock_irqrestore(&slow_subchannel_lock, flags);
 }
 
-void
-css_walk_subchannel_slow_list(void (*fn)(unsigned long))
-{
-       unsigned long flags;
 
-       spin_lock_irqsave(&slow_subchannel_lock, flags);
-       while (!list_empty(&slow_subchannels_head)) {
-               struct slow_subchannel *slow_sch =
-                       list_entry(slow_subchannels_head.next,
-                                  struct slow_subchannel, slow_list);
-
-               list_del_init(slow_subchannels_head.next);
-               spin_unlock_irqrestore(&slow_subchannel_lock, flags);
-               fn(slow_sch->schid);
-               spin_lock_irqsave(&slow_subchannel_lock, flags);
-               kfree(slow_sch);
-       }
-       spin_unlock_irqrestore(&slow_subchannel_lock, flags);
-}
 
 int
 css_slow_subchannels_exist(void)
index 54beb13..b834e6a 100644 (file)
@@ -136,7 +136,6 @@ void device_trigger_reprobe(struct subchannel *);
 
 /* Helper functions for vary on/off. */
 void device_set_waiting(struct subchannel *);
-void device_call_nopath_notify(struct subchannel *);
 
 /* Helper functions to build lists for the slow path. */
 int css_enqueue_subchannel_slow(unsigned long schid);
@@ -144,4 +143,7 @@ void css_walk_subchannel_slow_list(void (*fn)(unsigned long));
 void css_clear_subchannel_slow_list(void);
 int css_slow_subchannels_exist(void);
 extern int need_rescan;
+
+extern struct workqueue_struct *slow_path_wq;
+extern struct work_struct slow_path_work;
 #endif
index 1b7a39b..a921b1f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/device.c
  *  bus driver for ccw devices
- *   $Revision: 1.117 $
+ *   $Revision: 1.120 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *                      IBM Corporation
@@ -159,6 +159,11 @@ init_ccw_bus_type (void)
                ret = -ENOMEM; /* FIXME: better errno ? */
                goto out_err;
        }
+       slow_path_wq = create_singlethread_workqueue("kslowcrw");
+       if (!slow_path_wq) {
+               ret = -ENOMEM; /* FIXME: better errno ? */
+               goto out_err;
+       }
        if ((ret = bus_register (&ccw_bus_type)))
                goto out_err;
 
@@ -174,6 +179,8 @@ out_err:
                destroy_workqueue(ccw_device_work);
        if (ccw_device_notify_work)
                destroy_workqueue(ccw_device_notify_work);
+       if (slow_path_wq)
+               destroy_workqueue(slow_path_wq);
        return ret;
 }
 
@@ -519,7 +526,8 @@ get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
                cdev = to_ccwdev(dev);
                if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
                    (cdev->private->devno == devno) &&
-                   (!strncmp(cdev->dev.bus_id, sibling->dev.bus_id, 4))) {
+                   (!strncmp(cdev->dev.bus_id, sibling->dev.bus_id,
+                             BUS_ID_SIZE))) {
                        cdev->private->state = DEV_STATE_NOT_OPER;
                        break;
                }
@@ -646,9 +654,7 @@ ccw_device_call_sch_unregister(void *data)
        struct subchannel *sch;
 
        sch = to_subchannel(cdev->dev.parent);
-       /* Check if device is registered. */
-       if (!list_empty(&sch->dev.node))
-               device_unregister(&sch->dev);
+       device_unregister(&sch->dev);
        /* Reset intparm to zeroes. */
        sch->schib.pmcw.intparm = 0;
        cio_modify(sch);
@@ -677,7 +683,7 @@ io_subchannel_recog_done(struct ccw_device *cdev)
                sch = to_subchannel(cdev->dev.parent);
                INIT_WORK(&cdev->private->kick_work,
                          ccw_device_call_sch_unregister, (void *) cdev);
-               queue_work(ccw_device_work, &cdev->private->kick_work);
+               queue_work(slow_path_wq, &cdev->private->kick_work);
                break;
        case DEV_STATE_BOXED:
                /* Device did not respond in time. */
index c131f13..508f1a7 100644 (file)
@@ -458,20 +458,6 @@ ccw_device_nopath_notify(void *data)
        }
 }
 
-void
-device_call_nopath_notify(struct subchannel *sch)
-{
-       struct ccw_device *cdev;
-
-       if (!sch->dev.driver_data)
-               return;
-       cdev = sch->dev.driver_data;
-       PREPARE_WORK(&cdev->private->kick_work,
-                    ccw_device_nopath_notify, (void *)cdev);
-       queue_work(ccw_device_notify_work, &cdev->private->kick_work);
-}
-
-
 void
 ccw_device_verify_done(struct ccw_device *cdev, int err)
 {
@@ -1085,103 +1071,103 @@ ccw_device_bug(struct ccw_device *cdev, enum dev_event dev_event)
  * device statemachine
  */
 fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
-       [DEV_STATE_NOT_OPER] {
-               [DEV_EVENT_NOTOPER]     ccw_device_nop,
-               [DEV_EVENT_INTERRUPT]   ccw_device_bug,
-               [DEV_EVENT_TIMEOUT]     ccw_device_nop,
-               [DEV_EVENT_VERIFY]      ccw_device_nop,
+       [DEV_STATE_NOT_OPER] {
+               [DEV_EVENT_NOTOPER]     ccw_device_nop,
+               [DEV_EVENT_INTERRUPT]   ccw_device_bug,
+               [DEV_EVENT_TIMEOUT]     ccw_device_nop,
+               [DEV_EVENT_VERIFY]      ccw_device_nop,
        },
-       [DEV_STATE_SENSE_PGID] {
-               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
-               [DEV_EVENT_INTERRUPT]   ccw_device_sense_pgid_irq,
-               [DEV_EVENT_TIMEOUT]     ccw_device_onoff_timeout,
-               [DEV_EVENT_VERIFY]      ccw_device_nop,
+       [DEV_STATE_SENSE_PGID] {
+               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
+               [DEV_EVENT_INTERRUPT]   ccw_device_sense_pgid_irq,
+               [DEV_EVENT_TIMEOUT]     ccw_device_onoff_timeout,
+               [DEV_EVENT_VERIFY]      ccw_device_nop,
        },
-       [DEV_STATE_SENSE_ID] {
-               [DEV_EVENT_NOTOPER]     ccw_device_recog_notoper,
-               [DEV_EVENT_INTERRUPT]   ccw_device_sense_id_irq,
-               [DEV_EVENT_TIMEOUT]     ccw_device_recog_timeout,
-               [DEV_EVENT_VERIFY]      ccw_device_nop,
+       [DEV_STATE_SENSE_ID] {
+               [DEV_EVENT_NOTOPER]     ccw_device_recog_notoper,
+               [DEV_EVENT_INTERRUPT]   ccw_device_sense_id_irq,
+               [DEV_EVENT_TIMEOUT]     ccw_device_recog_timeout,
+               [DEV_EVENT_VERIFY]      ccw_device_nop,
        },
-       [DEV_STATE_OFFLINE] {
-               [DEV_EVENT_NOTOPER]     ccw_device_offline_notoper,
-               [DEV_EVENT_INTERRUPT]   ccw_device_offline_irq,
-               [DEV_EVENT_TIMEOUT]     ccw_device_nop,
-               [DEV_EVENT_VERIFY]      ccw_device_nop,
+       [DEV_STATE_OFFLINE] {
+               [DEV_EVENT_NOTOPER]     ccw_device_offline_notoper,
+               [DEV_EVENT_INTERRUPT]   ccw_device_offline_irq,
+               [DEV_EVENT_TIMEOUT]     ccw_device_nop,
+               [DEV_EVENT_VERIFY]      ccw_device_nop,
        },
-       [DEV_STATE_VERIFY] {
-               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
-               [DEV_EVENT_INTERRUPT]   ccw_device_verify_irq,
-               [DEV_EVENT_TIMEOUT]     ccw_device_onoff_timeout,
-               [DEV_EVENT_VERIFY]      ccw_device_nop,
+       [DEV_STATE_VERIFY] {
+               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
+               [DEV_EVENT_INTERRUPT]   ccw_device_verify_irq,
+               [DEV_EVENT_TIMEOUT]     ccw_device_onoff_timeout,
+               [DEV_EVENT_VERIFY]      ccw_device_nop,
        },
-       [DEV_STATE_ONLINE] {
-               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
-               [DEV_EVENT_INTERRUPT]   ccw_device_irq,
-               [DEV_EVENT_TIMEOUT]     ccw_device_online_timeout,
-               [DEV_EVENT_VERIFY]      ccw_device_online_verify,
+       [DEV_STATE_ONLINE] {
+               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
+               [DEV_EVENT_INTERRUPT]   ccw_device_irq,
+               [DEV_EVENT_TIMEOUT]     ccw_device_online_timeout,
+               [DEV_EVENT_VERIFY]      ccw_device_online_verify,
        },
-       [DEV_STATE_W4SENSE] {
-               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
-               [DEV_EVENT_INTERRUPT]   ccw_device_w4sense,
-               [DEV_EVENT_TIMEOUT]     ccw_device_nop,
-               [DEV_EVENT_VERIFY]      ccw_device_online_verify,
+       [DEV_STATE_W4SENSE] {
+               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
+               [DEV_EVENT_INTERRUPT]   ccw_device_w4sense,
+               [DEV_EVENT_TIMEOUT]     ccw_device_nop,
+               [DEV_EVENT_VERIFY]      ccw_device_online_verify,
        },
-       [DEV_STATE_DISBAND_PGID] {
-               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
-               [DEV_EVENT_INTERRUPT]   ccw_device_disband_irq,
-               [DEV_EVENT_TIMEOUT]     ccw_device_onoff_timeout,
-               [DEV_EVENT_VERIFY]      ccw_device_nop,
+       [DEV_STATE_DISBAND_PGID] {
+               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
+               [DEV_EVENT_INTERRUPT]   ccw_device_disband_irq,
+               [DEV_EVENT_TIMEOUT]     ccw_device_onoff_timeout,
+               [DEV_EVENT_VERIFY]      ccw_device_nop,
        },
-       [DEV_STATE_BOXED] {
-               [DEV_EVENT_NOTOPER]     ccw_device_offline_notoper,
-               [DEV_EVENT_INTERRUPT]   ccw_device_stlck_done,
-               [DEV_EVENT_TIMEOUT]     ccw_device_stlck_done,
-               [DEV_EVENT_VERIFY]      ccw_device_nop,
+       [DEV_STATE_BOXED] {
+               [DEV_EVENT_NOTOPER]     ccw_device_offline_notoper,
+               [DEV_EVENT_INTERRUPT]   ccw_device_stlck_done,
+               [DEV_EVENT_TIMEOUT]     ccw_device_stlck_done,
+               [DEV_EVENT_VERIFY]      ccw_device_nop,
        },
        /* states to wait for i/o completion before doing something */
-       [DEV_STATE_CLEAR_VERIFY] {
-               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
-               [DEV_EVENT_INTERRUPT]   ccw_device_clear_verify,
-               [DEV_EVENT_TIMEOUT]     ccw_device_nop,
-               [DEV_EVENT_VERIFY]      ccw_device_nop,
+       [DEV_STATE_CLEAR_VERIFY] {
+               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
+               [DEV_EVENT_INTERRUPT]   ccw_device_clear_verify,
+               [DEV_EVENT_TIMEOUT]     ccw_device_nop,
+               [DEV_EVENT_VERIFY]      ccw_device_nop,
        },
-       [DEV_STATE_TIMEOUT_KILL] {
-               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
-               [DEV_EVENT_INTERRUPT]   ccw_device_killing_irq,
-               [DEV_EVENT_TIMEOUT]     ccw_device_killing_timeout,
-               [DEV_EVENT_VERIFY]      ccw_device_nop, //FIXME
+       [DEV_STATE_TIMEOUT_KILL] {
+               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
+               [DEV_EVENT_INTERRUPT]   ccw_device_killing_irq,
+               [DEV_EVENT_TIMEOUT]     ccw_device_killing_timeout,
+               [DEV_EVENT_VERIFY]      ccw_device_nop, //FIXME
        },
-       [DEV_STATE_WAIT4IO] {
-               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
-               [DEV_EVENT_INTERRUPT]   ccw_device_wait4io_irq,
-               [DEV_EVENT_TIMEOUT]     ccw_device_wait4io_timeout,
-               [DEV_EVENT_VERIFY]      ccw_device_wait4io_verify,
+       [DEV_STATE_WAIT4IO] {
+               [DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
+               [DEV_EVENT_INTERRUPT]   ccw_device_wait4io_irq,
+               [DEV_EVENT_TIMEOUT]     ccw_device_wait4io_timeout,
+               [DEV_EVENT_VERIFY]      ccw_device_wait4io_verify,
        },
-       [DEV_STATE_QUIESCE] {
-               [DEV_EVENT_NOTOPER]     ccw_device_quiesce_done,
-               [DEV_EVENT_INTERRUPT]   ccw_device_quiesce_done,
-               [DEV_EVENT_TIMEOUT]     ccw_device_quiesce_timeout,
-               [DEV_EVENT_VERIFY]      ccw_device_nop,
+       [DEV_STATE_QUIESCE] {
+               [DEV_EVENT_NOTOPER]     ccw_device_quiesce_done,
+               [DEV_EVENT_INTERRUPT]   ccw_device_quiesce_done,
+               [DEV_EVENT_TIMEOUT]     ccw_device_quiesce_timeout,
+               [DEV_EVENT_VERIFY]      ccw_device_nop,
        },
        /* special states for devices gone not operational */
-       [DEV_STATE_DISCONNECTED] {
-               [DEV_EVENT_NOTOPER]     ccw_device_nop,
-               [DEV_EVENT_INTERRUPT]   ccw_device_start_id,
-               [DEV_EVENT_TIMEOUT]     ccw_device_bug,
-               [DEV_EVENT_VERIFY]      ccw_device_nop,
+       [DEV_STATE_DISCONNECTED] {
+               [DEV_EVENT_NOTOPER]     ccw_device_nop,
+               [DEV_EVENT_INTERRUPT]   ccw_device_start_id,
+               [DEV_EVENT_TIMEOUT]     ccw_device_bug,
+               [DEV_EVENT_VERIFY]      ccw_device_nop,
        },
-       [DEV_STATE_DISCONNECTED_SENSE_ID] {
-               [DEV_EVENT_NOTOPER]     ccw_device_recog_notoper,
-               [DEV_EVENT_INTERRUPT]   ccw_device_sense_id_irq,
-               [DEV_EVENT_TIMEOUT]     ccw_device_recog_timeout,
-               [DEV_EVENT_VERIFY]      ccw_device_nop,
+       [DEV_STATE_DISCONNECTED_SENSE_ID] {
+               [DEV_EVENT_NOTOPER]     ccw_device_recog_notoper,
+               [DEV_EVENT_INTERRUPT]   ccw_device_sense_id_irq,
+               [DEV_EVENT_TIMEOUT]     ccw_device_recog_timeout,
+               [DEV_EVENT_VERIFY]      ccw_device_nop,
        },
-       [DEV_STATE_CMFCHANGE] {
-               [DEV_EVENT_NOTOPER]     ccw_device_change_cmfstate,
-               [DEV_EVENT_INTERRUPT]   ccw_device_change_cmfstate,
-               [DEV_EVENT_TIMEOUT]     ccw_device_change_cmfstate,
-               [DEV_EVENT_VERIFY]      ccw_device_change_cmfstate,
+       [DEV_STATE_CMFCHANGE] {
+               [DEV_EVENT_NOTOPER]     ccw_device_change_cmfstate,
+               [DEV_EVENT_INTERRUPT]   ccw_device_change_cmfstate,
+               [DEV_EVENT_TIMEOUT]     ccw_device_change_cmfstate,
+               [DEV_EVENT_VERIFY]      ccw_device_change_cmfstate,
        },
 };
 
index acc5217..0ce71a2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/requestirq.c
  *   S/390 common I/O routines -- enabling and disabling of devices
- *   $Revision: 1.45 $
+ *   $Revision: 1.46 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *                           IBM Corporation
 
 #include "css.h"
 
-/* for compatiblity only... */
-int
-request_irq (unsigned int irq,
-            void (*handler) (int, void *, struct pt_regs *),
-            unsigned long irqflags, const char *devname, void *dev_id)
-{
-       return -EINVAL;
-}
-
-/* for compatiblity only... */
-void
-free_irq (unsigned int irq, void *dev_id)
-{
-}
-
 struct pgid global_pgid;
 EXPORT_SYMBOL_GPL(global_pgid);
 
index 4ec1eaa..dbc5dd0 100644 (file)
  * - length(n_modulus) = inputdatalength
  */
 struct ica_rsa_modexpo {
-       char *          inputdata;
+       char __user *   inputdata;
        unsigned int    inputdatalength;
-       char *          outputdata;
+       char __user *   outputdata;
        unsigned int    outputdatalength;
-       char *          b_key;
-       char *          n_modulus;
+       char __user *   b_key;
+       char __user *   n_modulus;
 };
 
 /**
@@ -69,15 +69,15 @@ struct ica_rsa_modexpo {
  * - length(u_mult_inv) = inputdatalength/2 + 8
  */
 struct ica_rsa_modexpo_crt {
-       char *          inputdata;
+       char __user *   inputdata;
        unsigned int    inputdatalength;
-       char *          outputdata;
+       char __user *   outputdata;
        unsigned int    outputdatalength;
-       char *          bp_key;
-       char *          bq_key;
-       char *          np_prime;
-       char *          nq_prime;
-       char *          u_mult_inv;
+       char __user *   bp_key;
+       char __user *   bq_key;
+       char __user *   np_prime;
+       char __user *   nq_prime;
+       char __user *   u_mult_inv;
 };
 
 #define Z90_IOCTL_MAGIC 'z'  // NOTE:  Need to allocate from linux folks
index 0190e27..8ac1e9b 100644 (file)
@@ -361,7 +361,7 @@ struct work_element {
        int               buff_size;      // size of the buffer for the request
        char              resp_buff[RESPBUFFSIZE];
        int               resp_buff_size;
-       char *            resp_addr;      // address of response in user space
+       char __user *     resp_addr;      // address of response in user space
        unsigned int      funccode;       // function code of request
        wait_queue_head_t waitq;
        unsigned long     requestsent;    // time at which the request was sent
@@ -378,8 +378,9 @@ struct work_element {
  */
 static int z90crypt_open(struct inode *, struct file *);
 static int z90crypt_release(struct inode *, struct file *);
-static ssize_t z90crypt_read(struct file *, char *, size_t, loff_t *);
-static ssize_t z90crypt_write(struct file *, const char *, size_t, loff_t *);
+static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *);
+static ssize_t z90crypt_write(struct file *, const char __user *,
+                                                       size_t, loff_t *);
 static int z90crypt_ioctl(struct inode *, struct file *,
                          unsigned int, unsigned long);
 
@@ -389,7 +390,7 @@ static void z90crypt_config_task(unsigned long);
 static void z90crypt_cleanup_task(unsigned long);
 
 static int z90crypt_status(char *, char **, off_t, int, int *, void *);
-static int z90crypt_status_write(struct file *, const char *,
+static int z90crypt_status_write(struct file *, const char __user *,
                                 unsigned long, void *);
 
 /**
@@ -473,9 +474,9 @@ static int
 trans_modexpo32(unsigned int fd, unsigned int cmd, unsigned long arg,
                struct file *file)
 {
-       struct ica_rsa_modexpo_32 *mex32u = compat_ptr(arg);
+       struct ica_rsa_modexpo_32 __user *mex32u = compat_ptr(arg);
        struct ica_rsa_modexpo_32  mex32k;
-       struct ica_rsa_modexpo    *mex64;
+       struct ica_rsa_modexpo __user *mex64;
        int ret = 0;
        unsigned int i;
 
@@ -517,9 +518,9 @@ static int
 trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg,
                    struct file *file)
 {
-       struct ica_rsa_modexpo_crt_32 *crt32u = compat_ptr(arg);
+       struct ica_rsa_modexpo_crt_32 __user *crt32u = compat_ptr(arg);
        struct ica_rsa_modexpo_crt_32  crt32k;
-       struct ica_rsa_modexpo_crt    *crt64;
+       struct ica_rsa_modexpo_crt __user *crt64;
        int ret = 0;
        unsigned int i;
 
@@ -841,7 +842,7 @@ z90crypt_release(struct inode *inode, struct file *filp)
  * z90crypt_read will not be supported beyond z90crypt 1.3.1
  */
 static ssize_t
-z90crypt_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
+z90crypt_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
 {
        PDEBUG("filp %p (PID %d)\n", filp, PID());
        return -EPERM;
@@ -854,7 +855,7 @@ z90crypt_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
  */
 #include <linux/random.h>
 static ssize_t
-z90crypt_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
+z90crypt_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
 {
        unsigned char *temp_buff;
 
@@ -892,7 +893,7 @@ z90crypt_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
  * Write is is not allowed
  */
 static ssize_t
-z90crypt_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
+z90crypt_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
 {
        PDEBUG("filp %p (PID %d)\n", filp, PID());
        return -EPERM;
@@ -1258,7 +1259,7 @@ z90crypt_send(struct work_element *we_p, const char *buf)
  * process_results copies the user's work from kernel space.
  */
 static inline int
-z90crypt_process_results(struct work_element *we_p, char *buf)
+z90crypt_process_results(struct work_element *we_p, char __user *buf)
 {
        int rv;
 
@@ -1556,7 +1557,7 @@ get_crypto_request_buffer(struct work_element *we_p)
 
 static inline int
 z90crypt_prepare(struct work_element *we_p, unsigned int funccode,
-                const char *buffer)
+                const char __user *buffer)
 {
        int rv;
 
@@ -1641,7 +1642,7 @@ z90crypt_rsa(struct priv_data *private_data_p, pid_t pid,
                PDEBUG("PID %d: allocate_work_element returned ENOMEM\n", pid);
                return rv;
        }
-       if ((rv = z90crypt_prepare(we_p, cmd, (const char *)arg)))
+       if ((rv = z90crypt_prepare(we_p, cmd, (const char __user *)arg)))
                PDEBUG("PID %d: rv = %d from z90crypt_prepare\n", pid, rv);
        if (!rv)
                if ((rv = z90crypt_send(we_p, (const char *)arg)))
@@ -1653,7 +1654,7 @@ z90crypt_rsa(struct priv_data *private_data_p, pid_t pid,
                rv = we_p->retcode;
        }
        if (!rv)
-               rv = z90crypt_process_results(we_p, (char *)arg);
+               rv = z90crypt_process_results(we_p, (char __user *)arg);
 
        if ((we_p->status[0] & STAT_FAILED)) {
                switch (rv) {
@@ -1748,49 +1749,49 @@ z90crypt_ioctl(struct inode *inode, struct file *filp,
 
        case Z90STAT_TOTALCOUNT:
                tempstat = get_status_totalcount();
-               if (copy_to_user((int *)arg, &tempstat,sizeof(int)) != 0)
+               if (copy_to_user((int __user *)arg, &tempstat,sizeof(int)) != 0)
                        ret = -EFAULT;
                break;
 
        case Z90STAT_PCICACOUNT:
                tempstat = get_status_PCICAcount();
-               if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+               if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
                        ret = -EFAULT;
                break;
 
        case Z90STAT_PCICCCOUNT:
                tempstat = get_status_PCICCcount();
-               if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+               if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
                        ret = -EFAULT;
                break;
 
        case Z90STAT_PCIXCCCOUNT:
                tempstat = get_status_PCIXCCcount();
-               if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+               if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
                        ret = -EFAULT;
                break;
 
        case Z90STAT_REQUESTQ_COUNT:
                tempstat = get_status_requestq_count();
-               if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+               if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
                        ret = -EFAULT;
                break;
 
        case Z90STAT_PENDINGQ_COUNT:
                tempstat = get_status_pendingq_count();
-               if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+               if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
                        ret = -EFAULT;
                break;
 
        case Z90STAT_TOTALOPEN_COUNT:
                tempstat = get_status_totalopen_count();
-               if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+               if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
                        ret = -EFAULT;
                break;
 
        case Z90STAT_DOMAIN_INDEX:
                tempstat = get_status_domain_index();
-               if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+               if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
                        ret = -EFAULT;
                break;
 
@@ -1802,7 +1803,8 @@ z90crypt_ioctl(struct inode *inode, struct file *filp,
                        break;
                }
                get_status_status_mask(status);
-               if (copy_to_user((char *) arg, status, Z90CRYPT_NUM_APS) != 0)
+               if (copy_to_user((char __user *) arg, status, Z90CRYPT_NUM_APS)
+                                                                       != 0)
                        ret = -EFAULT;
                kfree(status);
                break;
@@ -1815,7 +1817,7 @@ z90crypt_ioctl(struct inode *inode, struct file *filp,
                        break;
                }
                get_status_qdepth_mask(qdepth);
-               if (copy_to_user((char *) arg, qdepth, Z90CRYPT_NUM_APS) != 0)
+               if (copy_to_user((char __user *) arg, qdepth, Z90CRYPT_NUM_APS) != 0)
                        ret = -EFAULT;
                kfree(qdepth);
                break;
@@ -1828,7 +1830,7 @@ z90crypt_ioctl(struct inode *inode, struct file *filp,
                        break;
                }
                get_status_perdevice_reqcnt(reqcnt);
-               if (copy_to_user((char *) arg, reqcnt,
+               if (copy_to_user((char __user *) arg, reqcnt,
                                 Z90CRYPT_NUM_APS * sizeof(int)) != 0)
                        ret = -EFAULT;
                kfree(reqcnt);
@@ -1861,7 +1863,7 @@ z90crypt_ioctl(struct inode *inode, struct file *filp,
                get_status_status_mask(pstat->status);
                get_status_qdepth_mask(pstat->qdepth);
 
-               if (copy_to_user((struct ica_z90_status *) arg, pstat,
+               if (copy_to_user((struct ica_z90_status __user *) arg, pstat,
                                 sizeof(struct ica_z90_status)) != 0)
                        ret = -EFAULT;
                kfree(pstat);
@@ -2104,7 +2106,7 @@ scan_string(unsigned char *bf, unsigned int len,
 }
 
 static int
-z90crypt_status_write(struct file *file, const char *buffer,
+z90crypt_status_write(struct file *file, const char __user *buffer,
                      unsigned long count, void *data)
 {
        int i, j, len, offs, found, eof;
@@ -2209,7 +2211,7 @@ z90crypt_status_write(struct file *file, const char *buffer,
  */
 static inline int
 receive_from_crypto_device(int index, unsigned char *psmid, int *buff_len_p,
-                          unsigned char *buff, unsigned char **dest_p_p)
+                          unsigned char *buff, unsigned char __user **dest_p_p)
 {
        int dv, rv;
        struct device *dev_ptr;
@@ -2397,7 +2399,7 @@ helper_send_work(int index)
 static inline void
 helper_handle_work_element(int index, unsigned char psmid[8], int rc,
                           int buff_len, unsigned char *buff,
-                          unsigned char *resp_addr)
+                          unsigned char __user *resp_addr)
 {
        struct work_element *pq_p;
        struct list_head *lptr, *tptr;
@@ -2502,7 +2504,8 @@ static void
 z90crypt_reader_task(unsigned long ptr)
 {
        int workavail, remaining, index, rc, buff_len;
-       unsigned char   psmid[8], *resp_addr;
+       unsigned char   psmid[8];
+       unsigned char __user *resp_addr;
        static unsigned char buff[1024];
 
        PDEBUG("jiffies %ld\n", jiffies);
index 1120f79..3755f99 100644 (file)
@@ -515,7 +515,8 @@ ctc_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int cou
                }
                skb_reserve(skb, skb_res);
                if (from_user)
-                       copy_from_user(skb_put(skb, c), buf, c);
+                       copy_from_user(skb_put(skb, c),
+                                       (const u_char __user *)buf, c);
                else
                        memcpy(skb_put(skb, c), buf, c);
                skb_queue_tail(&info->tx_queue, skb);
@@ -640,7 +641,7 @@ ctc_tty_unthrottle(struct tty_struct *tty)
  *          allows RS485 driver to be written in user space.
  */
 static int
-ctc_tty_get_lsr_info(ctc_tty_info * info, uint value)
+ctc_tty_get_lsr_info(ctc_tty_info * info, uint __user *value)
 {
        u_char status;
        uint result;
@@ -650,7 +651,7 @@ ctc_tty_get_lsr_info(ctc_tty_info * info, uint * value)
        status = info->lsr;
        spin_unlock_irqrestore(&ctc_tty_lock, flags);
        result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
-       put_user(result, (uint *) value);
+       put_user(result, value);
        return 0;
 }
 
@@ -743,14 +744,14 @@ ctc_tty_ioctl(struct tty_struct *tty, struct file *file,
                        printk(KERN_DEBUG "%s%d ioctl TIOCGSOFTCAR\n", CTC_TTY_NAME,
                               info->line);
 #endif
-                       error = put_user(C_CLOCAL(tty) ? 1 : 0, (ulong *) arg);
+                       error = put_user(C_CLOCAL(tty) ? 1 : 0, (ulong __user *) arg);
                        return error;
                case TIOCSSOFTCAR:
 #ifdef CTC_DEBUG_MODEM_IOCTL
                        printk(KERN_DEBUG "%s%d ioctl TIOCSSOFTCAR\n", CTC_TTY_NAME,
                               info->line);
 #endif
-                       error = get_user(arg, (ulong *) arg);
+                       error = get_user(arg, (ulong __user *) arg);
                        if (error)
                                return error;
                        tty->termios->c_cflag =
@@ -762,11 +763,11 @@ ctc_tty_ioctl(struct tty_struct *tty, struct file *file,
                        printk(KERN_DEBUG "%s%d ioctl TIOCSERGETLSR\n", CTC_TTY_NAME,
                               info->line);
 #endif
-                       error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(uint));
+                       error = verify_area(VERIFY_WRITE, (void __user *) arg, sizeof(uint));
                        if (error)
                                return error;
                        else
-                               return ctc_tty_get_lsr_info(info, (uint *) arg);
+                               return ctc_tty_get_lsr_info(info, (uint __user *) arg);
                default:
 #ifdef CTC_DEBUG_MODEM_IOCTL
                        printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on %s%d\n", cmd,
index 8dd8bec..36790af 100644 (file)
@@ -1,5 +1,5 @@
 /* 
- * $Id: iucv.c,v 1.32 2004/05/18 09:28:43 braunu Exp $
+ * $Id: iucv.c,v 1.33 2004/05/24 10:19:18 braunu Exp $
  *
  * IUCV network driver
  *
@@ -29,7 +29,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.32 $
+ * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.33 $
  *
  */
 \f
@@ -352,7 +352,7 @@ do { \
 static void
 iucv_banner(void)
 {
-       char vbuf[] = "$Revision: 1.32 $";
+       char vbuf[] = "$Revision: 1.33 $";
        char *version = vbuf;
 
        if ((version = strchr(version, ':'))) {
@@ -2368,7 +2368,8 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                                        iucv_debug(2,
                                                   "found a matching handler");
                                        break;
-                               }
+                               } else
+                                       h = NULL;
                        }
                        spin_unlock_irqrestore (&iucv_lock, flags);
                        if (h) {
index 2b3753d..570a93b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: netiucv.c,v 1.53 2004/05/07 14:29:37 mschwide Exp $
+ * $Id: netiucv.c,v 1.54 2004/05/28 08:04:14 braunu Exp $
  *
  * IUCV network driver
  *
@@ -30,7 +30,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV network driver $Revision: 1.53 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.54 $
  *
  */
 \f
@@ -60,7 +60,6 @@
 #include <asm/io.h>
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
-#include <asm/ebcdic.h>
 
 #include "iucv.h"
 #include "fsm.h"
@@ -167,10 +166,10 @@ static __inline__ int netiucv_test_and_set_busy(struct net_device *dev)
 }
 
 static __u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-//static __u8 iucvMagic[16] = {
-//     0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-//     0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
-//};
+static __u8 iucvMagic[16] = {
+       0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+       0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
+};
 
 /**
  * This mask means the 16-byte IUCV "magic" and the origin userid must
@@ -769,18 +768,10 @@ conn_action_start(fsm_instance *fi, int event, void *arg)
        struct iucv_event *ev = (struct iucv_event *)arg;
        struct iucv_connection *conn = ev->conn;
        __u16 msglimit;
-       int rc, len;
-       __u8 iucvMagic[16] = {
-       0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-        0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
-       };
+       int rc;
 
        pr_debug("%s() called\n", __FUNCTION__);
 
-       len = (IFNAMSIZ < sizeof(conn->netdev->name)) ?
-               IFNAMSIZ : sizeof(conn->netdev->name);
-       memcpy(iucvMagic, conn->netdev->name, len);
-       ASCEBC (iucvMagic, len);
        if (conn->handle == 0) {
                conn->handle =
                        iucv_register_program(iucvMagic, conn->userid, mask,
@@ -1958,7 +1949,7 @@ static struct device_driver netiucv_driver = {
 static void
 netiucv_banner(void)
 {
-       char vbuf[] = "$Revision: 1.53 $";
+       char vbuf[] = "$Revision: 1.54 $";
        char *version = vbuf;
 
        if ((version = strchr(version, ':'))) {
index a299fa1..96c4243 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "qeth_mpc.h"
 
-#define VERSION_QETH_H                 "$Revision: 1.108 $"
+#define VERSION_QETH_H                 "$Revision: 1.110 $"
 
 #ifdef CONFIG_QETH_IPV6
 #define QETH_VERSION_IPV6      ":IPv6"
                debug_event(qeth_dbf_##name,level,(void*)(addr),len); \
        } while (0)
 
-#define QETH_DBF_TEXT_(name,level,text...)                               \
-       do {                                                              \
-               sprintf(qeth_dbf_text_buf, text);                         \
-               debug_text_event(qeth_dbf_##name,level,qeth_dbf_text_buf);\
+extern DEFINE_PER_CPU(char[256], qeth_dbf_txt_buf);
+
+#define QETH_DBF_TEXT_(name,level,text...)                             \
+       do {                                                            \
+               char* dbf_txt_buf = get_cpu_var(qeth_dbf_txt_buf);      \
+               sprintf(dbf_txt_buf, text);                             \
+               debug_text_event(qeth_dbf_##name,level,dbf_txt_buf);    \
+               put_cpu_var(qeth_dbf_txt_buf);                          \
        } while (0)
 
 #define QETH_DBF_SPRINTF(name,level,text...) \
@@ -376,11 +380,6 @@ enum qeth_qdio_buffer_states {
         * outbound: filled by driver; owned by hardware in order to be sent
         */
        QETH_QDIO_BUF_PRIMED,
-       /*
-        * inbound only: an error condition has been detected for a buffer
-        *     the buffer will be discarded (not read out)
-        */
-       QETH_QDIO_BUF_ERROR,
 };
 
 enum qeth_qdio_info_states {
@@ -419,7 +418,7 @@ struct qeth_qdio_q {
 
 struct qeth_qdio_out_buffer {
        struct qdio_buffer *buffer;
-       volatile enum qeth_qdio_buffer_states state;
+       atomic_t state;
        volatile int next_element_to_fill;
        struct sk_buff_head skb_list;
 };
index ceab62a..8aefa28 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.112 $)
+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.121 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  *
@@ -12,7 +12,7 @@
  *                       Frank Pavlic (pavlic@de.ibm.com) and
  *                       Thomas Spatzier <tspat@de.ibm.com>
  *
- *    $Revision: 1.112 $        $Date: 2004/05/19 09:28:21 $
+ *    $Revision: 1.121 $        $Date: 2004/06/11 16:32:15 $
  *
  * 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
@@ -78,7 +78,7 @@ qeth_eyecatcher(void)
 #include "qeth_mpc.h"
 #include "qeth_fs.h"
 
-#define VERSION_QETH_C "$Revision: 1.112 $"
+#define VERSION_QETH_C "$Revision: 1.121 $"
 static const char *version = "qeth S/390 OSA-Express driver";
 
 /**
@@ -91,7 +91,8 @@ static debug_info_t *qeth_dbf_control = NULL;
 static debug_info_t *qeth_dbf_trace = NULL;
 static debug_info_t *qeth_dbf_sense = NULL;
 static debug_info_t *qeth_dbf_qerr = NULL;
-static char qeth_dbf_text_buf[255];
+
+DEFINE_PER_CPU(char[256], qeth_dbf_txt_buf);
 
 /**
  * some more definitions and declarations
@@ -2344,13 +2345,17 @@ qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf)
 }
 
 static inline void
-qeth_clear_output_buffer(struct qeth_card *card,
+qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
                         struct qeth_qdio_out_buffer *buf)
 {
        int i;
        struct sk_buff *skb;
 
-       for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i){
+       /* is PCI flag set on buffer? */
+       if (buf->buffer->element[0].flags & 0x40)
+               atomic_dec(&queue->set_pci_flags_count);
+
+       for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i){
                buf->buffer->element[i].length = 0;
                buf->buffer->element[i].addr = NULL;
                buf->buffer->element[i].flags = 0;
@@ -2360,7 +2365,7 @@ qeth_clear_output_buffer(struct qeth_card *card,
                }
        }
        buf->next_element_to_fill = 0;
-       buf->state = QETH_QDIO_BUF_EMPTY;
+       atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
 }
 
 static inline void
@@ -2577,8 +2582,17 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
                QETH_DBF_TEXT(trace, 2, "flushbuf");
                QETH_DBF_TEXT_(trace, 2, " err%d", rc);
                queue->card->stats.tx_errors += count;
+               /* ok, since do_QDIO went wrong the buffers have not been given
+                * to the hardware. they still belong to us, so we can clear
+                * them and reuse then, i.e. set back next_buf_to_fill*/
+               for (i = index; i < index + count; ++i) {
+                       buf = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
+                       qeth_clear_output_buffer(queue, buf);
+               }
+               queue->next_buf_to_fill = index;
                return;
        }
+       atomic_add(count, &queue->used_buffers);
 #ifdef CONFIG_QETH_PERF_STATS
        queue->card->perf_stats.bufs_sent += count;
 #endif
@@ -2616,11 +2630,11 @@ qeth_switch_packing_state(struct qeth_qdio_out_q *queue)
                        queue->do_pack = 0;
                        /* flush packing buffers */
                        buffer = &queue->bufs[queue->next_buf_to_fill];
-                       BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED);
-                       if (buffer->next_element_to_fill > 0) {
-                               buffer->state = QETH_QDIO_BUF_PRIMED;
+                       if ((atomic_read(&buffer->state) ==
+                                               QETH_QDIO_BUF_EMPTY) &&
+                           (buffer->next_element_to_fill > 0)) {
+                               atomic_set(&buffer->state,QETH_QDIO_BUF_PRIMED);
                                flush_count++;
-                               atomic_inc(&queue->used_buffers);
                                queue->next_buf_to_fill =
                                        (queue->next_buf_to_fill + 1) %
                                        QDIO_MAX_BUFFERS_PER_Q;
@@ -2634,17 +2648,17 @@ static inline void
 qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue, int under_int)
 {
        struct qeth_qdio_out_buffer *buffer;
+       int index;
 
-       buffer = &queue->bufs[queue->next_buf_to_fill];
-       BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED);
-       if (buffer->next_element_to_fill > 0){
+       index = queue->next_buf_to_fill;
+       buffer = &queue->bufs[index];
+       if((atomic_read(&buffer->state) == QETH_QDIO_BUF_EMPTY) &&
+          (buffer->next_element_to_fill > 0)){
                /* it's a packing buffer */
-               buffer->state = QETH_QDIO_BUF_PRIMED;
-               atomic_inc(&queue->used_buffers);
-               qeth_flush_buffers(queue, under_int, queue->next_buf_to_fill,
-                                  1);
+               atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
                queue->next_buf_to_fill =
                        (queue->next_buf_to_fill + 1) % QDIO_MAX_BUFFERS_PER_Q;
+               qeth_flush_buffers(queue, under_int, index, 1);
        }
 }
 
@@ -2687,13 +2701,9 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status,
                        qeth_schedule_recovery(card);
                        return;
                }
-               /* is PCI flag set on buffer? */
-               if (buffer->buffer->element[0].flags & 0x40)
-                       atomic_dec(&queue->set_pci_flags_count);
-
-               qeth_clear_output_buffer(card, buffer);
-               atomic_dec(&queue->used_buffers);
+               qeth_clear_output_buffer(queue, buffer);
        }
+       atomic_sub(count, &queue->used_buffers);
 
        netif_wake_queue(card->dev);
 #ifdef CONFIG_QETH_PERF_STATS
@@ -2886,8 +2896,8 @@ qeth_free_qdio_buffers(struct qeth_card *card)
        /* free outbound qdio_qs */
        for (i = 0; i < card->qdio.no_out_queues; ++i){
                for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
-                       qeth_clear_output_buffer(card, &card->qdio.
-                                               out_qs[i]->bufs[j]);
+                       qeth_clear_output_buffer(card->qdio.out_qs[i],
+                                       &card->qdio.out_qs[i]->bufs[j]);
                kfree(card->qdio.out_qs[i]);
        }
        kfree(card->qdio.out_qs);
@@ -2904,8 +2914,8 @@ qeth_clear_qdio_buffers(struct qeth_card *card)
        for (i = 0; i < card->qdio.no_out_queues; ++i)
                if (card->qdio.out_qs[i]){
                        for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
-                               qeth_clear_output_buffer(card, &card->qdio.
-                                               out_qs[i]->bufs[j]);
+                               qeth_clear_output_buffer(card->qdio.out_qs[i],
+                                               &card->qdio.out_qs[i]->bufs[j]);
                }
 }
 
@@ -2957,8 +2967,8 @@ qeth_init_qdio_queues(struct qeth_card *card)
                memset(card->qdio.out_qs[i]->qdio_bufs, 0,
                       QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
                for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j){
-                       qeth_clear_output_buffer(card, &card->qdio.
-                                                out_qs[i]->bufs[j]);
+                       qeth_clear_output_buffer(card->qdio.out_qs[i],
+                                       &card->qdio.out_qs[i]->bufs[j]);
                }
                card->qdio.out_qs[i]->card = card;
                card->qdio.out_qs[i]->next_buf_to_fill = 0;
@@ -3670,7 +3680,7 @@ qeth_fill_buffer(struct qeth_qdio_out_q *queue, struct qeth_qdio_out_buffer *buf
        if (!queue->do_pack) {
                QETH_DBF_TEXT(trace, 6, "fillbfnp");
                /* set state to PRIMED -> will be flushed */
-               buf->state = QETH_QDIO_BUF_PRIMED;
+               atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
        } else {
                QETH_DBF_TEXT(trace, 6, "fillbfpa");
 #ifdef CONFIG_QETH_PERF_STATS
@@ -3682,7 +3692,7 @@ qeth_fill_buffer(struct qeth_qdio_out_q *queue, struct qeth_qdio_out_buffer *buf
                         * packed buffer if full -> set state PRIMED
                         * -> will be flushed
                         */
-                       buf->state = QETH_QDIO_BUF_PRIMED;
+                       atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
                }
        }
        return 0;
@@ -3695,32 +3705,27 @@ qeth_do_send_packet_fast(struct qeth_card *card, struct qeth_qdio_out_q *queue,
 {
        struct qeth_qdio_out_buffer *buffer;
        int index;
-       int rc = 0;
 
        QETH_DBF_TEXT(trace, 6, "dosndpfa");
 
        spin_lock(&queue->lock);
-       /* do we have empty buffers? */
-       if (atomic_read(&queue->used_buffers) >= (QDIO_MAX_BUFFERS_PER_Q - 1)){
+       index = queue->next_buf_to_fill;
+       buffer = &queue->bufs[queue->next_buf_to_fill];
+       /*
+        * check if buffer is empty to make sure that we do not 'overtake'
+        * ourselves and try to fill a buffer that is already primed
+        */
+       if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) {
                card->stats.tx_dropped++;
-               rc = -EBUSY;
                spin_unlock(&queue->lock);
-               goto out;
+               return -EBUSY;
        }
-       index = queue->next_buf_to_fill;
-       buffer = &queue->bufs[queue->next_buf_to_fill];
-       BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED);
        queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
                                  QDIO_MAX_BUFFERS_PER_Q;
-       atomic_inc(&queue->used_buffers);
-       spin_unlock(&queue->lock);
-
-       /* go on sending ... */
-       netif_wake_queue(skb->dev);
        qeth_fill_buffer(queue, buffer, (char *)hdr, skb);
        qeth_flush_buffers(queue, 0, index, 1);
-out:
-       return rc;
+       spin_unlock(&queue->lock);
+       return 0;
 }
 
 static inline int
@@ -3736,35 +3741,43 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
        QETH_DBF_TEXT(trace, 6, "dosndpkt");
 
        spin_lock(&queue->lock);
-       /* do we have empty buffers? */
-       if (atomic_read(&queue->used_buffers) >= (QDIO_MAX_BUFFERS_PER_Q - 2)){
-               card->stats.tx_dropped++;
-               rc = -EBUSY;
-               goto out;
-       }
        start_index = queue->next_buf_to_fill;
        buffer = &queue->bufs[queue->next_buf_to_fill];
-       BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED);
+       /*
+        * check if buffer is empty to make sure that we do not 'overtake'
+        * ourselves and try to fill a buffer that is already primed
+        */
+       if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){
+               card->stats.tx_dropped++;
+               spin_unlock(&queue->lock);
+               return -EBUSY;
+       }
        if (queue->do_pack){
                /* does packet fit in current buffer? */
-               if((QETH_MAX_BUFFER_ELEMENTS(card) - buffer->next_element_to_fill)
-                               < elements_needed){
+               if((QETH_MAX_BUFFER_ELEMENTS(card) -
+                   buffer->next_element_to_fill) < elements_needed){
                        /* ... no -> set state PRIMED */
-                       buffer->state = QETH_QDIO_BUF_PRIMED;
+                       atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
                        flush_count++;
-                       atomic_inc(&queue->used_buffers);
                        queue->next_buf_to_fill =
                                (queue->next_buf_to_fill + 1) %
                                QDIO_MAX_BUFFERS_PER_Q;
                        buffer = &queue->bufs[queue->next_buf_to_fill];
+                       /* we did a step forward, so check buffer state again */
+                       if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){
+                               card->stats.tx_dropped++;
+                               qeth_flush_buffers(queue, 0, start_index, 1);
+                               spin_unlock(&queue->lock);
+                               /* return EBUSY because we sent old packet, not
+                                * the current one */
+                               return -EBUSY;
+                       }
                }
        }
-
        qeth_fill_buffer(queue, buffer, (char *)hdr, skb);
-       if (buffer->state == QETH_QDIO_BUF_PRIMED){
+       if (atomic_read(&buffer->state) == QETH_QDIO_BUF_PRIMED){
                /* next time fill the next buffer */
                flush_count++;
-               atomic_inc(&queue->used_buffers);
                queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
                        QDIO_MAX_BUFFERS_PER_Q;
        }
@@ -3776,9 +3789,8 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
 
        if (!atomic_read(&queue->set_pci_flags_count))
                qeth_flush_buffers_on_no_pci(queue, 0);
-out:
-       spin_unlock(&queue->lock);
 
+       spin_unlock(&queue->lock);
        return rc;
 }
 
@@ -4078,21 +4090,43 @@ out_error:
 
 static int
 qeth_send_ipa_arp_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
-                     int len, int (*reply_cb)
-                                       (struct qeth_card *,
-                                        struct qeth_reply*, unsigned long),
+                     int len, int (*reply_cb)(struct qeth_card *,
+                                              struct qeth_reply *,
+                                              unsigned long),
                      void *reply_param)
 {
-       int rc;
-
        QETH_DBF_TEXT(trace,4,"sendarp");
 
        memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
        memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
               &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
-       rc = qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
-                                   reply_cb, reply_param);
-       return rc;
+       return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
+                                     reply_cb, reply_param);
+}
+
+static int
+qeth_send_ipa_snmp_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
+                     int len, int (*reply_cb)(struct qeth_card *,
+                                              struct qeth_reply *,
+                                              unsigned long),
+                     void *reply_param)
+{
+       u16 s1, s2;
+
+       QETH_DBF_TEXT(trace,4,"sendsnmp");
+
+       memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
+       memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
+              &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
+       /* adjust PDU length fields in IPA_PDU_HEADER */
+       s1 = (u32) IPA_PDU_HEADER_SIZE + len;
+       s2 = (u32) len;
+       memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
+       memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
+       memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
+       memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
+       return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
+                                     reply_cb, reply_param);
 }
 
 static struct qeth_cmd_buffer *
@@ -4135,8 +4169,7 @@ qeth_arp_query(struct qeth_card *card, char *udata)
 
        rc = qeth_send_ipa_arp_cmd(card, iob,
                                   QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN,
-                                  qeth_arp_query_cb,
-                                  (void *)&qinfo);
+                                  qeth_arp_query_cb, (void *)&qinfo);
        if (rc) {
                tmp = rc;
                PRINT_WARN("Error while querying ARP cache on %s: %s "
@@ -4182,9 +4215,10 @@ qeth_snmp_command_cb(struct qeth_card *card, struct qeth_reply *reply,
        }
        data_len = *((__u16*)QETH_IPA_PDU_LEN_PDU1(data));
        if (cmd->data.setadapterparms.hdr.seq_no == 1)
-               data_len -= (__u16)((char*)&snmp->request - (char *)cmd);
-       else
                data_len -= (__u16)((char *)&snmp->data - (char *)cmd);
+       else
+               data_len -= (__u16)((char*)&snmp->request - (char *)cmd);
+
        /* check if there is enough room in userspace */
        if ((qinfo->udata_len - qinfo->udata_offset) < data_len) {
                QETH_DBF_TEXT_(trace, 4, "scer3%i", -ENOMEM);
@@ -4193,15 +4227,17 @@ qeth_snmp_command_cb(struct qeth_card *card, struct qeth_reply *reply,
        }
        QETH_DBF_TEXT_(trace, 4, "snore%i",
                       cmd->data.setadapterparms.hdr.used_total);
-       QETH_DBF_TEXT_(trace, 4, "sseqn%i", cmd->data.setassparms.hdr.seq_no);
+       QETH_DBF_TEXT_(trace, 4, "sseqn%i", cmd->data.setadapterparms.hdr.seq_no);
        /*copy entries to user buffer*/
        if (cmd->data.setadapterparms.hdr.seq_no == 1) {
                memcpy(qinfo->udata + qinfo->udata_offset,
-                      (char *)snmp,offsetof(struct qeth_snmp_cmd,data));
+                      (char *)snmp,
+                      data_len + offsetof(struct qeth_snmp_cmd,data));
                qinfo->udata_offset += offsetof(struct qeth_snmp_cmd, data);
+       } else {
+               memcpy(qinfo->udata + qinfo->udata_offset,
+                      (char *)&snmp->request, data_len);
        }
-       memcpy(qinfo->udata + qinfo->udata_offset,
-              (char *)&snmp->data, data_len);
        qinfo->udata_offset += data_len;
        /* check if all replies received ... */
                QETH_DBF_TEXT_(trace, 4, "srtot%i",
@@ -4212,7 +4248,6 @@ qeth_snmp_command_cb(struct qeth_card *card, struct qeth_reply *reply,
            cmd->data.setadapterparms.hdr.used_total)
                return 1;
        return 0;
-
 }
 
 static struct qeth_cmd_buffer *
@@ -4244,7 +4279,8 @@ qeth_snmp_command(struct qeth_card *card, char *udata)
 {
        struct qeth_cmd_buffer *iob;
        struct qeth_ipa_cmd *cmd;
-       struct qeth_snmp_ureq ureq;
+       struct qeth_snmp_ureq *ureq;
+       int req_len;
        struct qeth_arp_query_info qinfo = {0, };
        int rc = 0;
 
@@ -4257,30 +4293,39 @@ qeth_snmp_command(struct qeth_card *card, char *udata)
                           "on %s!\n", card->info.if_name);
                return -EOPNOTSUPP;
        }
-       if (copy_from_user(&ureq, udata, sizeof(struct qeth_snmp_ureq)))
+       /* skip 4 bytes (data_len struct member) to get req_len */
+       if (copy_from_user(&req_len, udata + sizeof(int), sizeof(int)))
                return -EFAULT;
-       qinfo.udata_len = ureq.hdr.data_len;
-       if (!(qinfo.udata = kmalloc(qinfo.udata_len, GFP_KERNEL)))
+       ureq = kmalloc(req_len, GFP_KERNEL);
+       if (!ureq) {
+               QETH_DBF_TEXT(trace, 2, "snmpnome");
                return -ENOMEM;
+       }
+       if (copy_from_user(ureq, udata, req_len)){
+               kfree(ureq);
+               return -EFAULT;
+       }
+       qinfo.udata_len = ureq->hdr.data_len;
+       if (!(qinfo.udata = kmalloc(qinfo.udata_len, GFP_KERNEL))){
+               kfree(ureq);
+               return -ENOMEM;
+       }
        memset(qinfo.udata, 0, qinfo.udata_len);
        qinfo.udata_offset = sizeof(struct qeth_snmp_ureq_hdr);
 
        iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL,
-                                  QETH_SNMP_SETADP_CMDLENGTH+ureq.hdr.req_len);
+                                  QETH_SNMP_SETADP_CMDLENGTH + req_len);
        cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
-       memcpy(&cmd->data.setadapterparms.data.snmp, &ureq.cmd,
-              sizeof(struct qeth_snmp_cmd));
-       rc = qeth_send_ipa_arp_cmd(card, iob,
-                                  QETH_SETADP_BASE_LEN + QETH_ARP_DATA_SIZE +
-                                  ureq.hdr.req_len, qeth_snmp_command_cb,
-                                  (void *)&qinfo);
+       memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len);
+       rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len,
+                                   qeth_snmp_command_cb, (void *)&qinfo);
        if (rc)
                PRINT_WARN("SNMP command failed on %s: (0x%x)\n",
                           card->info.if_name, rc);
         else
                copy_to_user(udata, qinfo.udata, qinfo.udata_len);
 
-
+       kfree(ureq);
        kfree(qinfo.udata);
        return rc;
 }
@@ -4476,13 +4521,17 @@ qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data);
                break;
        case SIOC_QETH_GET_CARD_TYPE:
+               if ((card->info.type == QETH_CARD_TYPE_OSAE) &&
+                   !card->info.guestlan)
+                       return 1;
+               return 0;
                break;
        case SIOCGMIIPHY:
-               mii_data = (struct mii_ioctl_data *) &rq->ifr_ifru.ifru_data;
+               mii_data = if_mii(rq);
                mii_data->phy_id = 0;
                break;
        case SIOCGMIIREG:
-               mii_data = (struct mii_ioctl_data *) &rq->ifr_ifru.ifru_data;
+               mii_data = if_mii(rq);
                if (mii_data->phy_id != 0)
                        rc = -EINVAL;
                else
@@ -4497,7 +4546,7 @@ qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                        rc = -EPERM;
                        break;
                }
-               mii_data = (struct mii_ioctl_data *) &rq->ifr_ifru.ifru_data;
+               mii_data = if_mii(rq);
                if (mii_data->phy_id != 0)
                        rc = -EINVAL;
                else
index 5178a6c..910c5f5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.30 $)
+ * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.32 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  * This file contains code related to sysfs.
@@ -20,7 +20,7 @@
 #include "qeth_mpc.h"
 #include "qeth_fs.h"
 
-const char *VERSION_QETH_SYS_C = "$Revision: 1.30 $";
+const char *VERSION_QETH_SYS_C = "$Revision: 1.32 $";
 
 /*****************************************************************************/
 /*                                                                           */
@@ -1447,14 +1447,16 @@ qeth_driver_notifier_register_store(struct device_driver *ddrv, const char *buf,
 {
        int rc;
        int signum;
-       char *tmp;
+       char *tmp, *tmp2;
 
        tmp = strsep((char **) &buf, "\n");
-       if (!strcmp(tmp, "unregister")){
-               return qeth_notifier_unregister(current);
+       if (!strncmp(tmp, "unregister", 10)){
+               if ((rc = qeth_notifier_unregister(current)))
+                       return rc;
+               return count;
        }
 
-       signum = simple_strtoul(buf, &tmp, 10);
+       signum = simple_strtoul(tmp, &tmp2, 10);
        if ((signum < 0) || (signum > 32)){
                PRINT_WARN("Signal number %d is out of range\n", signum);
                return -EINVAL;
@@ -1465,7 +1467,7 @@ qeth_driver_notifier_register_store(struct device_driver *ddrv, const char *buf,
        return count;
 }
 
-static DRIVER_ATTR(notifier_register, 0644, 0,
+static DRIVER_ATTR(notifier_register, 0200, 0,
                   qeth_driver_notifier_register_store);
 
 int
index 2138af8..ffa996c 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
+#include <linux/workqueue.h>
 
 #include <asm/lowcore.h>
 
 // #define DBG(args,...) do {} while (0);
 
 static struct semaphore m_sem;
-static struct semaphore s_sem;
 
 extern int css_process_crw(int);
 extern int chsc_process_crw(void);
 extern int chp_process_crw(int, int);
 extern void css_reiterate_subchannels(void);
-extern void css_trigger_slow_path(void);
+
+extern struct workqueue_struct *slow_path_wq;
+extern struct work_struct slow_path_work;
 
 static void
 s390_handle_damage(char *msg)
@@ -39,21 +41,6 @@ s390_handle_damage(char *msg)
        disabled_wait((unsigned long) __builtin_return_address(0));
 }
 
-static int
-s390_mchk_slow_path(void *param)
-{
-       struct semaphore *sem;
-
-       sem = (struct semaphore *)param;
-       /* Set a nice name. */
-       daemonize("kslowcrw");
-repeat:
-       down_interruptible(sem);
-       css_trigger_slow_path();
-       goto repeat;
-       return 0;
-}
-
 /*
  * Retrieve CRWs and call function to handle event.
  *
@@ -130,7 +117,7 @@ repeat:
                }
        }
        if (slow)
-               up(&s_sem);
+               queue_work(slow_path_wq, &slow_path_work);
        goto repeat;
        return 0;
 }
@@ -202,7 +189,6 @@ static int
 machine_check_init(void)
 {
        init_MUTEX_LOCKED(&m_sem);
-       init_MUTEX_LOCKED( &s_sem );
        ctl_clear_bit(14, 25);  /* disable damage MCH */
        ctl_set_bit(14, 26);    /* enable degradation MCH */
        ctl_set_bit(14, 27);    /* enable system recovery MCH */
@@ -226,7 +212,6 @@ static int __init
 machine_check_crw_init (void)
 {
        kernel_thread(s390_collect_crw_info, &m_sem, CLONE_FS|CLONE_FILES);
-       kernel_thread(s390_mchk_slow_path, &s_sem, CLONE_FS|CLONE_FILES);
        ctl_set_bit(14, 28);    /* enable channel report MCH */
        return 0;
 }
index 632488e..209c3fb 100644 (file)
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/blkdev.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/byteorder.h>
-#include <linux/blkdev.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
 
-#include "scsi.h"
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_eh.h>
 #include <scsi/scsi_host.h>
-
+#include <scsi/scsi_tcq.h>
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_spi.h>
 
@@ -164,15 +167,15 @@ MODULE_LICENSE("GPL");
 #include "53c700_d.h"
 
 
-STATIC int NCR_700_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-STATIC int NCR_700_abort(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_bus_reset(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_dev_reset(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_host_reset(Scsi_Cmnd * SCpnt);
+STATIC int NCR_700_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+STATIC int NCR_700_abort(struct scsi_cmnd * SCpnt);
+STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt);
+STATIC int NCR_700_dev_reset(struct scsi_cmnd * SCpnt);
+STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt);
 STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
 STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
-STATIC int NCR_700_slave_configure(Scsi_Device *SDpnt);
-STATIC void NCR_700_slave_destroy(Scsi_Device *SDpnt);
+STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt);
+STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt);
 
 STATIC struct device_attribute *NCR_700_dev_attrs[];
 
@@ -279,7 +282,7 @@ NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata,
 }
 
 static inline __u8
-NCR_700_get_SXFER(Scsi_Device *SDp)
+NCR_700_get_SXFER(struct scsi_device *SDp)
 {
        struct NCR_700_Host_Parameters *hostdata = 
                (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
@@ -289,7 +292,7 @@ NCR_700_get_SXFER(Scsi_Device *SDp)
 }
 
 struct Scsi_Host *
-NCR_700_detect(Scsi_Host_Template *tpnt,
+NCR_700_detect(struct scsi_host_template *tpnt,
               struct NCR_700_Host_Parameters *hostdata)
 {
        dma_addr_t pScript, pSlots;
@@ -561,7 +564,7 @@ free_slot(struct NCR_700_command_slot *slot,
    the ITL and (if tagged) the ITLQ lists in _queuecommand */
 STATIC void
 save_for_reselection(struct NCR_700_Host_Parameters *hostdata,
-                    Scsi_Cmnd *SCp, __u32 dsp)
+                    struct scsi_cmnd *SCp, __u32 dsp)
 {
        /* Its just possible that this gets executed twice */
        if(SCp != NULL) {
@@ -575,27 +578,25 @@ save_for_reselection(struct NCR_700_Host_Parameters *hostdata,
 }
 
 STATIC inline void
-NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, Scsi_Cmnd *SCp,
+NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, struct scsi_cmnd *SCp,
              struct NCR_700_command_slot *slot)
 {
-       if(SCp->sc_data_direction != SCSI_DATA_NONE &&
-          SCp->sc_data_direction != SCSI_DATA_UNKNOWN) {
-               enum dma_data_direction direction = SCp->sc_data_direction;
+       if(SCp->sc_data_direction != DMA_NONE &&
+          SCp->sc_data_direction != DMA_BIDIRECTIONAL) {
                if(SCp->use_sg) {
                        dma_unmap_sg(hostdata->dev, SCp->buffer,
-                                    SCp->use_sg, direction);
+                                    SCp->use_sg, SCp->sc_data_direction);
                } else {
-                       dma_unmap_single(hostdata->dev,
-                                        slot->dma_handle,
+                       dma_unmap_single(hostdata->dev, slot->dma_handle,
                                         SCp->request_bufflen,
-                                        direction);
+                                        SCp->sc_data_direction);
                }
        }
 }
 
 STATIC inline void
 NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
-              Scsi_Cmnd *SCp, int result)
+              struct scsi_cmnd *SCp, int result)
 {
        hostdata->state = NCR_700_HOST_FREE;
        hostdata->cmd = NULL;
@@ -611,7 +612,7 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
 #ifdef NCR_700_DEBUG
                        printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n",
                               SCp, SCp->cmnd[7], result);
-                       print_sense("53c700", SCp);
+                       scsi_print_sense("53c700", SCp);
 
 #endif
                        /* restore the old result if the request sense was
@@ -780,7 +781,7 @@ NCR_700_chip_reset(struct Scsi_Host *host)
 STATIC __u32
 process_extended_message(struct Scsi_Host *host, 
                         struct NCR_700_Host_Parameters *hostdata,
-                        Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps)
+                        struct scsi_cmnd *SCp, __u32 dsp, __u32 dsps)
 {
        __u32 resume_offset = dsp, temp = dsp + 8;
        __u8 pun = 0xff, lun = 0xff;
@@ -849,7 +850,7 @@ process_extended_message(struct Scsi_Host *host,
                printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",
                       host->host_no, pun, lun,
                       NCR_700_phase[(dsps & 0xf00) >> 8]);
-               print_msg(hostdata->msgin);
+               scsi_print_msg(hostdata->msgin);
                printk("\n");
                /* just reject it */
                hostdata->msgout[0] = A_REJECT_MSG;
@@ -865,7 +866,7 @@ process_extended_message(struct Scsi_Host *host,
 
 STATIC __u32
 process_message(struct Scsi_Host *host,        struct NCR_700_Host_Parameters *hostdata,
-               Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps)
+               struct scsi_cmnd *SCp, __u32 dsp, __u32 dsps)
 {
        /* work out where to return to */
        __u32 temp = dsp + 8, resume_offset = dsp;
@@ -879,7 +880,7 @@ process_message(struct Scsi_Host *host,     struct NCR_700_Host_Parameters *hostdata
 #ifdef NCR_700_DEBUG
        printk("scsi%d (%d:%d): message %s: ", host->host_no, pun, lun,
               NCR_700_phase[(dsps & 0xf00) >> 8]);
-       print_msg(hostdata->msgin);
+       scsi_print_msg(hostdata->msgin);
        printk("\n");
 #endif
 
@@ -927,7 +928,7 @@ process_message(struct Scsi_Host *host,     struct NCR_700_Host_Parameters *hostdata
                       host->host_no, pun, lun,
                       NCR_700_phase[(dsps & 0xf00) >> 8]);
 
-               print_msg(hostdata->msgin);
+               scsi_print_msg(hostdata->msgin);
                printk("\n");
                /* just reject it */
                hostdata->msgout[0] = A_REJECT_MSG;
@@ -946,7 +947,7 @@ process_message(struct Scsi_Host *host,     struct NCR_700_Host_Parameters *hostdata
 }
 
 STATIC __u32
-process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
+process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
                         struct Scsi_Host *host,
                         struct NCR_700_Host_Parameters *hostdata)
 {
@@ -975,7 +976,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                                NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
                        } else {
 #ifdef NCR_DEBUG
-                               print_command(SCp->cmnd);
+                               scsi_print_command(SCp);
                                printk("  cmd %p has status %d, requesting sense\n",
                                       SCp, hostdata->status[0]);
 #endif
@@ -1004,7 +1005,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                                SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
                                SCp->cmnd[7] = hostdata->status[0];
                                SCp->use_sg = 0;
-                               SCp->sc_data_direction = SCSI_DATA_READ;
+                               SCp->sc_data_direction = DMA_FROM_DEVICE;
                                dma_sync_single_for_device(hostdata->dev, slot->pCmd,
                                                           SCp->cmd_len, DMA_TO_DEVICE);
                                SCp->request_bufflen = sizeof(SCp->sense_buffer);
@@ -1053,7 +1054,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                       NCR_700_phase[i],
                       sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
                printk(KERN_ERR "         len = %d, cmd =", SCp->cmd_len);
-               print_command(SCp->cmnd);
+               scsi_print_command(SCp);
 
                NCR_700_internal_bus_reset(host);
        } else if((dsps & 0xfffff000) == A_FATAL) {
@@ -1080,7 +1081,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                __u8 lun;
                struct NCR_700_command_slot *slot;
                __u8 reselection_id = hostdata->reselection_id;
-               Scsi_Device *SDp;
+               struct scsi_device *SDp;
 
                lun = hostdata->msgin[0] & 0x1f;
 
@@ -1095,7 +1096,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                        BUG();
                }
                if(hostdata->msgin[1] == A_SIMPLE_TAG_MSG) {
-                       Scsi_Cmnd *SCp = scsi_find_tag(SDp, hostdata->msgin[2]);
+                       struct scsi_cmnd *SCp = scsi_find_tag(SDp, hostdata->msgin[2]);
                        if(unlikely(SCp == NULL)) {
                                printk(KERN_ERR "scsi%d: (%d:%d) no saved request for tag %d\n", 
                                       host->host_no, reselection_id, lun, hostdata->msgin[2]);
@@ -1107,7 +1108,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                               host->host_no, SDp->id, SDp->lun,
                               hostdata->msgin[2], slot, slot->tag));
                } else {
-                       Scsi_Cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG);
+                       struct scsi_cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG);
                        if(unlikely(SCp == NULL)) {
                                printk(KERN_ERR "scsi%d: (%d:%d) no saved request for untagged cmd\n", 
                                       host->host_no, reselection_id, lun);
@@ -1234,7 +1235,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                       host->host_no, pun, lun, NCR_700_condition[i],
                       NCR_700_phase[j], dsp - hostdata->pScript);
                if(SCp != NULL) {
-                       print_command(SCp->cmnd);
+                       scsi_print_command(SCp);
 
                        if(SCp->use_sg) {
                                for(i = 0; i < SCp->use_sg + 1; i++) {
@@ -1270,7 +1271,7 @@ process_selection(struct Scsi_Host *host, __u32 dsp)
        __u32 resume_offset = 0;
        struct NCR_700_Host_Parameters *hostdata =
                (struct NCR_700_Host_Parameters *)host->hostdata[0];
-       Scsi_Cmnd *SCp = hostdata->cmd;
+       struct scsi_cmnd *SCp = hostdata->cmd;
        __u8 sbcl;
 
        for(count = 0; count < 5; count++) {
@@ -1373,7 +1374,7 @@ NCR_700_flush_fifo(struct Scsi_Host *host) {
 /* The queue lock with interrupts disabled must be held on entry to
  * this function */
 STATIC int
-NCR_700_start_command(Scsi_Cmnd *SCp)
+NCR_700_start_command(struct scsi_cmnd *SCp)
 {
        struct NCR_700_command_slot *slot =
                (struct NCR_700_command_slot *)SCp->host_scribble;
@@ -1481,7 +1482,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
                __u32 dsps;
                __u8 sstat0 = 0, dstat = 0;
                __u32 dsp;
-               Scsi_Cmnd *SCp = hostdata->cmd;
+               struct scsi_cmnd *SCp = hostdata->cmd;
                enum NCR_700_Host_State state;
 
                handled = 1;
@@ -1514,7 +1515,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
                }
 
                if(sstat0 & SCSI_RESET_DETECTED) {
-                       Scsi_Device *SDp;
+                       struct scsi_device *SDp;
                        int i;
 
                        hostdata->state = NCR_700_HOST_BUSY;
@@ -1530,7 +1531,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
                        
                        /* clear all the slots and their pending commands */
                        for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
-                               Scsi_Cmnd *SCp;
+                               struct scsi_cmnd *SCp;
                                struct NCR_700_command_slot *slot =
                                        &hostdata->slots[i];
 
@@ -1590,7 +1591,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
                                printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x\n",
                                       host->host_no, pun, lun,
                                       SGcount, data_transfer);
-                               print_command(SCp->cmnd);
+                               scsi_print_command(SCp);
                                if(residual) {
                                        printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x, residual %d\n",
                                       host->host_no, pun, lun,
@@ -1731,7 +1732,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
 }
 
 STATIC int
-NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
+NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
 {
        struct NCR_700_Host_Parameters *hostdata = 
                (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
@@ -1781,7 +1782,7 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
 
 #ifdef NCR_700_DEBUG
        printk("53c700: scsi%d, command ", SCp->device->host->host_no);
-       print_command(SCp->cmnd);
+       scsi_print_command(SCp);
 #endif
        if(SCp->device->tagged_supported && !SCp->device->simple_tags
           && (hostdata->tag_negotiated &(1<<SCp->device->id)) == 0
@@ -1827,13 +1828,13 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
        /* sanity check: some of the commands generated by the mid-layer
         * have an eccentric idea of their sc_data_direction */
        if(!SCp->use_sg && !SCp->request_bufflen 
-          && SCp->sc_data_direction != SCSI_DATA_NONE) {
+          && SCp->sc_data_direction != DMA_NONE) {
 #ifdef NCR_700_DEBUG
                printk("53c700: Command");
-               print_command(SCp->cmnd);
+               scsi_print_command(SCp);
                printk("Has wrong data direction %d\n", SCp->sc_data_direction);
 #endif
-               SCp->sc_data_direction = SCSI_DATA_NONE;
+               SCp->sc_data_direction = DMA_NONE;
        }
 
        switch (SCp->cmnd[0]) {
@@ -1844,20 +1845,20 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
        default:
                /* OK, get it from the command */
                switch(SCp->sc_data_direction) {
-               case SCSI_DATA_UNKNOWN:
+               case DMA_BIDIRECTIONAL:
                default:
                        printk(KERN_ERR "53c700: Unknown command for data direction ");
-                       print_command(SCp->cmnd);
+                       scsi_print_command(SCp);
                        
                        move_ins = 0;
                        break;
-               case SCSI_DATA_NONE:
+               case DMA_NONE:
                        move_ins = 0;
                        break;
-               case SCSI_DATA_READ:
+               case DMA_FROM_DEVICE:
                        move_ins = SCRIPT_MOVE_DATA_IN;
                        break;
-               case SCSI_DATA_WRITE:
+               case DMA_TO_DEVICE:
                        move_ins = SCRIPT_MOVE_DATA_OUT;
                        break;
                }
@@ -1914,13 +1915,13 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
 }
 
 STATIC int
-NCR_700_abort(Scsi_Cmnd * SCp)
+NCR_700_abort(struct scsi_cmnd * SCp)
 {
        struct NCR_700_command_slot *slot;
 
        printk(KERN_INFO "scsi%d (%d:%d) New error handler wants to abort command\n\t",
               SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
-       print_command(SCp->cmnd);
+       scsi_print_command(SCp);
 
        slot = (struct NCR_700_command_slot *)SCp->host_scribble;
 
@@ -1946,7 +1947,7 @@ NCR_700_abort(Scsi_Cmnd * SCp)
 }
 
 STATIC int
-NCR_700_bus_reset(Scsi_Cmnd * SCp)
+NCR_700_bus_reset(struct scsi_cmnd * SCp)
 {
        DECLARE_COMPLETION(complete);
        struct NCR_700_Host_Parameters *hostdata = 
@@ -1954,7 +1955,7 @@ NCR_700_bus_reset(Scsi_Cmnd * SCp)
 
        printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t",
               SCp->device->host->host_no, SCp->device->id, SCp->device->lun, SCp);
-       print_command(SCp->cmnd);
+       scsi_print_command(SCp);
        /* In theory, eh_complete should always be null because the
         * eh is single threaded, but just in case we're handling a
         * reset via sg or something */
@@ -1976,21 +1977,21 @@ NCR_700_bus_reset(Scsi_Cmnd * SCp)
 }
 
 STATIC int
-NCR_700_dev_reset(Scsi_Cmnd * SCp)
+NCR_700_dev_reset(struct scsi_cmnd * SCp)
 {
        printk(KERN_INFO "scsi%d (%d:%d) New error handler wants device reset\n\t",
               SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
-       print_command(SCp->cmnd);
+       scsi_print_command(SCp);
        
        return FAILED;
 }
 
 STATIC int
-NCR_700_host_reset(Scsi_Cmnd * SCp)
+NCR_700_host_reset(struct scsi_cmnd * SCp)
 {
        printk(KERN_INFO "scsi%d (%d:%d) New error handler wants HOST reset\n\t",
               SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
-       print_command(SCp->cmnd);
+       scsi_print_command(SCp);
 
        NCR_700_internal_bus_reset(SCp->device->host);
        NCR_700_chip_reset(SCp->device->host);
@@ -2043,7 +2044,7 @@ NCR_700_set_offset(struct scsi_device *SDp, int offset)
 
 
 STATIC int
-NCR_700_slave_configure(Scsi_Device *SDp)
+NCR_700_slave_configure(struct scsi_device *SDp)
 {
        struct NCR_700_Host_Parameters *hostdata = 
                (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
@@ -2066,7 +2067,7 @@ NCR_700_slave_configure(Scsi_Device *SDp)
 }
 
 STATIC void
-NCR_700_slave_destroy(Scsi_Device *SDp)
+NCR_700_slave_destroy(struct scsi_device *SDp)
 {
        /* to do here: deallocate memory */
 }
index c1f0aa3..b357a4a 100644 (file)
@@ -9,9 +9,11 @@
 #define _53C700_H
 
 #include <linux/interrupt.h>
-
 #include <asm/io.h>
 
+#include <scsi/scsi_device.h>
+
+
 #if defined(CONFIG_53C700_MEM_MAPPED) && defined(CONFIG_53C700_IO_MAPPED)
 #define CONFIG_53C700_BOTH_MAPPED
 #endif
@@ -57,7 +59,8 @@
 struct NCR_700_Host_Parameters;
 
 /* These are the externally used routines */
-struct Scsi_Host *NCR_700_detect(Scsi_Host_Template *, struct NCR_700_Host_Parameters *);
+struct Scsi_Host *NCR_700_detect(struct scsi_host_template *,
+               struct NCR_700_Host_Parameters *);
 int NCR_700_release(struct Scsi_Host *host);
 irqreturn_t NCR_700_intr(int, void *, struct pt_regs *);
 
@@ -102,7 +105,7 @@ struct NCR_700_SG_List {
 #define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19)
 
 static inline void
-NCR_700_set_depth(Scsi_Device *SDp, __u8 depth)
+NCR_700_set_depth(struct scsi_device *SDp, __u8 depth)
 {
        long l = (long)SDp->hostdata;
 
@@ -111,27 +114,27 @@ NCR_700_set_depth(Scsi_Device *SDp, __u8 depth)
        SDp->hostdata = (void *)l;
 }
 static inline __u8
-NCR_700_get_depth(Scsi_Device *SDp)
+NCR_700_get_depth(struct scsi_device *SDp)
 {
        return ((((unsigned long)SDp->hostdata) & 0xff00)>>8);
 }
 static inline int
-NCR_700_is_flag_set(Scsi_Device *SDp, __u32 flag)
+NCR_700_is_flag_set(struct scsi_device *SDp, __u32 flag)
 {
        return (((unsigned long)SDp->hostdata) & flag) == flag;
 }
 static inline int
-NCR_700_is_flag_clear(Scsi_Device *SDp, __u32 flag)
+NCR_700_is_flag_clear(struct scsi_device *SDp, __u32 flag)
 {
        return (((unsigned long)SDp->hostdata) & flag) == 0;
 }
 static inline void
-NCR_700_set_flag(Scsi_Device *SDp, __u32 flag)
+NCR_700_set_flag(struct scsi_device *SDp, __u32 flag)
 {
        SDp->hostdata = (void *)((long)SDp->hostdata | (flag & 0xffff0000));
 }
 static inline void
-NCR_700_clear_flag(Scsi_Device *SDp, __u32 flag)
+NCR_700_clear_flag(struct scsi_device *SDp, __u32 flag)
 {
        SDp->hostdata = (void *)((long)SDp->hostdata & ~(flag & 0xffff0000));
 }
@@ -147,7 +150,7 @@ struct NCR_700_command_slot {
        __u8    state;
        int     tag;
        __u32   resume_offset;
-       Scsi_Cmnd       *cmnd;
+       struct scsi_cmnd *cmnd;
        /* The pci_mapped address of the actual command in cmnd */
        dma_addr_t      pCmd;
        __u32           temp;
@@ -185,7 +188,7 @@ struct NCR_700_Host_Parameters {
        __u32   pScript;                /* physical mem addr of script */
 
        enum NCR_700_Host_State state; /* protected by state lock */
-       Scsi_Cmnd *cmd;
+       struct scsi_cmnd *cmd;
        /* Note: pScript contains the single consistent block of
         * memory.  All the msgin, msgout and status are allocated in
         * this memory too (at separate cache lines).  TOTAL_MEM_SIZE
index 0cd207e..6104ca0 100644 (file)
@@ -227,7 +227,7 @@ config SCSI_DECSII
        depends on DECSTATION && SCSI
 
 config BLK_DEV_3W_XXXX_RAID
-       tristate "3ware Hardware ATA-RAID support"
+       tristate "3ware 5/6/7/8xxx ATA-RAID support"
        depends on PCI && SCSI
        help
          3ware is the only hardware ATA-Raid product in Linux to date.
@@ -239,6 +239,17 @@ config BLK_DEV_3W_XXXX_RAID
          Please read the comments at the top of
          <file:drivers/scsi/3w-xxxx.c>.
 
+config SCSI_3W_9XXX
+       tristate "3ware 9xxx SATA-RAID support"
+       depends on PCI && SCSI
+       help
+         This driver supports the 9000 series 3ware SATA-RAID cards.
+
+         <http://www.amcc.com>
+
+         Please read the comments at the top of
+         <file:drivers/scsi/3w-9xxx.c>.
+
 config SCSI_7000FASST
        tristate "7000FASST SCSI support"
        depends on ISA && SCSI
@@ -352,7 +363,7 @@ source "drivers/scsi/aic7xxx/Kconfig.aic79xx"
 # All the I2O code and drivers do not seem to be 64bit safe.
 config SCSI_DPT_I2O
        tristate "Adaptec I2O RAID support "
-       depends on !64BIT && SCSI
+       depends on !64BIT && SCSI && PCI
        help
          This driver supports all of Adaptec's I2O based RAID controllers as 
          well as the DPT SmartRaid V cards.  This is an Adaptec maintained
@@ -478,9 +489,7 @@ config SCSI_BUSLOGIC
          Adapters. Consult the SCSI-HOWTO, available from
          <http://www.tldp.org/docs.html#howto>, and the files
          <file:Documentation/scsi/BusLogic.txt> and
-         <file:Documentation/scsi/FlashPoint.txt> for more information. If this
-         driver does not work correctly without modification, please contact
-         the author, Leonard N. Zubkoff, by email to lnz@dandelion.com.
+         <file:Documentation/scsi/FlashPoint.txt> for more information.
 
          To compile this driver as a module, choose M here: the
          module will be called BusLogic.
@@ -494,9 +503,15 @@ config SCSI_OMIT_FLASHPOINT
          substantial, so users of MultiMaster Host Adapters may wish to omit
          it.
 
+#
+# This is marked broken because it uses over 4kB of stack in
+# just two routines:
+#     2076  CpqTsProcessIMQEntry
+#     2052  PeekIMQEntry
+#
 config SCSI_CPQFCTS
        tristate "Compaq Fibre Channel 64-bit/66Mhz HBA support"
-       depends on PCI && SCSI
+       depends on PCI && SCSI && BROKEN
        help
          Say Y here to compile in support for the Compaq StorageWorks Fibre
          Channel 64-bit/66Mhz Host Bus Adapter.
@@ -1710,18 +1725,6 @@ config SCSI_SUNESP
          To compile this driver as a module, choose M here: the
          module will be called esp.
 
-config SCSI_PC980155
-       tristate "NEC PC-9801-55 SCSI support"
-       depends on X86_PC9800 && SCSI
-       help
-         If you have the NEC PC-9801-55 SCSI interface card or compatibles
-         for NEC PC-9801/PC-9821, say Y.
-
-config WD33C93_PIO
-       bool
-       depends on SCSI_PC980155
-       default y
-
 #      bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI
 
 config ZFCP
index 73e462e..fe95ba7 100644 (file)
@@ -34,7 +34,6 @@ obj-$(CONFIG_SCSI_AMIGA7XX)   += amiga7xx.o   53c7xx.o
 obj-$(CONFIG_A3000_SCSI)       += a3000.o      wd33c93.o
 obj-$(CONFIG_A2091_SCSI)       += a2091.o      wd33c93.o
 obj-$(CONFIG_GVP11_SCSI)       += gvp11.o      wd33c93.o
-obj-$(CONFIG_SCSI_PC980155)    += pc980155.o   wd33c93.o
 obj-$(CONFIG_MVME147_SCSI)     += mvme147.o    wd33c93.o
 obj-$(CONFIG_SGIWD93_SCSI)     += sgiwd93.o    wd33c93.o
 obj-$(CONFIG_CYBERSTORM_SCSI)  += NCR53C9x.o   cyberstorm.o
@@ -109,6 +108,7 @@ obj-$(CONFIG_SCSI_MAC53C94) += mac53c94.o
 obj-$(CONFIG_SCSI_PLUTO)       += pluto.o
 obj-$(CONFIG_SCSI_DECNCR)      += NCR53C9x.o   dec_esp.o
 obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o
+obj-$(CONFIG_SCSI_3W_9XXX)     += 3w-9xxx.o
 obj-$(CONFIG_SCSI_PPA)         += ppa.o
 obj-$(CONFIG_SCSI_IMM)         += imm.o
 obj-$(CONFIG_JAZZ_ESP)         += NCR53C9x.o   jazz_esp.o
@@ -142,7 +142,6 @@ scsi_mod-y                  += scsi.o hosts.o scsi_ioctl.o constants.o \
                                   scsi_devinfo.o
 scsi_mod-$(CONFIG_SYSCTL)      += scsi_sysctl.o
 scsi_mod-$(CONFIG_SCSI_PROC_FS)        += scsi_proc.o
-scsi_mod-$(CONFIG_X86_PC9800)  += scsi_pc98.o
 
 sd_mod-objs    := sd.o
 sr_mod-objs    := sr.o sr_ioctl.o sr_vendor.o
index 2135029..9f70a7b 100644 (file)
@@ -3646,4 +3646,15 @@ void esp_release(void)
 }
 #endif
 
+EXPORT_SYMBOL(esp_abort);
+EXPORT_SYMBOL(esp_allocate);
+EXPORT_SYMBOL(esp_deallocate);
+EXPORT_SYMBOL(esp_initialize);
+EXPORT_SYMBOL(esp_intr);
+EXPORT_SYMBOL(esp_queue);
+EXPORT_SYMBOL(esp_reset);
+EXPORT_SYMBOL(esp_slave_alloc);
+EXPORT_SYMBOL(esp_slave_destroy);
+EXPORT_SYMBOL(esps_in_use);
+
 MODULE_LICENSE("GPL");
index 8c0fc3f..802f907 100644 (file)
@@ -98,8 +98,6 @@
 #include <linux/module.h>
 #include <linux/mca.h>
 #include <asm/io.h>
-
-#include "scsi.h"
 #include <scsi/scsi_host.h>
 
 #include "53c700.h"
@@ -156,7 +154,7 @@ param_setup(char *string)
 
 /* Host template.  The 53c700 routine NCR_700_detect will
  * fill in all of the missing routines */
-static Scsi_Host_Template NCR_D700_driver_template = {
+static struct scsi_host_template NCR_D700_driver_template = {
        .module                 = THIS_MODULE,
        .name                   = "NCR Dual 700 MCA",
        .proc_name              = "NCR_D700",
index c48c59a..8eb05dd 100644 (file)
 
 */
 
-
-/*
- * --- Linux Version
- */
-
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif /* LINUX_VERSION_CODE */
-
-/* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
-#define ASC_LINUX_VERSION(V, P, S)    (((V) * 65536) + ((P) * 256) + (S))
-#define ASC_LINUX_KERNEL22 (LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
-#define ASC_LINUX_KERNEL24 (LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,4,0))
-
-/* Driver supported only in version 2.2 and version >= 2.4. */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,2,0) || \
-    (LINUX_VERSION_CODE > ASC_LINUX_VERSION(2,3,0) && \
-     LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
-#error "AdvanSys driver supported only in 2.2 and 2.4 or greater kernels."
-#endif
-
 /*
  * --- Linux Include Files
  */
 #include <linux/blkdev.h>
 #include <linux/stat.h>
 #include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
 
 typedef unsigned char uchar;
 
-#ifndef NULL
-#define NULL     (0)
-#endif
 #ifndef TRUE
 #define TRUE     (1)
 #endif
@@ -986,49 +963,6 @@ typedef unsigned char uchar;
 #define ASC_MIN_SENSE_LEN   14
 #define ASC_MAX_CDB_LEN     12
 #define ASC_SCSI_RESET_HOLD_TIME_US  60
-#define SCSICMD_TestUnitReady     0x00
-#define SCSICMD_Rewind            0x01
-#define SCSICMD_Rezero            0x01
-#define SCSICMD_RequestSense      0x03
-#define SCSICMD_Format            0x04
-#define SCSICMD_FormatUnit        0x04
-#define SCSICMD_Read6             0x08
-#define SCSICMD_Write6            0x0A
-#define SCSICMD_Seek6             0x0B
-#define SCSICMD_Inquiry           0x12
-#define SCSICMD_Verify6           0x13
-#define SCSICMD_ModeSelect6       0x15
-#define SCSICMD_ModeSense6        0x1A
-#define SCSICMD_StartStopUnit     0x1B
-#define SCSICMD_LoadUnloadTape    0x1B
-#define SCSICMD_ReadCapacity      0x25
-#define SCSICMD_Read10            0x28
-#define SCSICMD_Write10           0x2A
-#define SCSICMD_Seek10            0x2B
-#define SCSICMD_Erase10           0x2C
-#define SCSICMD_WriteAndVerify10  0x2E
-#define SCSICMD_Verify10          0x2F
-#define SCSICMD_WriteBuffer       0x3B
-#define SCSICMD_ReadBuffer        0x3C
-#define SCSICMD_ReadLong          0x3E
-#define SCSICMD_WriteLong         0x3F
-#define SCSICMD_ReadTOC           0x43
-#define SCSICMD_ReadHeader        0x44
-#define SCSICMD_ModeSelect10      0x55
-#define SCSICMD_ModeSense10       0x5A
-
-/* Inquiry Data Peripheral Device Types */
-#define SCSI_TYPE_DASD     0x00
-#define SCSI_TYPE_SASD     0x01
-#define SCSI_TYPE_PRN      0x02
-#define SCSI_TYPE_PROC     0x03
-#define SCSI_TYPE_WORM     0x04
-#define SCSI_TYPE_CDROM    0x05
-#define SCSI_TYPE_SCANNER  0x06
-#define SCSI_TYPE_OPTMEM   0x07
-#define SCSI_TYPE_MED_CHG  0x08
-#define SCSI_TYPE_COMM     0x09
-#define SCSI_TYPE_UNKNOWN  0x1F
 
 #define ADV_INQ_CLOCKING_ST_ONLY    0x0
 #define ADV_INQ_CLOCKING_DT_ONLY    0x1
@@ -1047,36 +981,11 @@ typedef unsigned char uchar;
 #define ASC_SCSIDIR_T2H      0x08
 #define ASC_SCSIDIR_H2T      0x10
 #define ASC_SCSIDIR_NODATA   0x18
-#define SCSI_SENKEY_NO_SENSE      0x00
-#define SCSI_SENKEY_UNDEFINED     0x01
-#define SCSI_SENKEY_NOT_READY     0x02
-#define SCSI_SENKEY_MEDIUM_ERR    0x03
-#define SCSI_SENKEY_HW_ERR        0x04
-#define SCSI_SENKEY_ILLEGAL       0x05
-#define SCSI_SENKEY_ATTENTION     0x06
-#define SCSI_SENKEY_PROTECTED     0x07
-#define SCSI_SENKEY_BLANK         0x08
-#define SCSI_SENKEY_V_UNIQUE      0x09
-#define SCSI_SENKEY_CPY_ABORT     0x0A
-#define SCSI_SENKEY_ABORT         0x0B
-#define SCSI_SENKEY_EQUAL         0x0C
-#define SCSI_SENKEY_VOL_OVERFLOW  0x0D
-#define SCSI_SENKEY_MISCOMP       0x0E
-#define SCSI_SENKEY_RESERVED      0x0F
 #define SCSI_ASC_NOMEDIA          0x3A
 #define ASC_SRB_HOST(x)  ((uchar)((uchar)(x) >> 4))
 #define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
 #define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
 #define PUT_CDB1(x)   ((uchar)((uint)(x) >> 8))
-#define SS_GOOD              0x00
-#define SS_CHK_CONDITION     0x02
-#define SS_CONDITION_MET     0x04
-#define SS_TARGET_BUSY       0x08
-#define SS_INTERMID          0x10
-#define SS_INTERMID_COND_MET 0x14
-#define SS_RSERV_CONFLICT    0x18
-#define SS_CMD_TERMINATED    0x22
-#define SS_QUEUE_FULL        0x28
 #define MS_CMD_DONE    0x00
 #define MS_EXTEND      0x01
 #define MS_SDTR_LEN    0x03
@@ -1085,26 +994,6 @@ typedef unsigned char uchar;
 #define MS_WDTR_CODE   0x03
 #define MS_MDP_LEN    0x05
 #define MS_MDP_CODE   0x00
-#define M1_SAVE_DATA_PTR        0x02
-#define M1_RESTORE_PTRS         0x03
-#define M1_DISCONNECT           0x04
-#define M1_INIT_DETECTED_ERR    0x05
-#define M1_ABORT                0x06
-#define M1_MSG_REJECT           0x07
-#define M1_NO_OP                0x08
-#define M1_MSG_PARITY_ERR       0x09
-#define M1_LINK_CMD_DONE        0x0A
-#define M1_LINK_CMD_DONE_WFLAG  0x0B
-#define M1_BUS_DVC_RESET        0x0C
-#define M1_ABORT_TAG            0x0D
-#define M1_CLR_QUEUE            0x0E
-#define M1_INIT_RECOVERY        0x0F
-#define M1_RELEASE_RECOVERY     0x10
-#define M1_KILL_IO_PROC         0x11
-#define M2_QTAG_MSG_SIMPLE      0x20
-#define M2_QTAG_MSG_HEAD        0x21
-#define M2_QTAG_MSG_ORDERED     0x22
-#define M2_IGNORE_WIDE_RESIDUE  0x23
 
 /*
  * Inquiry data structure and bitfield macros
@@ -1576,7 +1465,7 @@ typedef struct asc_dvc_cfg {
     uchar               sdtr_period_offset[ASC_MAX_TID + 1];
     ushort              pci_slot_info;
     uchar               adapter_info[6];
-    struct pci_dev     *pci_dev;
+    struct device      *dev;
 } ASC_DVC_CFG;
 
 #define ASC_DEF_DVC_CNTL       0xFFFF
@@ -3082,7 +2971,7 @@ typedef struct adv_dvc_cfg {
   ushort serial1;           /* EEPROM serial number word 1 */
   ushort serial2;           /* EEPROM serial number word 2 */
   ushort serial3;           /* EEPROM serial number word 3 */
-  struct pci_dev *pci_dev;  /* pointer to the pci dev structure for this board */
+  struct device *dev;  /* pointer to the pci dev structure for this board */
 } ADV_DVC_CFG;
 
 struct adv_dvc_var;
@@ -3581,19 +3470,6 @@ typedef struct {
 
 #define NO_ISA_DMA              0xff        /* No ISA DMA Channel Used */
 
-/*
- * If the Linux kernel version supports freeing initialization code
- * and data after loading, define macros for this purpose. These macros
- * are not used when the driver is built as a module, cf. linux/init.h.
- */
-#if ASC_LINUX_KERNEL24
-#define ASC_INITFUNC(type, func)        type __init func
-#elif ASC_LINUX_KERNEL22
-#define ASC_INITFUNC(type, func)        __initfunc(type func)
-#endif
-#define ASC_INITDATA                    __initdata
-#define ASC_INIT                        __init
-
 #define ASC_INFO_SIZE           128            /* advansys_info() line size */
 
 #ifdef CONFIG_PROC_FS
@@ -3610,8 +3486,6 @@ typedef struct {
         } \
         cp += len; \
     }
-
-#define ASC_MIN(a, b) (((a) < (b)) ? (a) : (b))
 #endif /* CONFIG_PROC_FS */
 
 /* Asc Library return codes */
@@ -3685,53 +3559,6 @@ typedef Scsi_Cmnd            REQ, *REQP;
 /* Return non-zero, if the queue is empty. */
 #define ASC_QUEUE_EMPTY(ascq)    ((ascq)->q_tidmask == 0)
 
-/* PCI configuration declarations */
-
-#define PCI_BASE_CLASS_PREDEFINED               0x00
-#define PCI_BASE_CLASS_MASS_STORAGE             0x01
-#define PCI_BASE_CLASS_NETWORK                  0x02
-#define PCI_BASE_CLASS_DISPLAY                  0x03
-#define PCI_BASE_CLASS_MULTIMEDIA               0x04
-#define PCI_BASE_CLASS_MEMORY_CONTROLLER        0x05
-#define PCI_BASE_CLASS_BRIDGE_DEVICE            0x06
-
-/* MASS STORAGE */
-#define PCI_SUB_CLASS_SCSI_CONTROLLER           0x00
-#define PCI_SUB_CLASS_IDE_CONTROLLER            0x01
-#define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER    0x02
-#define PCI_SUB_CLASS_IPI_BUS_CONTROLLER        0x03
-#define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER     0x80
-
-/* NETWORK CONTROLLER */
-#define PCI_SUB_CLASS_ETHERNET_CONTROLLER       0x00
-#define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER     0x01
-#define PCI_SUB_CLASS_FDDI_CONTROLLER           0x02
-#define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER  0x80
-
-/* DISPLAY CONTROLLER */
-#define PCI_SUB_CLASS_VGA_CONTROLLER            0x00
-#define PCI_SUB_CLASS_XGA_CONTROLLER            0x01
-#define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER  0x80
-
-/* MULTIMEDIA CONTROLLER */
-#define PCI_SUB_CLASS_VIDEO_DEVICE              0x00
-#define PCI_SUB_CLASS_AUDIO_DEVICE              0x01
-#define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE   0x80
-
-/* MEMORY CONTROLLER */
-#define PCI_SUB_CLASS_RAM_CONTROLLER            0x00
-#define PCI_SUB_CLASS_FLASH_CONTROLLER          0x01
-#define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER   0x80
-
-/* BRIDGE CONTROLLER */
-#define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER    0x00
-#define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER     0x01
-#define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER    0x02
-#define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER      0x03
-#define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER    0x04
-#define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER  0x05
-#define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER   0x80
-
 #define PCI_MAX_SLOT            0x1F
 #define PCI_MAX_BUS             0xFF
 #define PCI_IOADDRESS_MASK      0xFFFE
@@ -3744,25 +3571,6 @@ typedef Scsi_Cmnd            REQ, *REQP;
 #define ASC_PCI_DEVICE_ID_2500  0x2500  /* ASC-38C0800 */
 #define ASC_PCI_DEVICE_ID_2700  0x2700  /* ASC-38C1600 */
 
-/* PCI IO Port Addresses to generate special cycle */
-
-#define PCI_CONFIG_ADDRESS_MECH1          0x0CF8
-#define PCI_CONFIG_DATA_MECH1             0x0CFC
-
-#define PCI_CONFIG_FORWARD_REGISTER       0x0CFA    /* 0=type 0; 1=type 1; */
-
-#define PCI_CONFIG_BUS_NUMBER_MASK        0x00FF0000
-#define PCI_CONFIG_DEVICE_FUNCTION_MASK   0x0000FF00
-#define PCI_CONFIG_REGISTER_NUMBER_MASK   0x000000F8
-
-#define PCI_DEVICE_FOUND                0x0000
-#define PCI_DEVICE_NOT_FOUND            0xffff
-
-#define SUBCLASS_OFFSET         0x0A
-#define CLASSCODE_OFFSET        0x0B
-#define VENDORID_OFFSET         0x00
-#define DEVICEID_OFFSET         0x02
-
 #ifndef ADVANSYS_STATS
 #define ASC_STATS(shp, counter)
 #define ASC_STATS_ADD(shp, counter, count)
@@ -4145,19 +3953,6 @@ typedef struct _PCI_CONFIG_SPACE_
 
 /* Note: All driver global data should be initialized. */
 
-#if ASC_LINUX_KERNEL22
-#ifdef CONFIG_PROC_FS
-struct proc_dir_entry proc_scsi_advansys =
-{
-    PROC_SCSI_ADVANSYS,              /* unsigned short low_ino */
-    8,                               /* unsigned short namelen */
-    "advansys",                      /* const char *name */
-    S_IFDIR | S_IRUGO | S_IXUGO,     /* mode_t mode */
-    2                                /* nlink_t nlink */
-};
-#endif /* CONFIG_PROC_FS */
-#endif /* ASC_LINUX_KERNEL22 */
-
 /* Number of boards detected in system. */
 STATIC int asc_board_count = 0;
 STATIC struct Scsi_Host    *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
@@ -4172,7 +3967,7 @@ STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } };
 STATIC ASC_SG_HEAD asc_sg_head = { 0 };
 
 /* List of supported bus types. */
-STATIC ushort asc_bus[ASC_NUM_BUS] ASC_INITDATA = {
+STATIC ushort asc_bus[ASC_NUM_BUS] __initdata = {
     ASC_IS_ISA,
     ASC_IS_VL,
     ASC_IS_EISA,
@@ -4210,11 +4005,11 @@ STATIC PortAddr     _asc_def_iop_base[];
 
 STATIC irqreturn_t advansys_interrupt(int, void *, struct pt_regs *);
 STATIC int       advansys_slave_configure(Scsi_Device *);
-STATIC void       asc_scsi_done_list(Scsi_Cmnd *, int from_isr);
+STATIC void       asc_scsi_done_list(Scsi_Cmnd *);
 STATIC int        asc_execute_scsi_cmnd(Scsi_Cmnd *);
 STATIC int        asc_build_req(asc_board_t *, Scsi_Cmnd *);
 STATIC int        adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **);
-STATIC int        adv_get_sglist(asc_board_t *, adv_req_t *, Scsi_Cmnd *);
+STATIC int        adv_get_sglist(asc_board_t *, adv_req_t *, Scsi_Cmnd *, int);
 STATIC void       asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
 STATIC void       adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
 STATIC void       adv_async_callback(ADV_DVC_VAR *, uchar);
@@ -4505,10 +4300,8 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
  * it must not call SCSI mid-level functions including scsi_malloc()
  * and scsi_free().
  */
-ASC_INITFUNC(
-int,
+int __init
 advansys_detect(Scsi_Host_Template *tpnt)
-)
 {
     static int          detect_called = ASC_FALSE;
     int                 iop;
@@ -4526,6 +4319,7 @@ advansys_detect(Scsi_Host_Template *tpnt)
     struct pci_dev      *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
     int                 pci_card_cnt_max = 0;
     int                 pci_card_cnt = 0;
+    struct device      *dev = NULL;
     struct pci_dev      *pci_devp = NULL;
     int                 pci_device_id_cnt = 0;
     unsigned int        pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
@@ -4550,12 +4344,6 @@ advansys_detect(Scsi_Host_Template *tpnt)
 
     ASC_DBG(1, "advansys_detect: begin\n");
 
-#if ASC_LINUX_KERNEL24
-    tpnt->proc_name = "advansys";
-#elif ASC_LINUX_KERNEL22
-    tpnt->proc_dir = &proc_scsi_advansys;
-#endif
-
     asc_board_count = 0;
 
     /*
@@ -4681,13 +4469,9 @@ advansys_detect(Scsi_Host_Template *tpnt)
                             NULL) {
                             pci_device_id_cnt++;
                         } else {
-#if ASC_LINUX_KERNEL24
                             if (pci_enable_device(pci_devp) == 0) {
                                 pci_devicep[pci_card_cnt_max++] = pci_devp;
                             }
-#elif ASC_LINUX_KERNEL22
-                            pci_devicep[pci_card_cnt_max++] = pci_devp;
-#endif
                         }
                     }
 
@@ -4724,17 +4508,16 @@ advansys_detect(Scsi_Host_Template *tpnt)
                     ASC_DBG2(2,
                         "advansys_detect: devfn %d, bus number %d\n",
                         pci_devp->devfn, pci_devp->bus->number);
-#if ASC_LINUX_KERNEL24
                     iop = pci_resource_start(pci_devp, 0);
-#elif ASC_LINUX_KERNEL22
-                    iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK;
-#endif
                     ASC_DBG2(1,
                         "advansys_detect: vendorID %X, deviceID %X\n",
                         pci_devp->vendor, pci_devp->device);
                     ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
                         iop, pci_devp->irq);
                 }
+               if(pci_devp)
+                   dev = &pci_devp->dev;
+
 #endif /* CONFIG_PCI */
                 break;
 
@@ -4765,7 +4548,7 @@ advansys_detect(Scsi_Host_Template *tpnt)
                 continue;
             }
 
-           scsi_set_device(shp, &pci_devp->dev);
+           scsi_set_device(shp, dev);
 
             /* Save a pointer to the Scsi_Host of each board found. */
             asc_host[asc_board_count++] = shp;
@@ -4849,11 +4632,7 @@ advansys_detect(Scsi_Host_Template *tpnt)
                     iolen = ADV_38C1600_IOLEN;
                 }
 #ifdef CONFIG_PCI
-#if ASC_LINUX_KERNEL24
                 pci_memory_address = pci_resource_start(pci_devp, 1);
-#elif ASC_LINUX_KERNEL22
-                pci_memory_address = pci_devp->base_address[1];
-#endif
                 ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n",
                     (ulong) pci_memory_address);
                 if ((boardp->ioremap_addr =
@@ -4904,7 +4683,8 @@ advansys_detect(Scsi_Host_Template *tpnt)
 #endif /* CONFIG_PROC_FS */
 
             if (ASC_NARROW_BOARD(boardp)) {
-                /*
+               asc_dvc_varp->cfg->dev = dev;
+               /*
                  * Set the board bus type and PCI IRQ before
                  * calling AscInitGetConfig().
                  */
@@ -4926,7 +4706,6 @@ advansys_detect(Scsi_Host_Template *tpnt)
 #ifdef CONFIG_PCI
                 case ASC_IS_PCI:
                     shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
-                    asc_dvc_varp->cfg->pci_dev = pci_devp;
                     asc_dvc_varp->cfg->pci_slot_info =
                         ASC_PCI_MKID(pci_devp->bus->number,
                             PCI_SLOT(pci_devp->devfn),
@@ -4944,13 +4723,13 @@ advansys_detect(Scsi_Host_Template *tpnt)
                     break;
                 }
             } else {
+                adv_dvc_varp->cfg->dev = dev;
                 /*
                  * For Wide boards set PCI information before calling
                  * AdvInitGetConfig().
                  */
 #ifdef CONFIG_PCI
                 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
-                adv_dvc_varp->cfg->pci_dev = pci_devp;
                 adv_dvc_varp->cfg->pci_slot_info =
                     ASC_PCI_MKID(pci_devp->bus->number,
                         PCI_SLOT(pci_devp->devfn),
@@ -5321,11 +5100,7 @@ advansys_detect(Scsi_Host_Template *tpnt)
 
             /* BIOS start address. */
             if (ASC_NARROW_BOARD(boardp)) {
-#if ASC_LINUX_KERNEL24
                 shp->base =
-#elif ASC_LINUX_KERNEL22
-                shp->base = (char *)
-#endif
                         ((ulong) AscGetChipBiosAddress(
                             asc_dvc_varp->iop_base,
                             asc_dvc_varp->bus_type));
@@ -5360,11 +5135,7 @@ advansys_detect(Scsi_Host_Template *tpnt)
                      * Convert x86 realmode code segment to a linear
                      * address by shifting left 4.
                      */
-                    shp->base =
-#if ASC_LINUX_KERNEL22
-                        (char *)
-#endif
-                        ((ulong) boardp->bios_codeseg << 4);
+                    shp->base = ((ulong) boardp->bios_codeseg << 4);
                 } else {
                     shp->base = 0;
                 }
@@ -5385,7 +5156,6 @@ advansys_detect(Scsi_Host_Template *tpnt)
             ASC_DBG2(2,
                 "advansys_detect: request_region port 0x%lx, len 0x%x\n",
                 (ulong) shp->io_port, boardp->asc_n_io_port);
-#if ASC_LINUX_KERNEL24
             if (request_region(shp->io_port, boardp->asc_n_io_port,
                                "advansys") == NULL) {
                 ASC_PRINT3(
@@ -5398,9 +5168,6 @@ advansys_detect(Scsi_Host_Template *tpnt)
                 asc_board_count--;
                 continue;
             }
-#elif ASC_LINUX_KERNEL22
-            request_region(shp->io_port, boardp->asc_n_io_port, "advansys");
-#endif
 
             /* Register DMA Channel for Narrow boards. */
             shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
@@ -5880,7 +5647,7 @@ advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
     default:
         done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
         /* Interrupts could be enabled here. */
-        asc_scsi_done_list(done_scp, 0);
+        asc_scsi_done_list(done_scp);
         break;
     }
     spin_unlock_irqrestore(&boardp->lock, flags);
@@ -6063,7 +5830,7 @@ advansys_reset(Scsi_Cmnd *scp)
      * Complete all the 'done_scp' requests.
      */
     if (done_scp != NULL) {
-        asc_scsi_done_list(done_scp, 0);
+        asc_scsi_done_list(done_scp);
     }
 
     ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
@@ -6149,10 +5916,8 @@ advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
  * ints[2] - second argument
  * ...
  */
-ASC_INITFUNC(
-void,
+void __init
 advansys_setup(char *str, int *ints)
-)
 {
     int    i;
 
@@ -6328,7 +6093,7 @@ advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
      * Complete all requests on the done list.
      */
 
-    asc_scsi_done_list(done_scp, 1);
+    asc_scsi_done_list(done_scp);
 
     ASC_DBG(1, "advansys_interrupt: end\n");
     return IRQ_HANDLED;
@@ -6374,23 +6139,38 @@ advansys_slave_configure(Scsi_Device *device)
  * Interrupts can be enabled on entry.
  */
 STATIC void
-asc_scsi_done_list(Scsi_Cmnd *scp, int from_isr)
+asc_scsi_done_list(Scsi_Cmnd *scp)
 {
     Scsi_Cmnd    *tscp;
-    ulong        flags = 0;
 
     ASC_DBG(2, "asc_scsi_done_list: begin\n");
     while (scp != NULL) {
+       asc_board_t *boardp;
+       struct device *dev;
+
         ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
         tscp = REQPNEXT(scp);
         scp->host_scribble = NULL;
+
+       boardp = ASC_BOARDP(scp->device->host);
+
+       if (ASC_NARROW_BOARD(boardp))
+           dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
+       else
+           dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
+
+       if (scp->use_sg)
+           dma_unmap_sg(dev, (struct scatterlist *)scp->request_buffer,
+                        scp->use_sg, scp->sc_data_direction);
+       else if (scp->request_bufflen)
+           dma_unmap_single(dev, scp->SCp.dma_handle,
+                            scp->request_bufflen, scp->sc_data_direction);
+
         ASC_STATS(scp->device->host, done);
         ASC_ASSERT(scp->scsi_done != NULL);
-       if (from_isr)
-           spin_lock_irqsave(scp->device->host->host_lock, flags);
+
         scp->scsi_done(scp);
-       if (from_isr)
-           spin_unlock_irqrestore(scp->device->host->host_lock, flags);
+
         scp = tscp;
     }
     ASC_DBG(2, "asc_scsi_done_list: done\n");
@@ -6619,6 +6399,8 @@ asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
 STATIC int
 asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
 {
+    struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
+
     /*
      * Mutually exclusive access is required to 'asc_scsi_q' and
      * 'asc_sg_head' until after the request is started.
@@ -6665,9 +6447,9 @@ asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
      */
     if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
         (boardp->reqcnt[scp->device->id] % 255) == 0) {
-        asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
+        asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
     } else {
-        asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE;
+        asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
     }
 
     /*
@@ -6679,8 +6461,10 @@ asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
          * CDB request of single contiguous buffer.
          */
         ASC_STATS(scp->device->host, cont_cnt);
-        asc_scsi_q.q1.data_addr =
-            cpu_to_le32(virt_to_bus(scp->request_buffer));
+       scp->SCp.dma_handle = scp->request_bufflen ?
+           dma_map_single(dev, scp->request_buffer,
+                          scp->request_bufflen, scp->sc_data_direction) : 0;
+       asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
         asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
         ASC_STATS_ADD(scp->device->host, cont_xfer,
                       ASC_CEILING(scp->request_bufflen, 512));
@@ -6691,12 +6475,17 @@ asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
          * CDB scatter-gather request list.
          */
         int                     sgcnt;
+       int                     use_sg;
         struct scatterlist      *slp;
 
-        if (scp->use_sg > scp->device->host->sg_tablesize) {
+       slp = (struct scatterlist *)scp->request_buffer;
+       use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
+
+       if (use_sg > scp->device->host->sg_tablesize) {
             ASC_PRINT3(
 "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
-                boardp->id, scp->use_sg, scp->device->host->sg_tablesize);
+               boardp->id, use_sg, scp->device->host->sg_tablesize);
+           dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
             scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
             return ASC_ERROR;
@@ -6715,19 +6504,16 @@ asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
         asc_scsi_q.q1.data_cnt = 0;
         asc_scsi_q.q1.data_addr = 0;
         /* This is a byte value, otherwise it would need to be swapped. */
-        asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
+       asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
         ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt);
 
         /*
          * Convert scatter-gather list into ASC_SG_HEAD list.
          */
-        slp = (struct scatterlist *) scp->request_buffer;
-        for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
-            asc_sg_head.sg_list[sgcnt].addr =
-                cpu_to_le32(virt_to_bus(
-               (unsigned char *)page_address(slp->page) + slp->offset));
-            asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(slp->length);
-            ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512));
+       for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
+           asc_sg_head.sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(slp));
+           asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(slp));
+           ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
         }
     }
 
@@ -6755,6 +6541,7 @@ adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
     ADV_SCSI_REQ_Q      *scsiqp;
     int                 i;
     int                 ret;
+    struct device      *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
 
     /*
      * Allocate an adv_req_t structure from the board to execute
@@ -6827,15 +6614,23 @@ adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
      * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
      * buffer command.
      */
-    scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
-    scsiqp->vdata_addr = scp->request_buffer;
-    scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
 
     if (scp->use_sg == 0) {
         /*
          * CDB request of single contiguous buffer.
          */
         reqp->sgblkp = NULL;
+       scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
+       if (scp->request_bufflen) {
+           scsiqp->vdata_addr = scp->request_buffer;
+           scp->SCp.dma_handle =
+               dma_map_single(dev, scp->request_buffer,
+                              scp->request_bufflen, scp->sc_data_direction);
+       } else {
+           scsiqp->vdata_addr = 0;
+           scp->SCp.dma_handle = 0;
+       }
+       scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
         scsiqp->sg_list_ptr = NULL;
         scsiqp->sg_real_addr = 0;
         ASC_STATS(scp->device->host, cont_cnt);
@@ -6845,10 +6640,21 @@ adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
         /*
          * CDB scatter-gather request list.
          */
-        if (scp->use_sg > ADV_MAX_SG_LIST) {
+       struct scatterlist *slp;
+       int use_sg;
+
+       scsiqp->data_cnt = 0;
+       scsiqp->vdata_addr = 0;
+       scsiqp->data_addr = 0;
+
+       slp = (struct scatterlist *)scp->request_buffer;
+       use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
+
+       if (use_sg > ADV_MAX_SG_LIST) {
             ASC_PRINT3(
 "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
-                boardp->id, scp->use_sg, scp->device->host->sg_tablesize);
+               boardp->id, use_sg, scp->device->host->sg_tablesize);
+           dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
             scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
 
@@ -6862,7 +6668,7 @@ adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
             return ASC_ERROR;
         }
 
-        if ((ret = adv_get_sglist(boardp, reqp, scp)) != ADV_SUCCESS) {
+       if ((ret = adv_get_sglist(boardp, reqp, scp, use_sg)) != ADV_SUCCESS) {
             /*
              * Free the adv_req_t structure by adding it back to the
              * board free list.
@@ -6874,7 +6680,7 @@ adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
         }
 
         ASC_STATS(scp->device->host, sg_cnt);
-        ASC_STATS_ADD(scp->device->host, sg_elem, scp->use_sg);
+       ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
     }
 
     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
@@ -6898,7 +6704,7 @@ adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
  *      ADV_ERROR(-1) - SG List creation failed
  */
 STATIC int
-adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp)
+adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp, int use_sg)
 {
     adv_sgblk_t         *sgblkp;
     ADV_SCSI_REQ_Q      *scsiqp;
@@ -6910,7 +6716,7 @@ adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp)
 
     scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
     slp = (struct scatterlist *) scp->request_buffer;
-    sg_elem_cnt = scp->use_sg;
+    sg_elem_cnt = use_sg;
     prev_sg_block = NULL;
     reqp->sgblkp = NULL;
 
@@ -6982,11 +6788,9 @@ adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp)
 
         for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
         {
-            sg_block->sg_list[i].sg_addr =
-                cpu_to_le32(virt_to_bus(
-                   (unsigned char *)page_address(slp->page) + slp->offset));
-            sg_block->sg_list[i].sg_count = cpu_to_le32(slp->length);
-            ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512));
+           sg_block->sg_list[i].sg_addr = cpu_to_le32(sg_dma_address(slp));
+           sg_block->sg_list[i].sg_count = cpu_to_le32(sg_dma_len(slp));
+           ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
 
             if (--sg_elem_cnt == 0)
             {   /* Last ADV_SG_BLOCK and scatter-gather entry. */
@@ -7079,14 +6883,13 @@ asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
          * If an INQUIRY command completed successfully, then call
          * the AscInquiryHandling() function to set-up the device.
          */
-        if (scp->cmnd[0] == SCSICMD_Inquiry && scp->device->lun == 0 &&
+        if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
             (scp->request_bufflen - qdonep->remain_bytes) >= 8)
         {
             AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
                 (ASC_SCSI_INQUIRY *) scp->request_buffer);
         }
 
-#if ASC_LINUX_KERNEL24
         /*
          * Check for an underrun condition.
          *
@@ -7099,15 +6902,14 @@ asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
             (unsigned) qdonep->remain_bytes);
             scp->resid = qdonep->remain_bytes;
         }
-#endif
         break;
 
     case QD_WITH_ERROR:
         ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
         switch (qdonep->d3.host_stat) {
         case QHSTA_NO_ERROR:
-            if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
-                ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
+            if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
+                ASC_DBG(2, "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
                     sizeof(scp->sense_buffer));
                 /*
@@ -7185,9 +6987,7 @@ adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
     Scsi_Cmnd           *scp;
     struct Scsi_Host    *shp;
     int                 i;
-#if ASC_LINUX_KERNEL24
     ADV_DCNT            resid_cnt;
-#endif
 
 
     ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
@@ -7270,7 +7070,6 @@ adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
         ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
         scp->result = 0;
 
-#if ASC_LINUX_KERNEL24
         /*
          * Check for an underrun condition.
          *
@@ -7284,15 +7083,14 @@ adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
                 (ulong) resid_cnt);
             scp->resid = resid_cnt;
         }
-#endif
         break;
 
     case QD_WITH_ERROR:
         ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
         switch (scsiqp->host_status) {
         case QHSTA_NO_ERROR:
-            if (scsiqp->scsi_status == SS_CHK_CONDITION) {
-                ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
+            if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
+                ASC_DBG(2, "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
                     sizeof(scp->sense_buffer));
                 /*
@@ -8858,7 +8656,7 @@ asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
             (unsigned) offset, (unsigned) advoffset, cplen);
     if (offset <= advoffset) {
         /* Read offset below current offset, copy everything. */
-        cnt = ASC_MIN(cplen, leftlen);
+        cnt = min(cplen, leftlen);
         ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
                 (ulong) curbuf, (ulong) cp, cnt);
         memcpy(curbuf, cp, cnt);
@@ -8866,7 +8664,7 @@ asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
         /* Read offset within current range, partial copy. */
         cnt = (advoffset + cplen) - offset;
         cp = (cp + cplen) - cnt;
-        cnt = ASC_MIN(cnt, leftlen);
+        cnt = min(cnt, leftlen);
         ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
                 (ulong) curbuf, (ulong) cp, cnt);
         memcpy(curbuf, cp, cnt);
@@ -8899,7 +8697,7 @@ asc_prt_line(char *buf, int buflen, char *fmt, ...)
         (void) printk(s);
         ret = 0;
     } else {
-        ret = ASC_MIN(buflen, ret);
+        ret = min(buflen, ret);
         memcpy(buf, s, ret);
     }
     va_end(args);
@@ -9002,16 +8800,14 @@ DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
 /*
  * Read a PCI configuration byte.
  */
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 DvcReadPCIConfigByte(
         ASC_DVC_VAR *asc_dvc,
         ushort offset)
-)
 {
 #ifdef CONFIG_PCI
     uchar byte_data;
-    pci_read_config_byte(asc_dvc->cfg->pci_dev, offset, &byte_data);
+    pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
     return byte_data;
 #else /* !defined(CONFIG_PCI) */
     return 0;
@@ -9021,16 +8817,14 @@ DvcReadPCIConfigByte(
 /*
  * Write a PCI configuration byte.
  */
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
 DvcWritePCIConfigByte(
         ASC_DVC_VAR *asc_dvc,
         ushort offset,
         uchar  byte_data)
-)
 {
 #ifdef CONFIG_PCI
-    pci_write_config_byte(asc_dvc->cfg->pci_dev, offset, byte_data);
+    pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
 #endif /* CONFIG_PCI */
 }
 
@@ -9038,13 +8832,10 @@ DvcWritePCIConfigByte(
  * Return the BIOS address of the adapter at the specified
  * I/O port and with the specified bus type.
  */
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscGetChipBiosAddress(
         PortAddr iop_base,
-        ushort bus_type
-)
-)
+        ushort bus_type)
 {
     ushort  cfg_lsw;
     ushort  bios_addr;
@@ -9119,16 +8910,14 @@ DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
 /*
  * Read a PCI configuration byte.
  */
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 DvcAdvReadPCIConfigByte(
         ADV_DVC_VAR *asc_dvc,
         ushort offset)
-)
 {
 #ifdef CONFIG_PCI
     uchar byte_data;
-    pci_read_config_byte(asc_dvc->cfg->pci_dev, offset, &byte_data);
+    pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
     return byte_data;
 #else /* CONFIG_PCI */
     return 0;
@@ -9138,16 +8927,14 @@ DvcAdvReadPCIConfigByte(
 /*
  * Write a PCI configuration byte.
  */
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
 DvcAdvWritePCIConfigByte(
         ADV_DVC_VAR *asc_dvc,
         ushort offset,
         uchar  byte_data)
-)
 {
 #ifdef CONFIG_PCI
-    pci_write_config_byte(asc_dvc->cfg->pci_dev, offset, byte_data);
+    pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
 #else /* CONFIG_PCI */
     return 0;
 #endif /* CONFIG_PCI */
@@ -9358,16 +9145,6 @@ asc_prt_scsi_host(struct Scsi_Host *s)
         s->host_busy, s->host_no,
         (unsigned) s->last_reset);
 
-#if ASC_LINUX_KERNEL24
-    printk(
-" hostt 0x%lx\n",
-        (ulong) s->hostt);
-#elif ASC_LINUX_KERNEL22
-    printk(
-" host_queue 0x%lx, hostt 0x%lx, block 0x%lx,\n",
-        (ulong) s->host_queue, (ulong) s->hostt, (ulong) s->block);
-#endif
-
     printk(
 " base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
         (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq);
@@ -9404,11 +9181,9 @@ asc_prt_scsi_cmnd(Scsi_Cmnd *s)
 
     asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
 
-#if ASC_LINUX_KERNEL24
     printk (
 "sc_data_direction %u, resid %d\n",
         s->sc_data_direction, s->resid);
-#endif
 
     printk(
 " use_sg %u, sglist_len %u, abort_reason 0x%x\n",
@@ -9423,15 +9198,9 @@ asc_prt_scsi_cmnd(Scsi_Cmnd *s)
 " timeout_per_command %d, timeout_total %d, timeout %d\n",
         s->timeout_per_command, s->timeout_total, s->timeout);
 
-#if ASC_LINUX_KERNEL24
     printk(
 " internal_timeout %u, flags %u\n",
         s->internal_timeout, s->flags);
-#elif ASC_LINUX_KERNEL22
-    printk(
-" internal_timeout %u, flags %u, this_count %d\n",
-        s->internal_timeout, s->flags,s->this_count);
-#endif
 
     printk(
 " scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
@@ -9507,7 +9276,8 @@ asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
 
     printk(
 " pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
-          h->pci_dev->device, h->lib_serial_no, h->lib_version, h->mcode_date);
+          to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
+          h->mcode_date);
 
     printk(
 " mcode_version %d, overrun_buf 0x%lx\n",
@@ -9632,7 +9402,7 @@ asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
 
     printk(
 "  mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
-       h->mcode_version, h->pci_dev->device, h->lib_version);
+       h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
 
     printk(
 "  control_flag 0x%x, pci_slot_info 0x%x\n",
@@ -9787,12 +9557,9 @@ asc_prt_hex(char *f, uchar *s, int l)
  * --- Asc Library Functions
  */
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscGetEisaChipCfg(
-                     PortAddr iop_base
-)
-)
+                     PortAddr iop_base)
 {
     PortAddr            eisa_cfg_iop;
 
@@ -9801,13 +9568,11 @@ AscGetEisaChipCfg(
     return (inpw(eisa_cfg_iop));
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscSetChipScsiID(
                     PortAddr iop_base,
                     uchar new_host_id
 )
-)
 {
     ushort              cfg_lsw;
 
@@ -9821,12 +9586,9 @@ AscSetChipScsiID(
     return (AscGetChipScsiID(iop_base));
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscGetChipScsiCtrl(
-                      PortAddr iop_base
-)
-)
+               PortAddr iop_base)
 {
     uchar               sc;
 
@@ -9836,13 +9598,11 @@ AscGetChipScsiCtrl(
     return (sc);
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscGetChipVersion(
                      PortAddr iop_base,
                      ushort bus_type
 )
-)
 {
     if ((bus_type & ASC_IS_EISA) != 0) {
         PortAddr            eisa_iop;
@@ -9855,12 +9615,9 @@ AscGetChipVersion(
     return (AscGetChipVerNo(iop_base));
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscGetChipBusType(
-                     PortAddr iop_base
-)
-)
+                     PortAddr iop_base)
 {
     ushort              chip_ver;
 
@@ -9940,22 +9697,19 @@ AscFindSignature(
     return (0);
 }
 
-STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
+STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata =
 {
     0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
     ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
 };
 
 #ifdef CONFIG_ISA
-STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
+STATIC uchar _isa_pnp_inited __initdata = 0;
 
-ASC_INITFUNC(
-STATIC PortAddr,
+STATIC PortAddr __init
 AscSearchIOPortAddr(
                        PortAddr iop_beg,
-                       ushort bus_type
-)
-)
+                       ushort bus_type)
 {
     if (bus_type & ASC_IS_VL) {
         while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
@@ -9986,12 +9740,10 @@ AscSearchIOPortAddr(
     return (0);
 }
 
-ASC_INITFUNC(
-STATIC PortAddr,
+STATIC PortAddr __init
 AscSearchIOPortAddr11(
                          PortAddr s_addr
 )
-)
 {
     int                 i;
     PortAddr            iop_base;
@@ -10017,11 +9769,8 @@ AscSearchIOPortAddr11(
     return (0);
 }
 
-ASC_INITFUNC(
-STATIC void,
-AscSetISAPNPWaitForKey(
-    void)
-)
+STATIC void __init
+AscSetISAPNPWaitForKey(void)
 {
     outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
     outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
@@ -10029,25 +9778,20 @@ AscSetISAPNPWaitForKey(
 }
 #endif /* CONFIG_ISA */
 
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
 AscToggleIRQAct(
                    PortAddr iop_base
 )
-)
 {
     AscSetChipStatus(iop_base, CIW_IRQ_ACT);
     AscSetChipStatus(iop_base, 0);
     return;
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscGetChipIRQ(
                  PortAddr iop_base,
-                 ushort bus_type
-)
-)
+                 ushort bus_type)
 {
     ushort              cfg_lsw;
     uchar               chip_irq;
@@ -10077,14 +9821,11 @@ AscGetChipIRQ(
     return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscSetChipIRQ(
                  PortAddr iop_base,
                  uchar irq_no,
-                 ushort bus_type
-)
-)
+                 ushort bus_type)
 {
     ushort              cfg_lsw;
 
@@ -10119,12 +9860,9 @@ AscSetChipIRQ(
 }
 
 #ifdef CONFIG_ISA
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
 AscEnableIsaDma(
-                   uchar dma_channel
-)
-)
+                   uchar dma_channel)
 {
     if (dma_channel < 4) {
         outp(0x000B, (ushort) (0xC0 | dma_channel));
@@ -10285,7 +10023,7 @@ AscIsrChipHalted(
             return (0);
         } else {
 
-            ext_msg.msg_type = M1_MSG_REJECT;
+            ext_msg.msg_type = MESSAGE_REJECT;
             AscMemWordCopyPtrToLram(iop_base,
                                  ASCV_MSGOUT_BEG,
                                  (uchar *) &ext_msg,
@@ -10385,7 +10123,7 @@ AscIsrChipHalted(
                              (ushort) ASCV_SCSIBUSY_B, scsi_busy);
             asc_dvc->queue_full_or_busy |= target_id;
 
-            if (scsi_status == SS_QUEUE_FULL) {
+            if (scsi_status == SAM_STAT_TASK_SET_FULL) {
                 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
                     cur_dvc_qng -= 1;
                     asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
@@ -10732,7 +10470,7 @@ AscIsrQDone(
             } else {
                 if ((AscReadLramByte(iop_base,
                           (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
-                     SCSICMD_StartStopUnit)) {
+                     START_STOP)) {
                     asc_dvc->unit_not_ready &= ~target_id;
                     if (scsiq->d3.done_stat != QD_NO_ERROR) {
                         asc_dvc->start_motor &= ~target_id;
@@ -11005,14 +10743,14 @@ STATIC ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
 STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
 {
-    SCSICMD_Inquiry,
-    SCSICMD_RequestSense,
-    SCSICMD_ReadCapacity,
-    SCSICMD_ReadTOC,
-    SCSICMD_ModeSelect6,
-    SCSICMD_ModeSense6,
-    SCSICMD_ModeSelect10,
-    SCSICMD_ModeSense10,
+    INQUIRY,
+    REQUEST_SENSE,
+    READ_CAPACITY,
+    READ_TOC,
+    MODE_SELECT,
+    MODE_SENSE,
+    MODE_SELECT_10,
+    MODE_SENSE_10,
     0xFF,
     0xFF,
     0xFF,
@@ -11065,7 +10803,7 @@ AscExeScsiQueue(
     target_ix = scsiq->q2.target_ix;
     tid_no = ASC_TIX_TO_TID(target_ix);
     n_q_required = 1;
-    if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
+    if (scsiq->cdbptr[0] == REQUEST_SENSE) {
         if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
             asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
@@ -11134,7 +10872,7 @@ AscExeScsiQueue(
         }
     }
     if (disable_syn_offset_one_fix) {
-        scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
+        scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
         scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
                                ASC_TAG_FLAG_DISABLE_DISCONNECT);
     } else {
@@ -11143,8 +10881,8 @@ AscExeScsiQueue(
     if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
         if (asc_dvc->bug_fix_cntl) {
             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
-                if ((scsi_cmd == SCSICMD_Read6) ||
-                    (scsi_cmd == SCSICMD_Read10)) {
+                if ((scsi_cmd == READ_6) ||
+                    (scsi_cmd == READ_10)) {
                     addr =
                         (ADV_PADDR) le32_to_cpu(
                             sg_head->sg_list[sg_entry_cnt_minus_one].addr) +
@@ -11193,8 +10931,8 @@ AscExeScsiQueue(
     } else {
         if (asc_dvc->bug_fix_cntl) {
             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
-                if ((scsi_cmd == SCSICMD_Read6) ||
-                    (scsi_cmd == SCSICMD_Read10)) {
+                if ((scsi_cmd == READ_6) ||
+                    (scsi_cmd == READ_10)) {
                     addr = le32_to_cpu(scsiq->q1.data_addr) +
                         le32_to_cpu(scsiq->q1.data_cnt);
                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
@@ -11365,7 +11103,7 @@ AscPutReadyQueue(
     }
     q_addr = ASC_QNO_TO_QADDR(q_no);
     if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
-        scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
+        scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG ;
     }
     scsiq->q1.status = QS_FREE;
     AscMemWordCopyPtrToLram(iop_base,
@@ -11862,12 +11600,9 @@ DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
 }
 
 #ifdef CONFIG_ISA
-ASC_INITFUNC(
-STATIC ASC_DCNT,
+STATIC ASC_DCNT __init
 AscGetEisaProductID(
-                       PortAddr iop_base
-)
-)
+                       PortAddr iop_base)
 {
     PortAddr            eisa_iop;
     ushort              product_id_high, product_id_low;
@@ -11881,12 +11616,9 @@ AscGetEisaProductID(
     return (product_id);
 }
 
-ASC_INITFUNC(
-STATIC PortAddr,
+STATIC PortAddr __init
 AscSearchIOPortAddrEISA(
-                           PortAddr iop_base
-)
-)
+                           PortAddr iop_base)
 {
     ASC_DCNT            eisa_product_id;
 
@@ -12080,12 +11812,9 @@ AscResetChipAndScsiBus(
     return (AscIsChipHalted(iop_base));
 }
 
-ASC_INITFUNC(
-STATIC ASC_DCNT,
+STATIC ASC_DCNT __init
 AscGetMaxDmaCount(
-                     ushort bus_type
-)
-)
+                     ushort bus_type)
 {
     if (bus_type & ASC_IS_ISA)
         return (ASC_MAX_ISA_DMA_COUNT);
@@ -12095,12 +11824,9 @@ AscGetMaxDmaCount(
 }
 
 #ifdef CONFIG_ISA
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscGetIsaDmaChannel(
-                       PortAddr iop_base
-)
-)
+                       PortAddr iop_base)
 {
     ushort              channel;
 
@@ -12112,13 +11838,10 @@ AscGetIsaDmaChannel(
     return (channel + 4);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscSetIsaDmaChannel(
                        PortAddr iop_base,
-                       ushort dma_channel
-)
-)
+                       ushort dma_channel)
 {
     ushort              cfg_lsw;
     uchar               value;
@@ -12136,13 +11859,10 @@ AscSetIsaDmaChannel(
     return (0);
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscSetIsaDmaSpeed(
                      PortAddr iop_base,
-                     uchar speed_value
-)
-)
+                     uchar speed_value)
 {
     speed_value &= 0x07;
     AscSetBank(iop_base, 1);
@@ -12151,12 +11871,10 @@ AscSetIsaDmaSpeed(
     return (AscGetIsaDmaSpeed(iop_base));
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscGetIsaDmaSpeed(
                      PortAddr iop_base
 )
-)
 {
     uchar               speed_value;
 
@@ -12168,12 +11886,10 @@ AscGetIsaDmaSpeed(
 }
 #endif /* CONFIG_ISA */
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscReadPCIConfigWord(
     ASC_DVC_VAR *asc_dvc,
     ushort pci_config_offset)
-)
 {
     uchar       lsb, msb;
 
@@ -12182,12 +11898,10 @@ AscReadPCIConfigWord(
     return ((ushort) ((msb << 8) | lsb));
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscInitGetConfig(
         ASC_DVC_VAR *asc_dvc
 )
-)
 {
     ushort              warn_code;
     PortAddr            iop_base;
@@ -12267,12 +11981,10 @@ AscInitGetConfig(
     return(warn_code);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscInitSetConfig(
                     ASC_DVC_VAR *asc_dvc
 )
-)
 {
     ushort              warn_code = 0;
 
@@ -12288,12 +12000,10 @@ AscInitSetConfig(
     return (warn_code);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscInitFromAscDvcVar(
                         ASC_DVC_VAR *asc_dvc
 )
-)
 {
     PortAddr            iop_base;
     ushort              cfg_msw;
@@ -12301,7 +12011,7 @@ AscInitFromAscDvcVar(
     ushort              pci_device_id;
 
     iop_base = asc_dvc->iop_base;
-    pci_device_id = asc_dvc->cfg->pci_dev->device;
+    pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
     warn_code = 0;
     cfg_msw = AscGetChipCfgMsw(iop_base);
     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
@@ -12393,12 +12103,9 @@ AscInitAsc1000Driver(
     return (warn_code);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscInitAscDvcVar(
-                    ASC_DVC_VAR *asc_dvc
-)
-)
+                    ASC_DVC_VAR *asc_dvc)
 {
     int                 i;
     PortAddr            iop_base;
@@ -12508,12 +12215,8 @@ AscInitAscDvcVar(
     return (warn_code);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
-AscInitFromEEP(
-                  ASC_DVC_VAR *asc_dvc
-)
-)
+STATIC ushort __init
+AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
 {
     ASCEEP_CONFIG       eep_config_buf;
     ASCEEP_CONFIG       *eep_config;
@@ -12729,12 +12432,9 @@ AscInitMicroCodeVar(
     return (warn_code);
 }
 
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AscTestExternalLram(
-                       ASC_DVC_VAR *asc_dvc
-)
-)
+                       ASC_DVC_VAR *asc_dvc)
 {
     PortAddr            iop_base;
     ushort              q_addr;
@@ -12756,13 +12456,11 @@ AscTestExternalLram(
     return (sta);
 }
 
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AscWriteEEPCmdReg(
                      PortAddr iop_base,
                      uchar cmd_reg
 )
-)
 {
     uchar               read_back;
     int                 retry;
@@ -12781,13 +12479,11 @@ AscWriteEEPCmdReg(
     }
 }
 
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AscWriteEEPDataReg(
                       PortAddr iop_base,
                       ushort data_reg
 )
-)
 {
     ushort              read_back;
     int                 retry;
@@ -12806,35 +12502,24 @@ AscWriteEEPDataReg(
     }
 }
 
-ASC_INITFUNC(
-STATIC void,
-AscWaitEEPRead(
-                  void
-)
-)
+STATIC void __init
+AscWaitEEPRead(void)
 {
     DvcSleepMilliSecond(1);
     return;
 }
 
-ASC_INITFUNC(
-STATIC void,
-AscWaitEEPWrite(
-                   void
-)
-)
+STATIC void __init
+AscWaitEEPWrite(void)
 {
     DvcSleepMilliSecond(20);
     return;
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscReadEEPWord(
                   PortAddr iop_base,
-                  uchar addr
-)
-)
+                  uchar addr)
 {
     ushort              read_wval;
     uchar               cmd_reg;
@@ -12849,14 +12534,11 @@ AscReadEEPWord(
     return (read_wval);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscWriteEEPWord(
                    PortAddr iop_base,
                    uchar addr,
-                   ushort word_val
-)
-)
+                   ushort word_val)
 {
     ushort              read_wval;
 
@@ -12876,13 +12558,10 @@ AscWriteEEPWord(
     return (read_wval);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscGetEEPConfig(
                    PortAddr iop_base,
-                   ASCEEP_CONFIG * cfg_buf, ushort bus_type
-)
-)
+                   ASCEEP_CONFIG * cfg_buf, ushort bus_type)
 {
     ushort              wval;
     ushort              sum;
@@ -12928,13 +12607,10 @@ AscGetEEPConfig(
     return (sum);
 }
 
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AscSetEEPConfigOnce(
                        PortAddr iop_base,
-                       ASCEEP_CONFIG * cfg_buf, ushort bus_type
-)
-)
+                       ASCEEP_CONFIG * cfg_buf, ushort bus_type)
 {
     int                 n_error;
     ushort              *wbuf;
@@ -13026,13 +12702,11 @@ AscSetEEPConfigOnce(
     return (n_error);
 }
 
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AscSetEEPConfig(
                    PortAddr iop_base,
                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
 )
-)
 {
     int            retry;
     int            n_error;
@@ -13066,17 +12740,17 @@ AscAsyncFix(
     {
         if (!(asc_dvc->init_sdtr & tid_bits))
         {
-            if ((dvc_type == SCSI_TYPE_CDROM) &&
+            if ((dvc_type == TYPE_ROM) &&
                 (AscCompareString((uchar *) inq->vendor_id,
                     (uchar *) "HP ", 3) == 0))
             {
                 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
             }
             asc_dvc->pci_fix_asyn_xfer |= tid_bits;
-            if ((dvc_type == SCSI_TYPE_PROC) ||
-                (dvc_type == SCSI_TYPE_SCANNER) ||
-                (dvc_type == SCSI_TYPE_CDROM) ||
-                (dvc_type == SCSI_TYPE_SASD))
+            if ((dvc_type == TYPE_PROCESSOR) ||
+                (dvc_type == TYPE_SCANNER) ||
+                (dvc_type == TYPE_ROM) ||
+                (dvc_type == TYPE_TAPE))
             {
                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
             }
@@ -14470,7 +14144,7 @@ STATIC ADV_DCNT _adv_asc38C1600_chksum =
  * unswapped on big-endian platforms.
  */
 STATIC ADVEEP_3550_CONFIG
-Default_3550_EEPROM_Config ASC_INITDATA = {
+Default_3550_EEPROM_Config __initdata = {
     ADV_EEPROM_BIOS_ENABLE,     /* cfg_lsw */
     0x0000,                     /* cfg_msw */
     0xFFFF,                     /* disc_enable */
@@ -14508,7 +14182,7 @@ Default_3550_EEPROM_Config ASC_INITDATA = {
 };
 
 STATIC ADVEEP_3550_CONFIG
-ADVEEP_3550_Config_Field_IsChar ASC_INITDATA = {
+ADVEEP_3550_Config_Field_IsChar __initdata = {
     0,                          /* cfg_lsw */
     0,                          /* cfg_msw */
     0,                          /* -disc_enable */
@@ -14546,7 +14220,7 @@ ADVEEP_3550_Config_Field_IsChar ASC_INITDATA = {
 };
 
 STATIC ADVEEP_38C0800_CONFIG
-Default_38C0800_EEPROM_Config ASC_INITDATA = {
+Default_38C0800_EEPROM_Config __initdata = {
     ADV_EEPROM_BIOS_ENABLE,     /* 00 cfg_lsw */
     0x0000,                     /* 01 cfg_msw */
     0xFFFF,                     /* 02 disc_enable */
@@ -14611,7 +14285,7 @@ Default_38C0800_EEPROM_Config ASC_INITDATA = {
 };
 
 STATIC ADVEEP_38C0800_CONFIG
-ADVEEP_38C0800_Config_Field_IsChar ASC_INITDATA = {
+ADVEEP_38C0800_Config_Field_IsChar __initdata = {
     0,                          /* 00 cfg_lsw */
     0,                          /* 01 cfg_msw */
     0,                          /* 02 disc_enable */
@@ -14676,7 +14350,7 @@ ADVEEP_38C0800_Config_Field_IsChar ASC_INITDATA = {
 };
 
 STATIC ADVEEP_38C1600_CONFIG
-Default_38C1600_EEPROM_Config ASC_INITDATA = {
+Default_38C1600_EEPROM_Config __initdata = {
     ADV_EEPROM_BIOS_ENABLE,     /* 00 cfg_lsw */
     0x0000,                     /* 01 cfg_msw */
     0xFFFF,                     /* 02 disc_enable */
@@ -14741,7 +14415,7 @@ Default_38C1600_EEPROM_Config ASC_INITDATA = {
 };
 
 STATIC ADVEEP_38C1600_CONFIG
-ADVEEP_38C1600_Config_Field_IsChar ASC_INITDATA = {
+ADVEEP_38C1600_Config_Field_IsChar __initdata = {
     0,                          /* 00 cfg_lsw */
     0,                          /* 01 cfg_msw */
     0,                          /* 02 disc_enable */
@@ -14813,10 +14487,8 @@ ADVEEP_38C1600_Config_Field_IsChar ASC_INITDATA = {
  * For a non-fatal error return a warning code. If there are no warnings
  * then 0 is returned.
  */
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
-)
 {
     ushort      warn_code;
     AdvPortAddr iop_base;
@@ -16800,10 +16472,8 @@ AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
  *
  * Note: Chip is stopped on entry.
  */
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
-)
 {
     AdvPortAddr         iop_base;
     ushort              warn_code;
@@ -16974,10 +16644,8 @@ AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
  *
  * Note: Chip is stopped on entry.
  */
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
-)
 {
     AdvPortAddr              iop_base;
     ushort                   warn_code;
@@ -17209,10 +16877,8 @@ AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
  *
  * Note: Chip is stopped on entry.
  */
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
-)
 {
     AdvPortAddr              iop_base;
     ushort                   warn_code;
@@ -17477,10 +17143,8 @@ AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
  *
  * Return a checksum based on the EEPROM configuration read.
  */
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
-)
 {
     ushort              wval, chksum;
     ushort              *wbuf;
@@ -17525,11 +17189,9 @@ AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
  *
  * Return a checksum based on the EEPROM configuration read.
  */
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
                        ADVEEP_38C0800_CONFIG *cfg_buf)
-)
 {
     ushort              wval, chksum;
     ushort              *wbuf;
@@ -17574,11 +17236,9 @@ AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
  *
  * Return a checksum based on the EEPROM configuration read.
  */
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
                        ADVEEP_38C1600_CONFIG *cfg_buf)
-)
 {
     ushort              wval, chksum;
     ushort              *wbuf;
@@ -17621,10 +17281,8 @@ AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
 /*
  * Read the EEPROM from specified location
  */
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
-)
 {
     AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
         ASC_EEP_CMD_READ | eep_word_addr);
@@ -17635,10 +17293,8 @@ AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
 /*
  * Wait for EEPROM command to complete
  */
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
 AdvWaitEEPCmd(AdvPortAddr iop_base)
-)
 {
     int eep_delay_ms;
 
@@ -18290,7 +17946,7 @@ AdvISR(ADV_DVC_VAR *asc_dvc)
          * the device, otherwise may erroneously set *_able bits.
          */
         if (scsiq->done_status == QD_NO_ERROR &&
-            scsiq->cdb[0] == SCSICMD_Inquiry &&
+            scsiq->cdb[0] == INQUIRY &&
             scsiq->target_lun == 0 &&
             (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
                 == ADV_INQ_RTN_STD_INQUIRY_DATA)
index 6e9d28f..66e3ffe 100644 (file)
 #include <scsi/scsicam.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "aha152x.h"
 
 
@@ -577,11 +577,11 @@ struct aha152x_scdata {
 #define MSGO(i)                        (HOSTDATA(shpnt)->msgo[i])
 #define MSGO_I                 (HOSTDATA(shpnt)->msgo_i)
 #define MSGOLEN                        (HOSTDATA(shpnt)->msgo_len)
-#define ADDMSGO(x)             (MSGOLEN<256 ? MSGO(MSGOLEN++)=x : aha152x_error(shpnt,"MSGO overflow"))
+#define ADDMSGO(x)             (MSGOLEN<256 ? (void)(MSGO(MSGOLEN++)=x) : aha152x_error(shpnt,"MSGO overflow"))
 
 #define MSGI(i)                        (HOSTDATA(shpnt)->msgi[i])
 #define MSGILEN                        (HOSTDATA(shpnt)->msgi_len)
-#define ADDMSGI(x)             (MSGILEN<256 ? MSGI(MSGILEN++)=x : aha152x_error(shpnt,"MSGI overflow"))
+#define ADDMSGI(x)             (MSGILEN<256 ? (void)(MSGI(MSGILEN++)=x) : aha152x_error(shpnt,"MSGI overflow"))
 
 #define DATA_LEN               (HOSTDATA(shpnt)->data_len)
 
index 055938f..e5e8696 100644 (file)
 #include <asm/ecard.h>
 
 #include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
 #include "acornscsi.h"
 #include "msgqueue.h"
 #include "scsi.h"
index 54de7f5..cd5a63c 100644 (file)
@@ -37,7 +37,7 @@
 #include <asm/ecard.h>
 
 #include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
 #include "fas216.h"
 
 struct arxescsi_info {
index aa75d50..6dad722 100644 (file)
@@ -17,7 +17,7 @@
 #include <asm/system.h>
 
 #include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
 
 #include <scsi/scsicam.h>
 
index 89ffb31..92bfdd9 100644 (file)
@@ -35,7 +35,7 @@
 #include <asm/pgtable.h>
 
 #include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
 #include "fas216.h"
 #include "scsi.h"
 
index 7f27e54..57e7961 100644 (file)
@@ -33,7 +33,7 @@
 #include <asm/system.h>
 
 #include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
 
 #define NCR5380_implementation_fields  int port, ctrl
 #define NCR5380_local_declare()                struct Scsi_Host *_instance
index de4819f..530b59c 100644 (file)
@@ -41,7 +41,7 @@
 #include <asm/pgtable.h>
 
 #include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
 #include "fas216.h"
 #include "scsi.h"
 
index 2630125..f54b470 100644 (file)
@@ -52,7 +52,7 @@
 #include <asm/ecard.h>
 
 #include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
 #include "fas216.h"
 #include "scsi.h"
 
index ccca39b..ecfee93 100644 (file)
@@ -17,7 +17,7 @@
 #include <asm/system.h>
 
 #include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
 
 #define AUTOSENSE
 /*#define PSEUDO_DMA*/
index e5dd354..d53b0c2 100644 (file)
@@ -26,7 +26,7 @@
 #include <asm/pgtable.h>
 
 #include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
 #include "fas216.h"
 #include "scsi.h"
 
index 3363c71..a6588b0 100644 (file)
@@ -424,16 +424,15 @@ static void piix_set_udmamode (struct ata_port *ap, struct ata_device *adev,
        int w_flag              = 0x10 << drive_dn;
        int u_speed             = 0;
        int                     sitre;
-       u16                     reg4042, reg44, reg48, reg4a, reg54;
-       u8                      reg55;
+       u16                     reg4042, reg4a;
+       u8                      reg48, reg54, reg55;
 
        pci_read_config_word(dev, maslave, &reg4042);
        DPRINTK("reg4042 = 0x%04x\n", reg4042);
        sitre = (reg4042 & 0x4000) ? 1 : 0;
-       pci_read_config_word(dev, 0x44, &reg44);
-       pci_read_config_word(dev, 0x48, &reg48);
+       pci_read_config_byte(dev, 0x48, &reg48);
        pci_read_config_word(dev, 0x4a, &reg4a);
-       pci_read_config_word(dev, 0x54, &reg54);
+       pci_read_config_byte(dev, 0x54, &reg54);
        pci_read_config_byte(dev, 0x55, &reg55);
 
        switch(speed) {
@@ -450,23 +449,19 @@ static void piix_set_udmamode (struct ata_port *ap, struct ata_device *adev,
        }
 
        if (!(reg48 & u_flag))
-               pci_write_config_word(dev, 0x48, reg48|u_flag);
+               pci_write_config_byte(dev, 0x48, reg48 | u_flag);
        if (speed == XFER_UDMA_5) {
                pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
        } else {
                pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
        }
-       if (!(reg4a & u_speed)) {
-               pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
-               pci_write_config_word(dev, 0x4a, reg4a|u_speed);
-       }
+       if ((reg4a & a_speed) != u_speed)
+               pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
        if (speed > XFER_UDMA_2) {
-               if (!(reg54 & v_flag)) {
-                       pci_write_config_word(dev, 0x54, reg54|v_flag);
-               }
-       } else {
-               pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
-       }
+               if (!(reg54 & v_flag))
+                       pci_write_config_byte(dev, 0x54, reg54 | v_flag);
+       } else
+               pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
 }
 
 /* move to PCI layer, integrate w/ MSI stuff */
index 508d84f..113838b 100644 (file)
@@ -154,7 +154,7 @@ static void print_opcode(int opcode) {
 }
 #endif  
 
-void print_command (unsigned char *command) {
+void __scsi_print_command (unsigned char *command) {
     int i,s;
     print_opcode(command[0]);
     for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) 
@@ -173,7 +173,7 @@ void print_command (unsigned char *command) {
  *     (e.g. "0x2" for Check Condition).
  **/
 void
-print_status(unsigned char scsi_status) {
+scsi_print_status(unsigned char scsi_status) {
 #if (CONSTANTS & CONST_STATUS)
        const char * ccp;
 
@@ -1014,12 +1014,12 @@ print_sense_internal(const char *devclass,
 #endif
 }
 
-void print_sense(const char *devclass, struct scsi_cmnd *cmd)
+void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd)
 {
        print_sense_internal(devclass, cmd->sense_buffer, cmd->request);
 }
 
-void print_req_sense(const char *devclass, struct scsi_request *sreq)
+void scsi_print_req_sense(const char *devclass, struct scsi_request *sreq)
 {
        print_sense_internal(devclass, sreq->sr_sense_buffer, sreq->sr_request);
 }
@@ -1051,7 +1051,7 @@ static const char *extended_msgs[] = {
 #define NO_EXTENDED_MSGS (sizeof(two_byte_msgs)  / sizeof (const char *))
 #endif /* (CONSTANTS & CONST_MSG) */
 
-int print_msg (const unsigned char *msg) {
+int scsi_print_msg (const unsigned char *msg) {
     int len = 0, i;
     if (msg[0] == EXTENDED_MESSAGE) {
        len = 3 + msg[1];
@@ -1124,13 +1124,13 @@ int print_msg (const unsigned char *msg) {
     return len;
 }
 
-void print_Scsi_Cmnd(struct scsi_cmnd *cmd) {
+void scsi_print_command(struct scsi_cmnd *cmd) {
     printk("scsi%d : destination target %d, lun %d\n", 
           cmd->device->host->host_no, 
           cmd->device->id, 
           cmd->device->lun);
     printk("        command = ");
-    print_command(cmd->cmnd);
+    __scsi_print_command(cmd->cmnd);
 }
 
 #if (CONSTANTS & CONST_HOST)
@@ -1139,7 +1139,7 @@ static const char * hostbyte_table[]={
 "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",
 "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", NULL};
 
-void print_hostbyte(int scsiresult)
+void scsi_print_hostbyte(int scsiresult)
 {   static int maxcode=0;
     int i;
    
@@ -1155,7 +1155,7 @@ void print_hostbyte(int scsiresult)
     printk("(%s) ",hostbyte_table[host_byte(scsiresult)]);
 }
 #else
-void print_hostbyte(int scsiresult)
+void scsi_print_hostbyte(int scsiresult)
 {   printk("Hostbyte=0x%02x ",host_byte(scsiresult));
 }
 #endif
@@ -1170,7 +1170,7 @@ static const char * driversuggest_table[]={"SUGGEST_OK",
 unknown,unknown,unknown, "SUGGEST_SENSE",NULL};
 
 
-void print_driverbyte(int scsiresult)
+void scsi_print_driverbyte(int scsiresult)
 {   static int driver_max=0,suggest_max=0;
     int i,dr=driver_byte(scsiresult)&DRIVER_MASK, 
        su=(driver_byte(scsiresult)&SUGGEST_MASK)>>4;
@@ -1187,7 +1187,7 @@ void print_driverbyte(int scsiresult)
        su<suggest_max ? driversuggest_table[su]:"invalid");
 }
 #else
-void print_driverbyte(int scsiresult)
+void scsi_print_driverbyte(int scsiresult)
 {   printk("Driverbyte=0x%02x ",driver_byte(scsiresult));
 }
 #endif
index 2bd4bc6..a69bd79 100644 (file)
@@ -607,6 +607,7 @@ static int PeekIMQEntry( PTACHYON fcChip, ULONG type)
         if( (fcChip->IMQ->QEntry[CI].type & 0x1FF) == 0x104 )
         { 
           TachFCHDR_GCMND* fchs;
+#error This is too much stack
           ULONG ulFibreFrame[2048/4];  // max DWORDS in incoming FC Frame
          USHORT SFQpi = (USHORT)(fcChip->IMQ->QEntry[CI].word[0] & 0x0fffL);
 
@@ -718,6 +719,7 @@ int CpqTsProcessIMQEntry(void *host)
   ULONG x_ID;
   ULONG ulBuff, dwStatus;
   TachFCHDR_GCMND* fchs;
+#error This is too much stack
   ULONG ulFibreFrame[2048/4];  // max number of DWORDS in incoming Fibre Frame
   UCHAR ucInboundMessageType;  // Inbound CM, dword 3 "type" field
 
index 76fd8b1..eeaf46a 100644 (file)
 #define DC390_H
 
 #include <linux/version.h>
-#ifndef KERNEL_VERSION
-# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
-#endif
 
 #define DC390_BANNER "Tekram DC390/AM53C974"
-#define DC390_VERSION "2.1b 2004-04-13"
+#define DC390_VERSION "2.1d 2004-05-27"
 
 /* We don't have eh_abort_handler, eh_device_reset_handler, 
  * eh_bus_reset_handler, eh_host_reset_handler yet! 
 # define NEW_EH use_new_eh_code: 1,
 # define USE_NEW_EH
 #endif
-
-static int DC390_detect(Scsi_Host_Template *psht);
-static int DC390_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
-static int DC390_abort(Scsi_Cmnd *cmd);
-static int DC390_reset(Scsi_Cmnd *cmd);
-static int DC390_bios_param(struct scsi_device *sdev, struct block_device *dev,
-               sector_t capacity, int geom[]);
-
-static int DC390_release(struct Scsi_Host *);
-
 #endif /* DC390_H */
index 5139b06..7229b2d 100644 (file)
@@ -68,8 +68,11 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
 #include <asm/pgtable.h>
 #include <asm/io.h>            /* for virt_to_bus, etc. */
 
-#include "scsi.h"
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
 
 #include "dpt/dptsig.h"
 #include "dpti.h"
@@ -86,9 +89,9 @@ static dpt_sig_S DPTI_sig = {
 #elif defined(__ia64__)
        PROC_INTEL, PROC_IA64,
 #elif defined(__sparc__)
-       PROC_ULTRASPARC,
+       PROC_ULTRASPARC, PROC_ULTRASPARC,
 #elif defined(__alpha__)
-       PROC_ALPHA ,
+       PROC_ALPHA, PROC_ALPHA,
 #else
        (-1),(-1),
 #endif
@@ -173,7 +176,7 @@ static struct pci_device_id dptids[] = {
 };
 MODULE_DEVICE_TABLE(pci,dptids);
 
-static int adpt_detect(Scsi_Host_Template* sht)
+static int adpt_detect(struct scsi_host_template* sht)
 {
        struct pci_dev *pDev = NULL;
        adpt_hba* pHba;
@@ -362,7 +365,7 @@ static void adpt_inquiry(adpt_hba* pHba)
 }
 
 
-static int adpt_slave_configure(Scsi_Device * device)
+static int adpt_slave_configure(struct scsi_device * device)
 {
        struct Scsi_Host *host = device->host;
        adpt_hba* pHba;
@@ -378,7 +381,7 @@ static int adpt_slave_configure(Scsi_Device * device)
        return 0;
 }
 
-static int adpt_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
 {
        adpt_hba* pHba = NULL;
        struct adpt_device* pDev = NULL;        /* dpt per device information */
@@ -643,7 +646,7 @@ stop_output:
  *===========================================================================
  */
 
-static int adpt_abort(Scsi_Cmnd * cmd)
+static int adpt_abort(struct scsi_cmnd * cmd)
 {
        adpt_hba* pHba = NULL;  /* host bus adapter structure */
        struct adpt_device* dptdevice;  /* dpt per device information */
@@ -683,7 +686,7 @@ static int adpt_abort(Scsi_Cmnd * cmd)
 // This is the same for BLK and SCSI devices
 // NOTE this is wrong in the i2o.h definitions
 // This is not currently supported by our adapter but we issue it anyway
-static int adpt_device_reset(Scsi_Cmnd* cmd)
+static int adpt_device_reset(struct scsi_cmnd* cmd)
 {
        adpt_hba* pHba;
        u32 msg[4];
@@ -723,7 +726,7 @@ static int adpt_device_reset(Scsi_Cmnd* cmd)
 
 #define I2O_HBA_BUS_RESET 0x87
 // This version of bus reset is called by the eh_error handler
-static int adpt_bus_reset(Scsi_Cmnd* cmd)
+static int adpt_bus_reset(struct scsi_cmnd* cmd)
 {
        adpt_hba* pHba;
        u32 msg[4];
@@ -745,7 +748,7 @@ static int adpt_bus_reset(Scsi_Cmnd* cmd)
 }
 
 // This version of reset is called by the eh_error_handler
-static int adpt_reset(Scsi_Cmnd* cmd)
+static int adpt_reset(struct scsi_cmnd* cmd)
 {
        adpt_hba* pHba;
        int rcode;
@@ -860,7 +863,7 @@ static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p)
 #endif
 
 
-static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) 
+static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) 
 {
 
        adpt_hba* pHba = NULL;
@@ -1997,7 +2000,7 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
 
 static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
 {
-       Scsi_Cmnd* cmd;
+       struct scsi_cmnd* cmd;
        adpt_hba* pHba = dev_id;
        u32 m;
        ulong reply;
@@ -2059,14 +2062,14 @@ static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
                                status = I2O_POST_WAIT_OK;
                        }
                        if(!(context & 0x40000000)) {
-                               cmd = (Scsi_Cmnd*) readl(reply+12); 
+                               cmd = (struct scsi_cmnd*) readl(reply+12); 
                                if(cmd != NULL) {
                                        printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
                                }
                        }
                        adpt_i2o_post_wait_complete(context, status);
                } else { // SCSI message
-                       cmd = (Scsi_Cmnd*) readl(reply+12); 
+                       cmd = (struct scsi_cmnd*) readl(reply+12); 
                        if(cmd != NULL){
                                if(cmd->serial_number != 0) { // If not timedout
                                        adpt_i2o_to_scsi(reply, cmd);
@@ -2083,7 +2086,7 @@ out:      if(pHba->host)
        return IRQ_RETVAL(handled);
 }
 
-static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* d)
+static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* d)
 {
        int i;
        u32 msg[MAX_MESSAGE_SIZE];
@@ -2108,16 +2111,16 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device*
                 * cmd->cmnd[0] is an unsigned char
                 */
                switch(cmd->sc_data_direction){
-               case SCSI_DATA_READ:
+               case DMA_FROM_DEVICE:
                        scsidir  =0x40000000;   // DATA IN  (iop<--dev)
                        break;
-               case SCSI_DATA_WRITE:
+               case DMA_TO_DEVICE:
                        direction=0x04000000;   // SGL OUT
                        scsidir  =0x80000000;   // DATA OUT (iop-->dev)
                        break;
-               case SCSI_DATA_NONE:
+               case DMA_NONE:
                        break;
-               case SCSI_DATA_UNKNOWN:
+               case DMA_BIDIRECTIONAL:
                        scsidir  =0x40000000;   // DATA IN  (iop<--dev)
                        // Assume In - and continue;
                        break;
@@ -2156,7 +2159,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device*
        if(cmd->use_sg) {
                struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
                int sg_count = pci_map_sg(pHba->pDev, sg, cmd->use_sg,
-                        scsi_to_pci_dma_dir(cmd->sc_data_direction));
+                               cmd->sc_data_direction);
 
 
                len = 0;
@@ -2184,7 +2187,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device*
                        *mptr++ = pci_map_single(pHba->pDev,
                                cmd->request_buffer,
                                cmd->request_bufflen,
-                               scsi_to_pci_dma_dir(cmd->sc_data_direction));
+                               cmd->sc_data_direction);
                }
        }
        
@@ -2200,7 +2203,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device*
 }
 
 
-static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht)
+static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
 {
        struct Scsi_Host *host = NULL;
 
@@ -2231,7 +2234,7 @@ static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht)
 }
 
 
-static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd)
+static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd)
 {
        adpt_hba* pHba;
        u32 hba_status;
@@ -2533,8 +2536,8 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
 
 static void adpt_fail_posted_scbs(adpt_hba* pHba)
 {
-       Scsi_Cmnd*      cmd = NULL;
-       Scsi_Device*    d = NULL;
+       struct scsi_cmnd*       cmd = NULL;
+       struct scsi_device*     d = NULL;
 
        shost_for_each_device(d, pHba->host) {
                unsigned long flags;
@@ -3358,7 +3361,7 @@ static static void adpt_delay(int millisec)
 
 #endif
 
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
        .name                   = "dpt_i2o",
        .proc_name              = "dpt_i2o",
        .proc_info              = adpt_proc_info,
index 7f3c028..c43673b 100644 (file)
  * SCSI interface function Prototypes
  */
 
-static int adpt_detect(Scsi_Host_Template * sht);
-static int adpt_queue(Scsi_Cmnd * cmd, void (*cmdcomplete) (Scsi_Cmnd *));
-static int adpt_abort(Scsi_Cmnd * cmd);
-static int adpt_reset(Scsi_Cmnd* cmd);
+static int adpt_detect(struct scsi_host_template * sht);
+static int adpt_queue(struct scsi_cmnd * cmd, void (*cmdcomplete) (struct scsi_cmnd *));
+static int adpt_abort(struct scsi_cmnd * cmd);
+static int adpt_reset(struct scsi_cmnd* cmd);
 static int adpt_release(struct Scsi_Host *host);
-static int adpt_slave_configure(Scsi_Device *);
+static int adpt_slave_configure(struct scsi_device *);
 
 static const char *adpt_info(struct Scsi_Host *pSHost);
 static int adpt_bios_param(struct scsi_device * sdev, struct block_device *dev,
                sector_t, int geom[]);
 
-static int adpt_bus_reset(Scsi_Cmnd* cmd);
-static int adpt_device_reset(Scsi_Cmnd* cmd);
+static int adpt_bus_reset(struct scsi_cmnd* cmd);
+static int adpt_device_reset(struct scsi_cmnd* cmd);
 
 
 /*
@@ -198,7 +198,7 @@ struct adpt_device {
        u8      state;
        u16     tid;
        struct i2o_device* pI2o_dev;
-       Scsi_Device *pScsi_dev;
+       struct scsi_device *pScsi_dev;
 };
 
 struct adpt_channel {
@@ -296,9 +296,9 @@ static s32 adpt_i2o_quiesce_hba(adpt_hba* pHba);
 static s32 adpt_i2o_status_get(adpt_hba* pHba);
 static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba);
 static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
-static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* dptdevice);
-static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd);
-static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht);
+static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice);
+static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd);
+static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht);
 static s32 adpt_hba_reset(adpt_hba* pHba);
 static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
 static s32 adpt_rescan(adpt_hba* pHba);
@@ -308,7 +308,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba);
 static void adpt_inquiry(adpt_hba* pHba);
 static void adpt_fail_posted_scbs(adpt_hba* pHba);
 static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun);
-static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) ;
+static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) ;
 static int adpt_i2o_online_hba(adpt_hba* pHba);
 static void adpt_i2o_post_wait_complete(u32, int);
 static int adpt_i2o_systab_send(adpt_hba* pHba);
index 8bac58f..34bce2c 100644 (file)
@@ -317,7 +317,7 @@ struct eata_ccb {         /* Send Command Packet structure      */
     __u8 rw_latency;
     __u8 retries;
     __u8 status;             /* status of this queueslot               */
-    Scsi_Cmnd *cmd;          /* address of cmd                         */
+    struct scsi_cmnd *cmd;    /* address of cmd                                */
     struct eata_sg_list *sg_list;
 };
 
index ea79b56..3c5151c 100644 (file)
@@ -46,6 +46,7 @@
  *  last change: 2002/11/02               OS: Linux 2.5.45  *
  ************************************************************/
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
 #include <linux/interrupt.h>
-#include <linux/stat.h>
-#include <linux/config.h>
 #include <linux/blkdev.h>
 #include <linux/spinlock.h>
 #include <asm/io.h>
 
-#include "scsi.h"
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
-#include <scsi/scsicam.h>
 
 #include "eata_generic.h"
 #include "eata_pio.h"
@@ -91,6 +91,8 @@ static unsigned char reg_IRQL[16];
 static unsigned long int_counter;
 static unsigned long queue_counter;
 
+static struct scsi_host_template driver_template;
+
 /*
  * eata_proc_info
  * inout : decides on the direction of the dataflow and the meaning of the 
@@ -170,15 +172,15 @@ static int eata_pio_release(struct Scsi_Host *sh)
                if (sh->io_port && sh->n_io_port)
                        release_region(sh->io_port, sh->n_io_port);
        }
-       return (TRUE);
+       return 1;
 }
 
-static void IncStat(Scsi_Pointer * SCp, uint Increment)
+static void IncStat(struct scsi_pointer *SCp, uint Increment)
 {
        SCp->ptr += Increment;
        if ((SCp->this_residual -= Increment) == 0) {
                if ((--SCp->buffers_residual) == 0)
-                       SCp->Status = FALSE;
+                       SCp->Status = 0;
                else {
                        SCp->buffer++;
                        SCp->ptr = page_address(SCp->buffer->page) + SCp->buffer->offset;
@@ -204,7 +206,7 @@ static irqreturn_t do_eata_pio_int_handler(int irq, void *dev_id,
 static void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
        uint eata_stat = 0xfffff;
-       Scsi_Cmnd *cmd;
+       struct scsi_cmnd *cmd;
        hostdata *hd;
        struct eata_ccb *cp;
        uint base;
@@ -233,12 +235,12 @@ static void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs)
                        if (stat & HA_SDRQ) {
                                if (cp->DataIn) {
                                        z = 256;
-                                       odd = FALSE;
+                                       odd = 0;
                                        while ((cmd->SCp.Status) && ((z > 0) || (odd))) {
                                                if (odd) {
                                                        *(cmd->SCp.ptr) = zwickel >> 8;
                                                        IncStat(&cmd->SCp, 1);
-                                                       odd = FALSE;
+                                                       odd = 0;
                                                }
                                                x = min_t(unsigned int, z, cmd->SCp.this_residual / 2);
                                                insw(base + HA_RDATA, cmd->SCp.ptr, x);
@@ -249,7 +251,7 @@ static void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs)
                                                        *(cmd->SCp.ptr) = zwickel & 0xff;
                                                        IncStat(&cmd->SCp, 1);
                                                        z--;
-                                                       odd = TRUE;
+                                                       odd = 1;
                                                }
                                        }
                                        while (z > 0) {
@@ -258,7 +260,7 @@ static void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs)
                                        }
                                } else {        /* cp->DataOut */
 
-                                       odd = FALSE;
+                                       odd = 0;
                                        z = 256;
                                        while ((cmd->SCp.Status) && ((z > 0) || (odd))) {
                                                if (odd) {
@@ -266,7 +268,7 @@ static void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs)
                                                        IncStat(&cmd->SCp, 1);
                                                        outw(zwickel, base + HA_RDATA);
                                                        z--;
-                                                       odd = FALSE;
+                                                       odd = 0;
                                                }
                                                x = min_t(unsigned int, z, cmd->SCp.this_residual / 2);
                                                outsw(base + HA_RDATA, cmd->SCp.ptr, x);
@@ -276,13 +278,13 @@ static void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs)
                                                        zwickel = *(cmd->SCp.ptr);
                                                        zwickel &= 0xff;
                                                        IncStat(&cmd->SCp, 1);
-                                                       odd = TRUE;
+                                                       odd = 1;
                                                }
                                        }
                                        while (z > 0 || odd) {
                                                outw(zwickel, base + HA_RDATA);
                                                z--;
-                                               odd = FALSE;
+                                               odd = 0;
                                        }
                                }
                        }
@@ -331,7 +333,7 @@ static inline uint eata_pio_send_command(uint base, unsigned char command)
 
        while (inb(base + HA_RSTATUS) & HA_SBUSY)
                if (--loop == 0)
-                       return (TRUE);
+                       return 1;
 
        /* Enable interrupts for HBA.  It is not the best way to do it at this
         * place, but I hope that it doesn't interfere with the IDE driver 
@@ -340,10 +342,11 @@ static inline uint eata_pio_send_command(uint base, unsigned char command)
        outb(HA_CTRL_8HEADS, base + HA_CTRLREG);
 
        outb(command, base + HA_WCOMMAND);
-       return (FALSE);
+       return 0;
 }
 
-static int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int eata_pio_queue(struct scsi_cmnd *cmd,
+               void (*done)(struct scsi_cmnd *))
 {
        uint x, y;
        uint base;
@@ -383,21 +386,21 @@ static int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 
        cmd->scsi_done = (void *) done;
 
-       if(cmd->sc_data_direction == SCSI_DATA_WRITE)
-               cp->DataOut = TRUE;     /* Output mode */
+       if (cmd->sc_data_direction == DMA_TO_DEVICE)
+               cp->DataOut = 1;        /* Output mode */
        else
-               cp->DataIn = TRUE;      /* Input mode  */
+               cp->DataIn = 0; /* Input mode  */
 
        cp->Interpret = (cmd->device->id == hd->hostid);
        cp->cp_datalen = htonl((unsigned long) cmd->request_bufflen);
-       cp->Auto_Req_Sen = FALSE;
+       cp->Auto_Req_Sen = 0;
        cp->cp_reqDMA = htonl(0);
        cp->reqlen = 0;
 
        cp->cp_id = cmd->device->id;
        cp->cp_lun = cmd->device->lun;
-       cp->cp_dispri = FALSE;
-       cp->cp_identify = TRUE;
+       cp->cp_dispri = 0;
+       cp->cp_identify = 1;
        memcpy(cp->cp_cdb, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
 
        cp->cp_statDMA = htonl(0);
@@ -440,7 +443,7 @@ static int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        return (0);
 }
 
-static int eata_pio_abort(Scsi_Cmnd * cmd)
+static int eata_pio_abort(struct scsi_cmnd *cmd)
 {
        uint loop = HZ;
 
@@ -472,11 +475,11 @@ static int eata_pio_abort(Scsi_Cmnd * cmd)
        panic("eata_pio: abort: invalid slot status\n");
 }
 
-static int eata_pio_host_reset(Scsi_Cmnd * cmd)
+static int eata_pio_host_reset(struct scsi_cmnd *cmd)
 {
        uint x, limit = 0;
-       unsigned char success = FALSE;
-       Scsi_Cmnd *sp;
+       unsigned char success = 0;
+       struct scsi_cmnd *sp;
        struct Scsi_Host *host = cmd->device->host;
 
        DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason));
@@ -530,7 +533,7 @@ static int eata_pio_host_reset(Scsi_Cmnd * cmd)
                sp->scsi_done(sp);
        }
 
-       HD(cmd)->state = FALSE;
+       HD(cmd)->state = 0;
 
        if (success) {          /* hmmm... */
                DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, success.\n"));
@@ -550,8 +553,8 @@ static char *get_pio_board_data(unsigned long base, uint irq, uint id, unsigned
        memset(&cp, 0, sizeof(struct eata_ccb));
        memset(buff, 0, sizeof(buff));
 
-       cp.DataIn = TRUE;
-       cp.Interpret = TRUE;    /* Interpret command */
+       cp.DataIn = 1;
+       cp.Interpret = 1;       /* Interpret command */
 
        cp.cp_datalen = htonl(254);
        cp.cp_dataDMA = htonl(0);
@@ -593,14 +596,14 @@ static int get_pio_conf_PIO(u32 base, struct get_conf *buf)
        int z;
        unsigned short *p;
 
-       if (check_region(base, 9))
-               return (FALSE);
+       if (!request_region(base, 9, "eata_pio"))
+               return 0;
 
        memset(buf, 0, sizeof(struct get_conf));
 
        while (inb(base + HA_RSTATUS) & HA_SBUSY)
                if (--loop == 0)
-                       return (FALSE);
+                       goto fail;
 
        DBG(DBG_PIO && DBG_PROBE, printk(KERN_DEBUG "Issuing PIO READ CONFIG to HBA at %#x\n", base));
        eata_pio_send_command(base, EATA_CMD_PIO_READ_CONFIG);
@@ -609,30 +612,40 @@ static int get_pio_conf_PIO(u32 base, struct get_conf *buf)
        for (p = (unsigned short *) buf; (long) p <= ((long) buf + (sizeof(struct get_conf) / 2)); p++) {
                while (!(inb(base + HA_RSTATUS) & HA_SDRQ))
                        if (--loop == 0)
-                               return (FALSE);
+                               goto fail;
 
                loop = HZ / 2;
                *p = inw(base + HA_RDATA);
        }
-       if (!(inb(base + HA_RSTATUS) & HA_SERROR)) {    /* Error ? */
-               if (htonl(EATA_SIGNATURE) == buf->signature) {
-                       DBG(DBG_PIO && DBG_PROBE, printk(KERN_NOTICE "EATA Controller found " "at %#4x EATA Level: %x\n", base, (uint) (buf->version)));
-
-                       while (inb(base + HA_RSTATUS) & HA_SDRQ)
-                               inw(base + HA_RDATA);
-                       if (ALLOW_DMA_BOARDS == FALSE) {
-                               for (z = 0; z < MAXISA; z++)
-                                       if (base == ISAbases[z]) {
-                                               buf->IRQ = ISAirqs[z];
-                                               break;
-                                       }
+       if (inb(base + HA_RSTATUS) & HA_SERROR) {
+               DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during "
+                                       "transfer for HBA at %x\n", base));
+               goto fail;
+       }
+
+       if (htonl(EATA_SIGNATURE) != buf->signature)
+               goto fail;
+
+       DBG(DBG_PIO && DBG_PROBE, printk(KERN_NOTICE "EATA Controller found "
+                               "at %#4x EATA Level: %x\n",
+                               base, (uint) (buf->version)));
+
+       while (inb(base + HA_RSTATUS) & HA_SDRQ)
+               inw(base + HA_RDATA);
+
+       if (!ALLOW_DMA_BOARDS) {
+               for (z = 0; z < MAXISA; z++)
+                       if (base == ISAbases[z]) {
+                               buf->IRQ = ISAirqs[z];
+                               break;
                        }
-                       return (TRUE);
-               }
-       } else {
-               DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during transfer " "for HBA at %x\n", base));
        }
-       return (FALSE);
+
+       return 1;
+
+ fail:
+       release_region(base, 9);
+       return 0;
 }
 
 static void print_pio_config(struct get_conf *gc)
@@ -670,7 +683,7 @@ static uint print_selftest(uint base)
        return (!(inb(base + HA_RSTATUS) & HA_SERROR));
 }
 
-static int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
+static int register_pio_HBA(long base, struct get_conf *gc)
 {
        unsigned long size = 0;
        char *buff;
@@ -681,47 +694,41 @@ static int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template *
 
        DBG(DBG_REGISTER, print_pio_config(gc));
 
-       if (gc->DMA_support == TRUE) {
+       if (gc->DMA_support) {
                printk("HBA at %#.4lx supports DMA. Please use EATA-DMA driver.\n", base);
-               if (ALLOW_DMA_BOARDS == FALSE)
-                       return (FALSE);
+               if (!ALLOW_DMA_BOARDS)
+                       return 0;
        }
 
        if ((buff = get_pio_board_data((uint) base, gc->IRQ, gc->scsi_id[3], cplen = (htonl(gc->cplen) + 1) / 2, cppadlen = (htons(gc->cppadlen) + 1) / 2)) == NULL) {
                printk("HBA at %#lx didn't react on INQUIRY. Sorry.\n", (unsigned long) base);
-               return (FALSE);
+               return 0;
        }
 
-       if (print_selftest(base) == FALSE && ALLOW_DMA_BOARDS == FALSE) {
+       if (!print_selftest(base) && !ALLOW_DMA_BOARDS) {
                printk("HBA at %#lx failed while performing self test & setup.\n", (unsigned long) base);
-               return (FALSE);
+               return 0;
        }
 
-       request_region(base, 8, "eata_pio");
-
        size = sizeof(hostdata) + (sizeof(struct eata_ccb) * ntohs(gc->queuesiz));
 
-       sh = scsi_register(tpnt, size);
-       if (sh == NULL) {
-               release_region(base, 8);
-               return FALSE;
-       }
+       sh = scsi_register(&driver_template, size);
+       if (sh == NULL)
+               return 0;
 
        if (!reg_IRQ[gc->IRQ]) {        /* Interrupt already registered ? */
                if (!request_irq(gc->IRQ, do_eata_pio_int_handler, SA_INTERRUPT, "EATA-PIO", sh)) {
                        reg_IRQ[gc->IRQ]++;
                        if (!gc->IRQ_TR)
-                               reg_IRQL[gc->IRQ] = TRUE;       /* IRQ is edge triggered */
+                               reg_IRQL[gc->IRQ] = 1;  /* IRQ is edge triggered */
                } else {
                        printk("Couldn't allocate IRQ %d, Sorry.\n", gc->IRQ);
-                       release_region(base, 8);
-                       return (FALSE);
+                       return 0;
                }
        } else {                /* More than one HBA on this IRQ */
-               if (reg_IRQL[gc->IRQ] == TRUE) {
+               if (reg_IRQL[gc->IRQ]) {
                        printk("Can't support more than one HBA on this IRQ,\n" "  if the IRQ is edge triggered. Sorry.\n");
-                       release_region(base, 8);
-                       return (FALSE);
+                       return 0;
                } else
                        reg_IRQ[gc->IRQ]++;
        }
@@ -757,9 +764,9 @@ static int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template *
        }
 
        if (ntohl(gc->len) >= 0x22) {
-               if (gc->is_PCI == TRUE)
+               if (gc->is_PCI)
                        hd->bustype = IS_PCI;
-               else if (gc->is_EISA == TRUE)
+               else if (gc->is_EISA)
                        hd->bustype = IS_EISA;
                else
                        hd->bustype = IS_ISA;
@@ -780,7 +787,7 @@ static int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template *
        sh->unique_id = base;
        sh->base = base;
        sh->io_port = base;
-       sh->n_io_port = 8;
+       sh->n_io_port = 9;
        sh->irq = gc->IRQ;
        sh->dma_channel = PIO;
        sh->this_id = gc->scsi_id[3];
@@ -794,11 +801,11 @@ static int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template *
        sh->max_lun = 8;
 
        if (gc->SECOND)
-               hd->primary = FALSE;
+               hd->primary = 0;
        else
-               hd->primary = TRUE;
+               hd->primary = 1;
 
-       sh->unchecked_isa_dma = FALSE;  /* We can only do PIO */
+       sh->unchecked_isa_dma = 0;      /* We can only do PIO */
 
        hd->next = NULL;        /* build a linked list of all HBAs */
        hd->prev = last_HBA;
@@ -811,22 +818,24 @@ static int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template *
        return (1);
 }
 
-static void find_pio_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
+static void find_pio_ISA(struct get_conf *buf)
 {
        int i;
 
        for (i = 0; i < MAXISA; i++) {
-               if (ISAbases[i]) {
-                       if (get_pio_conf_PIO(ISAbases[i], buf) == TRUE) {
-                               register_pio_HBA(ISAbases[i], buf, tpnt);
-                       }
+               if (!ISAbases[i])
+                       continue;
+               if (!get_pio_conf_PIO(ISAbases[i], buf))
+                       continue;
+               if (!register_pio_HBA(ISAbases[i], buf))
+                       release_region(ISAbases[i], 9);
+               else
                        ISAbases[i] = 0;
-               }
        }
        return;
 }
 
-static void find_pio_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
+static void find_pio_EISA(struct get_conf *buf)
 {
        u32 base;
        int i;
@@ -836,7 +845,7 @@ static void find_pio_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
 #endif
 
        for (i = 0; i < MAXEISA; i++) {
-               if (EISAbases[i] == TRUE) {     /* Still a possibility ?          */
+               if (EISAbases[i]) {     /* Still a possibility ?          */
 
                        base = 0x1c88 + (i * 0x1000);
 #if CHECKPAL
@@ -847,12 +856,15 @@ static void find_pio_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
                        if (((pal1 == 0x12) && (pal2 == 0x14)) || ((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) || ((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24))) {
                                DBG(DBG_PROBE, printk(KERN_NOTICE "EISA EATA id tags found: " "%x %x %x \n", (int) pal1, (int) pal2, (int) pal3));
 #endif
-                               if (get_pio_conf_PIO(base, buf) == TRUE) {
+                               if (get_pio_conf_PIO(base, buf)) {
                                        DBG(DBG_PROBE && DBG_EISA, print_pio_config(buf));
                                        if (buf->IRQ) {
-                                               register_pio_HBA(base, buf, tpnt);
-                                       } else
+                                               if (!register_pio_HBA(base, buf))
+                                                       release_region(base, 9);
+                                       } else {
                                                printk(KERN_NOTICE "eata_dma: No valid IRQ. HBA " "removed from list\n");
+                                               release_region(base, 9);
+                                       }
                                }
                                /* Nothing found here so we take it from the list */
                                EISAbases[i] = 0;
@@ -864,7 +876,7 @@ static void find_pio_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
        return;
 }
 
-static void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
+static void find_pio_PCI(struct get_conf *buf)
 {
 #ifndef CONFIG_PCI
        printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n");
@@ -889,16 +901,21 @@ static void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
                base += 0x10;   /* Now, THIS is the real address */
                if (base != 0x1f8) {
                        /* We didn't find it in the primary search */
-                       if (get_pio_conf_PIO(base, buf) == TRUE) {
-                               if (buf->FORCADR)       /* If the address is forced */
+                       if (get_pio_conf_PIO(base, buf)) {
+                               if (buf->FORCADR) {     /* If the address is forced */
+                                       release_region(base, 9);
                                        continue;       /* we'll find it later      */
+                               }
 
                                /* OK. We made it till here, so we can go now  
                                 * and register it. We  only have to check and 
                                 * eventually remove it from the EISA and ISA list 
                                 */
 
-                               register_pio_HBA(base, buf, tpnt);
+                               if (!register_pio_HBA(base, buf)) {
+                                       release_region(base, 9);
+                                       continue;
+                               }
 
                                if (base < 0x1000) {
                                        for (x = 0; x < MAXISA; ++x) {
@@ -913,7 +930,7 @@ static void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
                                }
                        }
 #if CHECK_BLINK
-                       else if (check_blink_state(base) == TRUE) {
+                       else if (check_blink_state(base)) {
                                printk("eata_pio: HBA is in BLINK state.\n" "Consult your HBAs manual to correct this.\n");
                        }
 #endif
@@ -922,20 +939,15 @@ static void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
 #endif                         /* #ifndef CONFIG_PCI */
 }
 
-
-static int eata_pio_detect(Scsi_Host_Template * tpnt)
+static int eata_pio_detect(struct scsi_host_template *tpnt)
 {
        struct Scsi_Host *HBA_ptr;
        struct get_conf gc;
        int i;
 
-       tpnt->proc_name = "eata_pio";
-
-       find_pio_PCI(&gc, tpnt);
-
-       find_pio_EISA(&gc, tpnt);
-
-       find_pio_ISA(&gc, tpnt);
+       find_pio_PCI(&gc);
+       find_pio_EISA(&gc);
+       find_pio_ISA(&gc);
 
        for (i = 0; i <= MAXIRQ; i++)
                if (reg_IRQ[i])
@@ -955,16 +967,19 @@ static int eata_pio_detect(Scsi_Host_Template * tpnt)
                               HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision,
                               SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P') ?
                               "PCI " : (SD(HBA_ptr)->bustype == 'E') ? "EISA" : "ISA ",
-                              (uint) HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel, HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE) ? 'Y' : 'N', HBA_ptr->can_queue, HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun);
+                              (uint) HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel, HBA_ptr->this_id,
+                              SD(HBA_ptr)->primary ? 'Y' : 'N', HBA_ptr->can_queue,
+                              HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun);
                        HBA_ptr = SD(HBA_ptr)->next;
                }
        }
        return (registered_HBAs);
 }
 
-static Scsi_Host_Template driver_template = {
-       .proc_info              = eata_pio_proc_info,
+static struct scsi_host_template driver_template = {
+       .proc_name              = "eata_pio",
        .name                   = "EATA (Extended Attachment) PIO driver",
+       .proc_info              = eata_pio_proc_info,
        .detect                 = eata_pio_detect,
        .release                = eata_pio_release,
        .queuecommand           = eata_pio_queue,
index 5237cad..782c31b 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 
 #include "esp.h"
 
 #include <asm/oplib.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-
 #ifndef __sparc_v9__
 #include <asm/machines.h>
 #include <asm/idprom.h>
 #endif
 
-#include <linux/module.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
 
 #define DEBUG_ESP
 /* #define DEBUG_ESP_HME */
index 2957394..85beb47 100644 (file)
@@ -8,22 +8,9 @@
 #ifndef _SPARC_ESP_H
 #define _SPARC_ESP_H
 
-#include <linux/config.h>
-
-/* #include "scsi.h" */
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_eh.h>
-#include <scsi/scsi_request.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_host.h>
-
 /* For dvma controller register definitions. */
 #include <asm/dma.h>
 
-#define scsi_to_sbus_dma_dir(scsi_dir) ((int)(scsi_dir))
-
 /* The ESP SCSI controllers have their register sets in three
  * "classes":
  *
@@ -86,6 +73,8 @@ struct esp_device {
   unsigned disconnect:1;
 };
 
+struct scsi_cmnd;
+
 /* We get one of these for each ESP probed. */
 struct esp {
        unsigned long           eregs;          /* ESP controller registers */
index 9046901..763e33b 100644 (file)
@@ -87,6 +87,7 @@
 #include <linux/delay.h>
 #include <linux/mca.h>
 #include <linux/spinlock.h>
+#include <scsi/scsicam.h>
 #include <linux/mca-legacy.h>
 
 #include <asm/io.h>
@@ -1337,23 +1338,14 @@ static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
 static int fd_mcs_biosparam(struct scsi_device * disk, struct block_device *bdev,
                            sector_t capacity, int *info_array) 
 {
-       unsigned char buf[512 + sizeof(int) * 2];
+       unsigned char *p = scsi_bios_ptable(bdev);
        int size = capacity;
-       int *sizes = (int *) buf;
-       unsigned char *data = (unsigned char *) (sizes + 2);
-       unsigned char do_read[] = { READ_6, 0, 0, 0, 1, 0 };
-       int retcode;
 
        /* BIOS >= 3.4 for MCA cards */
        /* This algorithm was provided by Future Domain (much thanks!). */
 
-       sizes[0] = 0;   /* zero bytes out */
-       sizes[1] = 512; /* one sector in */
-       memcpy(data, do_read, sizeof(do_read));
-       retcode = kernel_scsi_ioctl(disk, SCSI_IOCTL_SEND_COMMAND, (void *) buf);
-       if (!retcode    /* SCSI command ok */
-           && data[511] == 0xaa && data[510] == 0x55   /* Partition table valid */
-           && data[0x1c2]) {   /* Partition type */
+       if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */
+           && p[4]) {  /* Partition type */
                /* The partition table layout is as follows:
 
                   Start: 0x1b3h
@@ -1383,8 +1375,8 @@ static int fd_mcs_biosparam(struct scsi_device * disk, struct block_device *bdev
                   Future Domain algorithm, but it seemed to be a reasonable thing
                   to do, especially in the Linux and BSD worlds. */
 
-               info_array[0] = data[0x1c3] + 1;        /* heads */
-               info_array[1] = data[0x1c4] & 0x3f;     /* sectors */
+               info_array[0] = p[5] + 1;       /* heads */
+               info_array[1] = p[6] & 0x3f;    /* sectors */
        } else {
                /* Note that this new method guarantees that there will always be
                   less than 1024 cylinders on a platter.  This is good for drives
@@ -1403,6 +1395,7 @@ static int fd_mcs_biosparam(struct scsi_device * disk, struct block_device *bdev
        }
        /* For both methods, compute the cylinders */
        info_array[2] = (unsigned int) size / (info_array[0] * info_array[1]);
+       kfree(p);
        return 0;
 }
 
index 0fff870..9cd9f4c 100644 (file)
 #include <linux/pci.h>
 #include <linux/stat.h>
 #include <linux/delay.h>
+#include <scsi/scsicam.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -1564,12 +1565,7 @@ static int fdomain_16x0_biosparam(struct scsi_device *sdev,
                sector_t capacity, int *info_array)
 {
    int              drive;
-   unsigned char    buf[512 + sizeof (Scsi_Ioctl_Command)];
-   Scsi_Ioctl_Command *sic = (Scsi_Ioctl_Command *) buf;
    int             size      = capacity;
-   unsigned char    *data     = sic->data;
-   unsigned char    do_read[] = { READ_6, 0, 0, 0, 1, 0 };
-   int              retcode;
    unsigned long    offset;
    struct drive_info {
       unsigned short cylinders;
@@ -1657,16 +1653,10 @@ static int fdomain_16x0_biosparam(struct scsi_device *sdev,
       info_array[2] = i.cylinders;
    } else {                    /* 3.4 BIOS (and up?) */
       /* This algorithm was provided by Future Domain (much thanks!). */
+      unsigned char *p = scsi_bios_ptable(bdev);
 
-      sic->inlen  = 0;         /* zero bytes out */
-      sic->outlen = 512;               /* one sector in */
-      memcpy( data, do_read, sizeof( do_read ) );
-      retcode = kernel_scsi_ioctl( sdev,
-                                  SCSI_IOCTL_SEND_COMMAND,
-                                  sic );
-      if (!retcode                                 /* SCSI command ok */
-         && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */
-         && data[0x1c2]) {                         /* Partition type */
+      if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */
+         && p[4]) {                        /* Partition type */
 
         /* The partition table layout is as follows:
 
@@ -1697,8 +1687,8 @@ static int fdomain_16x0_biosparam(struct scsi_device *sdev,
            Future Domain algorithm, but it seemed to be a reasonable thing
            to do, especially in the Linux and BSD worlds. */
 
-        info_array[0] = data[0x1c3] + 1;           /* heads */
-        info_array[1] = data[0x1c4] & 0x3f;        /* sectors */
+        info_array[0] = p[5] + 1;          /* heads */
+        info_array[1] = p[6] & 0x3f;       /* sectors */
       } else {
 
         /* Note that this new method guarantees that there will always be
@@ -1718,6 +1708,7 @@ static int fdomain_16x0_biosparam(struct scsi_device *sdev,
       }
                                /* For both methods, compute the cylinders */
       info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] );
+      kfree(p);
    }
    
    return 0;
index 5047d98..6cb8fa2 100644 (file)
 #endif
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "gdth.h"
 
 static void gdth_delay(int milliseconds);
@@ -3520,7 +3520,7 @@ static void gdth_readapp_event(gdth_ha_str *ha,
     GDTH_UNLOCK_HA(ha, flags);
 }
 
-static void gdth_clear_events()
+static void gdth_clear_events(void)
 {
     TRACE(("gdth_clear_events()"));
 
@@ -5293,13 +5293,13 @@ static int gdth_close(struct inode *inode, struct file *filep)
     return 0;
 }
 
-static int ioc_event(unsigned long arg)
+static int ioc_event(void __user *arg)
 {
     gdth_ioctl_event evt;
     gdth_ha_str *ha;
     ulong flags;
 
-    if (copy_from_user(&evt, (char *)arg, sizeof(gdth_ioctl_event)) ||
+    if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event)) ||
         evt.ionode >= gdth_ctr_count)
         return -EFAULT;
     ha = HADATA(gdth_ctr_tab[evt.ionode]);
@@ -5324,19 +5324,19 @@ static int ioc_event(unsigned long arg)
     } else {
         gdth_readapp_event(ha, evt.erase, &evt.event);
     }     
-    if (copy_to_user((char *)arg, &evt, sizeof(gdth_ioctl_event)))
+    if (copy_to_user(arg, &evt, sizeof(gdth_ioctl_event)))
         return -EFAULT;
     return 0;
 }
 
-static int ioc_lockdrv(unsigned long arg)
+static int ioc_lockdrv(void __user *arg)
 {
     gdth_ioctl_lockdrv ldrv;
     unchar i, j;
     ulong flags;
     gdth_ha_str *ha;
 
-    if (copy_from_user(&ldrv, (char *)arg, sizeof(gdth_ioctl_lockdrv)) ||
+    if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv)) ||
         ldrv.ionode >= gdth_ctr_count)
         return -EFAULT;
     ha = HADATA(gdth_ctr_tab[ldrv.ionode]);
@@ -5362,7 +5362,7 @@ static int ioc_lockdrv(unsigned long arg)
     return 0;
 }
 
-static int ioc_resetdrv(unsigned long arg, char *cmnd)
+static int ioc_resetdrv(void __user *arg, char *cmnd)
 {
     gdth_ioctl_reset res;
     gdth_cmd_str cmd;
@@ -5376,7 +5376,7 @@ static int ioc_resetdrv(unsigned long arg, char *cmnd)
         Scsi_Cmnd scp;
 #endif
 
-    if (copy_from_user(&res, (char *)arg, sizeof(gdth_ioctl_reset)) ||
+    if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) ||
         res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES)
         return -EFAULT;
     hanum = res.ionode;
@@ -5418,12 +5418,12 @@ static int ioc_resetdrv(unsigned long arg, char *cmnd)
     gdth_do_cmd(&scp, &cmd, cmnd, 30);
     res.status = (ushort)scp.SCp.Status;
 #endif
-    if (copy_to_user((char *)arg, &res, sizeof(gdth_ioctl_reset)))
+    if (copy_to_user(arg, &res, sizeof(gdth_ioctl_reset)))
         return -EFAULT;
     return 0;
 }
 
-static int ioc_general(unsigned long arg, char *cmnd)
+static int ioc_general(void __user *arg, char *cmnd)
 {
     gdth_ioctl_general gen;
     char *buf = NULL;
@@ -5438,7 +5438,7 @@ static int ioc_general(unsigned long arg, char *cmnd)
         Scsi_Cmnd scp;
 #endif
         
-    if (copy_from_user(&gen, (char *)arg, sizeof(gdth_ioctl_general)) ||
+    if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) ||
         gen.ionode >= gdth_ctr_count)
         return -EFAULT;
     hanum = gen.ionode; 
@@ -5447,7 +5447,7 @@ static int ioc_general(unsigned long arg, char *cmnd)
         if (!(buf = gdth_ioctl_alloc(hanum, gen.data_len + gen.sense_len, 
                                      FALSE, &paddr)))
             return -EFAULT;
-        if (copy_from_user(buf, (char *)arg + sizeof(gdth_ioctl_general),  
+        if (copy_from_user(buf, arg + sizeof(gdth_ioctl_general),  
                            gen.data_len + gen.sense_len)) {
             gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
             return -EFAULT;
@@ -5559,12 +5559,12 @@ static int ioc_general(unsigned long arg, char *cmnd)
     gen.info = scp.SCp.Message;
 #endif
 
-    if (copy_to_user((char *)arg + sizeof(gdth_ioctl_general), buf, 
+    if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, 
                      gen.data_len + gen.sense_len)) {
         gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
         return -EFAULT; 
     } 
-    if (copy_to_user((char *)arg, &gen, 
+    if (copy_to_user(arg, &gen, 
         sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) {
         gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
         return -EFAULT;
@@ -5573,7 +5573,7 @@ static int ioc_general(unsigned long arg, char *cmnd)
     return 0;
 }
  
-static int ioc_hdrlist(unsigned long arg, char *cmnd)
+static int ioc_hdrlist(void __user *arg, char *cmnd)
 {
     gdth_ioctl_rescan rsc;
     gdth_cmd_str cmd;
@@ -5588,7 +5588,7 @@ static int ioc_hdrlist(unsigned long arg, char *cmnd)
     Scsi_Cmnd scp;
 #endif
         
-    if (copy_from_user(&rsc, (char *)arg, sizeof(gdth_ioctl_rescan)) ||
+    if (copy_from_user(&rsc, arg, sizeof(gdth_ioctl_rescan)) ||
         rsc.ionode >= gdth_ctr_count)
         return -EFAULT;
     hanum = rsc.ionode;
@@ -5652,12 +5652,12 @@ static int ioc_hdrlist(unsigned long arg, char *cmnd)
     scsi_release_command(scp);
 #endif       
  
-    if (copy_to_user((char *)arg, &rsc, sizeof(gdth_ioctl_rescan)))
+    if (copy_to_user(arg, &rsc, sizeof(gdth_ioctl_rescan)))
         return -EFAULT;
     return 0;
 }
 
-static int ioc_rescan(unsigned long arg, char *cmnd)
+static int ioc_rescan(void __user *arg, char *cmnd)
 {
     gdth_ioctl_rescan rsc;
     gdth_cmd_str cmd;
@@ -5674,7 +5674,7 @@ static int ioc_rescan(unsigned long arg, char *cmnd)
     Scsi_Cmnd scp;
 #endif
         
-    if (copy_from_user(&rsc, (char *)arg, sizeof(gdth_ioctl_rescan)) ||
+    if (copy_from_user(&rsc, arg, sizeof(gdth_ioctl_rescan)) ||
         rsc.ionode >= gdth_ctr_count)
         return -EFAULT;
     hanum = rsc.ionode;
@@ -5852,7 +5852,7 @@ static int ioc_rescan(unsigned long arg, char *cmnd)
     scsi_release_command(scp);
 #endif       
  
-    if (copy_to_user((char *)arg, &rsc, sizeof(gdth_ioctl_rescan)))
+    if (copy_to_user(arg, &rsc, sizeof(gdth_ioctl_rescan)))
         return -EFAULT;
     return 0;
 }
@@ -5870,6 +5870,7 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
 #endif
     ulong flags;
     char cmnd[MAX_COMMAND_SIZE];   
+    void __user *argp = (void __user *)arg;
 
     memset(cmnd, 0xff, 12);
     
@@ -5879,7 +5880,7 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
       case GDTIOCTL_CTRCNT:
       { 
         int cnt = gdth_ctr_count;
-        if (put_user(cnt, (int *)arg))
+        if (put_user(cnt, (int __user *)argp))
                 return -EFAULT;
         break;
       }
@@ -5887,7 +5888,7 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
       case GDTIOCTL_DRVERS:
       { 
         int ver = (GDTH_VERSION<<8) | GDTH_SUBVERSION;
-        if (put_user(ver, (int *)arg))
+        if (put_user(ver, (int __user *)argp))
                 return -EFAULT;
         break;
       }
@@ -5899,7 +5900,7 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
         osv.version = (unchar)(LINUX_VERSION_CODE >> 16);
         osv.subversion = (unchar)(LINUX_VERSION_CODE >> 8);
         osv.revision = (ushort)(LINUX_VERSION_CODE & 0xff);
-        if (copy_to_user((char *)arg, &osv, sizeof(gdth_ioctl_osvers)))
+        if (copy_to_user(argp, &osv, sizeof(gdth_ioctl_osvers)))
                 return -EFAULT;
         break;
       }
@@ -5908,7 +5909,7 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
       { 
         gdth_ioctl_ctrtype ctrt;
         
-        if (copy_from_user(&ctrt, (char *)arg, sizeof(gdth_ioctl_ctrtype)) ||
+        if (copy_from_user(&ctrt, argp, sizeof(gdth_ioctl_ctrtype)) ||
             ctrt.ionode >= gdth_ctr_count)
             return -EFAULT;
         ha = HADATA(gdth_ctr_tab[ctrt.ionode]);
@@ -5930,26 +5931,26 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
         }
         ctrt.info = ha->brd_phys;
         ctrt.oem_id = ha->oem_id;
-        if (copy_to_user((char *)arg, &ctrt, sizeof(gdth_ioctl_ctrtype)))
+        if (copy_to_user(argp, &ctrt, sizeof(gdth_ioctl_ctrtype)))
             return -EFAULT;
         break;
       }
         
       case GDTIOCTL_GENERAL:
-        return ioc_general(arg, cmnd);
+        return ioc_general(argp, cmnd);
 
       case GDTIOCTL_EVENT:
-        return ioc_event(arg);
+        return ioc_event(argp);
 
       case GDTIOCTL_LOCKDRV:
-        return ioc_lockdrv(arg);
+        return ioc_lockdrv(argp);
 
       case GDTIOCTL_LOCKCHN:
       {
         gdth_ioctl_lockchn lchn;
         unchar i, j;
 
-        if (copy_from_user(&lchn, (char *)arg, sizeof(gdth_ioctl_lockchn)) ||
+        if (copy_from_user(&lchn, argp, sizeof(gdth_ioctl_lockchn)) ||
             lchn.ionode >= gdth_ctr_count)
             return -EFAULT;
         ha = HADATA(gdth_ctr_tab[lchn.ionode]);
@@ -5978,17 +5979,17 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
       }
 
       case GDTIOCTL_RESCAN:
-        return ioc_rescan(arg, cmnd);
+        return ioc_rescan(argp, cmnd);
 
       case GDTIOCTL_HDRLIST:
-        return ioc_hdrlist(arg, cmnd);
+        return ioc_hdrlist(argp, cmnd);
 
       case GDTIOCTL_RESET_BUS:
       {
         gdth_ioctl_reset res;
         int hanum, rval;
 
-        if (copy_from_user(&res, (char *)arg, sizeof(gdth_ioctl_reset)) ||
+        if (copy_from_user(&res, argp, sizeof(gdth_ioctl_reset)) ||
             res.ionode >= gdth_ctr_count)
             return -EFAULT;
         hanum = res.ionode; 
@@ -6025,13 +6026,13 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
         rval = gdth_eh_bus_reset(&scp);
         res.status = (rval == SUCCESS ? S_OK : S_GENERR);
 #endif
-        if (copy_to_user((char *)arg, &res, sizeof(gdth_ioctl_reset)))
+        if (copy_to_user(argp, &res, sizeof(gdth_ioctl_reset)))
             return -EFAULT;
         break;
       }
 
       case GDTIOCTL_RESET_DRV:
-        return ioc_resetdrv(arg, cmnd);
+        return ioc_resetdrv(argp, cmnd);
 
       default:
         break; 
index b468333..811c66d 100644 (file)
@@ -318,6 +318,13 @@ ide_startstop_t idescsi_atapi_error (ide_drive_t *drive, const char *msg, byte s
        if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
                return ide_stopped;
 
+       /* retry only "normal" I/O: */
+       if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
+               rq->errors = 1;
+               ide_end_drive_cmd(drive, stat, err);
+               return ide_stopped;
+       }
+
        if (HWIF(drive)->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
                /* force an abort */
                HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
@@ -334,6 +341,13 @@ ide_startstop_t idescsi_atapi_abort (ide_drive_t *drive, const char *msg)
        if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
               return ide_stopped;
 
+       /* retry only "normal" I/O: */
+       if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
+               rq->errors = 1;
+               ide_end_drive_cmd(drive, BUSY_STAT, 0);
+               return ide_stopped;
+       }
+
 #if IDESCSI_DEBUG_LOG
        printk(KERN_WARNING "idescsi_atapi_abort called for %lu\n",
                        ((idescsi_pc_t *) rq->special)->scsi_cmd->serial_number);
index e9c5098..2114bbf 100644 (file)
@@ -2884,6 +2884,7 @@ static int ipr_slave_alloc(struct scsi_device *sdev)
                    (res->cfgte.res_addr.lun == sdev->lun)) {
                        res->sdev = sdev;
                        res->add_to_ml = 0;
+                       res->in_erp = 0;
                        sdev->hostdata = res;
                        res->needs_sync_complete = 1;
                        break;
@@ -3435,8 +3436,10 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd)
                       SCSI_SENSE_BUFFERSIZE);
        }
 
-       if (res)
+       if (res) {
                res->needs_sync_complete = 1;
+               res->in_erp = 0;
+       }
        ipr_unmap_sglist(ioa_cfg, ipr_cmd);
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
        scsi_cmd->scsi_done(scsi_cmd);
@@ -3479,6 +3482,12 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd)
 static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd)
 {
        struct ipr_cmd_pkt *cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt;
+       u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+
+       if (IPR_IOASC_SENSE_KEY(ioasc) > 0) {
+               ipr_erp_done(ipr_cmd);
+               return;
+       }
 
        ipr_reinit_ipr_cmnd_for_erp(ipr_cmd);
 
@@ -3756,6 +3765,7 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg,
                        ipr_erp_cancel_all(ipr_cmd);
                        return;
                }
+               res->needs_sync_complete = 1;
                break;
        case IPR_IOASC_NR_INIT_CMD_REQUIRED:
                break;
@@ -4808,6 +4818,7 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd)
        ipr_cmd->timer.data = (unsigned long) ipr_cmd;
        ipr_cmd->timer.expires = jiffies + IPR_OPERATIONAL_TIMEOUT;
        ipr_cmd->timer.function = (void (*)(unsigned long))ipr_timeout;
+       ipr_cmd->done = ipr_reset_ioa_job;
        add_timer(&ipr_cmd->timer);
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
 
index 468c807..eadafeb 100644 (file)
@@ -36,8 +36,8 @@
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.0.7"
-#define IPR_DRIVER_DATE "(May 21, 2004)"
+#define IPR_DRIVER_VERSION "2.0.9"
+#define IPR_DRIVER_DATE "(May 26, 2004)"
 
 /*
  * IPR_DBG_TRACE: Setting this to 1 will turn on some general function tracing
index 429c227..8740108 100644 (file)
@@ -49,7 +49,6 @@
 #include <asm/parisc-device.h>
 #include <asm/delay.h>
 
-#include "scsi.h"
 #include <scsi/scsi_host.h>
 
 #include "lasi700.h"
@@ -65,7 +64,7 @@ static struct parisc_device_id lasi700_ids[] = {
        { 0 }
 };
 
-static Scsi_Host_Template lasi700_template = {
+static struct scsi_host_template lasi700_template = {
        .name           = "LASI SCSI 53c700",
        .proc_name      = "lasi700",
        .this_id        = 7,
index 67e9b68..c1d4e75 100644 (file)
@@ -3815,7 +3815,8 @@ mega_n_to_m(void *arg, megacmd_t *mc)
 
                        umc = MBOX_P(uiocp);
 
-                       upthru = (mega_passthru *)umc->xferaddr;
+                       if (get_user(upthru, (mega_passthru **)&umc->xferaddr))
+                               return (-EFAULT);
 
                        if( put_user(mc->status, (u8 *)&upthru->scsistatus) )
                                return (-EFAULT);
@@ -3831,7 +3832,8 @@ mega_n_to_m(void *arg, megacmd_t *mc)
 
                        umc = (megacmd_t *)uioc_mimd->mbox;
 
-                       upthru = (mega_passthru *)umc->xferaddr;
+                       if (get_user(upthru, (mega_passthru **)&umc->xferaddr))
+                               return (-EFAULT);
 
                        if( put_user(mc->status, (u8 *)&upthru->scsistatus) )
                                return (-EFAULT);
@@ -4082,12 +4084,9 @@ mega_del_logdrv(adapter_t *adapter, int logdrv)
         * Wait till all the issued commands are complete and there are no
         * commands in the pending queue
         */
-       while( atomic_read(&adapter->pend_cmds) > 0 ||
-                       !list_empty(&adapter->pending_list) ) {
-
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1*HZ );        /* sleep for 1s */
-       }
+       while (atomic_read(&adapter->pend_cmds) > 0 ||
+              !list_empty(&adapter->pending_list))
+               msleep(1000);   /* sleep for 1s */
 
        rval = mega_do_del_logdrv(adapter, logdrv);
 
@@ -4610,6 +4609,41 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
        pci_bus = pdev->bus->number;
        pci_dev_func = pdev->devfn;
+       
+       if(pdev->vendor == PCI_VENDOR_ID_INTEL)         /* The megaraid3 stuff reports the id of the intel
+                                                          part which is not remotely specific to the megaraid */
+       {
+               u16 magic;
+               /* Don't fall over the Compaq management cards using the same PCI identifier */
+               if(pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ &&
+                  pdev->subsystem_device == 0xC000)
+                       return -ENODEV;
+               /* Now check the magic signature byte */
+               pci_read_config_word(pdev, PCI_CONF_AMISIG, &magic);
+               if(magic != HBA_SIGNATURE_471 && magic != HBA_SIGNATURE)
+                       return -ENODEV;
+               /* Ok it is probably a megaraid */
+       }
+
+       /*
+        * The megaraid3 stuff reports the ID of the Intel part which is not
+        * remotely specific to the megaraid
+        */
+       if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
+               u16 magic;
+               /*
+                * Don't fall over the Compaq management cards using the same
+                * PCI identifier
+                */
+               if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ &&
+                   pdev->subsystem_device == 0xC000)
+                       return -ENODEV;
+               /* Now check the magic signature byte */
+               pci_read_config_word(pdev, PCI_CONF_AMISIG, &magic);
+               if (magic != HBA_SIGNATURE_471 && magic != HBA_SIGNATURE)
+                       return -ENODEV;
+               /* Ok it is probably a megaraid */
+       }
 
        /*
         * For these vendor and device ids, signature offsets are not
index caa4034..9d0cab9 100644 (file)
@@ -154,8 +154,8 @@ static int modes_defined = FALSE;
 static OSST_buffer *new_tape_buffer(int, int, int);
 static int enlarge_buffer(OSST_buffer *, int);
 static void normalize_buffer(OSST_buffer *);
-static int append_to_buffer(const char *, OSST_buffer *, int);
-static int from_buffer(OSST_buffer *, char *, int);
+static int append_to_buffer(const char __user *, OSST_buffer *, int);
+static int from_buffer(OSST_buffer *, char __user *, int);
 static int osst_zero_buffer_tail(OSST_buffer *);
 static int osst_copy_to_buffer(OSST_buffer *, unsigned char *);
 static int osst_copy_from_buffer(OSST_buffer *, unsigned char *);
@@ -3157,13 +3157,13 @@ static void reset_state(OS_Scsi_Tape *STp)
 /* Entry points to osst */
 
 /* Write command */
-static ssize_t osst_write(struct file * filp, const char * buf, size_t count, loff_t *ppos)
+static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
 {
        ssize_t        total, retval = 0;
        ssize_t        i, do_count, blks, transfer;
        int            write_threshold;
        int            doing_write = 0;
-       const char   * b_point;
+       const char   __user * b_point;
        Scsi_Request * SRpnt = NULL;
        ST_mode      * STm;
        ST_partstat  * STps;
@@ -3486,7 +3486,7 @@ out:
 
 
 /* Read command */
-static ssize_t osst_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
+static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
 {
        ssize_t        total, retval = 0;
        ssize_t        i, transfer;
@@ -5189,7 +5189,7 @@ static void normalize_buffer(OSST_buffer *STbuffer)
 
 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
    negative error code. */
-static int append_to_buffer(const char *ubp, OSST_buffer *st_bp, int do_count)
+static int append_to_buffer(const char __user *ubp, OSST_buffer *st_bp, int do_count)
 {
        int i, cnt, res, offset;
 
@@ -5222,7 +5222,7 @@ static int append_to_buffer(const char *ubp, OSST_buffer *st_bp, int do_count)
 
 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
    negative error code. */
-static int from_buffer(OSST_buffer *st_bp, char *ubp, int do_count)
+static int from_buffer(OSST_buffer *st_bp, char __user *ubp, int do_count)
 {
        int i, cnt, res, offset;
 
index f38faab..363d793 100644 (file)
@@ -46,7 +46,7 @@
 #include <asm/irq.h>
 
 #include <../drivers/scsi/scsi.h>
-#include <../drivers/scsi/hosts.h>
+#include <scsi/scsi_host.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_ioctl.h>
@@ -1936,10 +1936,10 @@ static void nsp_cs_config(dev_link_t *link)
        nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
 
        for (dev = host->host_queue; dev != NULL; dev = dev->next) {
-               unsigned long arg[2], id;
-               kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
-               id = (arg[0] & 0x0f) + ((arg[0] >> 4) & 0xf0) +
-                       ((arg[0] >> 8) & 0xf00) + ((arg[0] >> 12) & 0xf000);
+               unsigned long id;
+               id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) +
+                       ((dev->channel & 0x0f) << 8) +
+                       ((dev->host->host_no & 0x0f) << 12);
                node = &info->node[info->ndev];
                node->minor = 0;
                switch (dev->type) {
index f5a16ab..ae98131 100644 (file)
@@ -3119,6 +3119,7 @@ qla1280_marker(struct scsi_qla_host *ha, int bus, int id, int lun, u8 type)
  * Returns:
  *      0 = success, was able to issue command.
  */
+#ifdef QLA_64BIT_PTR
 static int
 qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
 {
@@ -3381,9 +3382,8 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
 
        return status;
 }
+#else /* !QLA_64BIT_PTR */
 
-
-#ifndef QLA_64BIT_PTR
 /*
  * qla1280_32bit_start_scsi
  *      The start SCSI is responsible for building request packets on
index a13200d..ef1fdfd 100644 (file)
 
 #define DEFAULT_LOOP_COUNT     1000000000
 
+#define ISP_TIMEOUT (2*HZ)
 /* End Configuration section ************************************************ */
 
 #include <linux/module.h>
@@ -1305,7 +1306,7 @@ int isp2x00_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *))
                cmd->control_flags = cpu_to_le16(CFLAG_READ);
 
        if (Cmnd->device->tagged_supported) {
-               if ((jiffies - hostdata->tag_ages[Cmnd->device->id]) > (2 * SCSI_TIMEOUT)) {
+               if ((jiffies - hostdata->tag_ages[Cmnd->device->id]) > (2 * ISP_TIMEOUT)) {
                        cmd->control_flags |= cpu_to_le16(CFLAG_ORDERED_TAG);
                        hostdata->tag_ages[Cmnd->device->id] = jiffies;
                } else
index 29522c4..c49ca7f 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 
 #include <asm/byteorder.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include <linux/module.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_request.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_host.h>
+
+
 
 #define MAX_TARGETS    16
 #define MAX_LUNS       8       /* 32 for 1.31 F/W */
index 91dead6..a40ff75 100644 (file)
@@ -6,19 +6,6 @@
 #ifndef _QLOGICPTI_H
 #define _QLOGICPTI_H
 
-#include <linux/config.h>
-
-/* #include "scsi.h" */
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_eh.h>
-#include <scsi/scsi_request.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_host.h>
-
-#define scsi_to_sbus_dma_dir(scsi_dir) ((int)(scsi_dir))
-
 /* Qlogic/SBUS controller registers. */
 #define SBUS_CFG1      0x006UL
 #define SBUS_CTRL      0x008UL
@@ -343,6 +330,8 @@ struct pti_queue_entry {
        char __opaque[QUEUE_ENTRY_LEN];
 };
 
+struct scsi_cmnd;
+
 /* Software state for the driver. */
 struct qlogicpti {
        /* These are the hot elements in the cache, so they come first. */
index fd5c8a3..cb6b5fb 100644 (file)
  *       add scatter-gather, multiple outstanding request, and other
  *       enhancements.
  */
+/*
+ * NOTE:  this file only contains compatibility glue for old drivers.  All
+ * these wrappers will be removed sooner or later.  For new code please use
+ * the interfaces declared in the headers in include/scsi/
+ */
 
 #ifndef _SCSI_H
 #define _SCSI_H
@@ -18,6 +23,7 @@
 #include <linux/config.h>          /* for CONFIG_SCSI_LOGGING */
 
 #include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_request.h>
 #define FALSE 0
 #endif
 
-#ifdef DEBUG
-#define SCSI_TIMEOUT (5*HZ)
-#else
-#define SCSI_TIMEOUT (2*HZ)
-#endif
-
 struct Scsi_Host;
 struct scsi_cmnd;
 struct scsi_device;
 struct scsi_target;
 struct scatterlist;
 
-/*
- * Prototypes for functions in constants.c
- * Some of these used to live in constants.h
- */
-extern void print_Scsi_Cmnd(struct scsi_cmnd *);
-extern void print_command(unsigned char *);
-extern void print_sense(const char *, struct scsi_cmnd *);
-extern void print_req_sense(const char *, struct scsi_request *);
-extern void print_driverbyte(int scsiresult);
-extern void print_hostbyte(int scsiresult);
-extern void print_status(unsigned char status);
-extern int print_msg(const unsigned char *);
-extern const char *scsi_sense_key_string(unsigned char);
-extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
-
 /*
  * Legacy dma direction interfaces.
  *
@@ -76,6 +61,42 @@ extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
 #define scsi_to_pci_dma_dir(scsi_dir)  ((int)(scsi_dir))
 #define scsi_to_sbus_dma_dir(scsi_dir) ((int)(scsi_dir))
 
+/*
+ * Old names for debug prettyprinting functions.
+ */
+static inline void print_Scsi_Cmnd(struct scsi_cmnd *cmd)
+{
+       return scsi_print_command(cmd);
+}
+static inline void print_command(unsigned char *cdb)
+{
+       return __scsi_print_command(cdb);
+}
+static inline void print_sense(const char *devclass, struct scsi_cmnd *cmd)
+{
+       return scsi_print_sense(devclass, cmd);
+}
+static inline void print_req_sense(const char *devclass, struct scsi_request *req)
+{
+       return scsi_print_req_sense(devclass, req);
+}
+static inline void print_driverbyte(int scsiresult)
+{
+       return scsi_print_driverbyte(scsiresult);
+}
+static inline void print_hostbyte(int scsiresult)
+{
+       return scsi_print_hostbyte(scsiresult);
+}
+static inline void print_status(unsigned char status)
+{
+       return scsi_print_status(status);
+}
+static inline int print_msg(const unsigned char *msg)
+{
+       return scsi_print_msg(msg);
+}
+
 /*
  * This is the crap from the old error handling code.  We have it in a special
  * place so that we can more easily delete it later on.
index 3e7e2cb..d291d68 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  *  linux/kernel/scsi_debug.c
  * vvvvvvvvvvvvvvvvvvvvvvv Original vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  *  Copyright (C) 1992  Eric Youngdale
@@ -7,9 +7,9 @@
  *  anything out of the ordinary is seen.
  * ^^^^^^^^^^^^^^^^^^^^^^^ Original ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  *
- *  This version is more generic, simulating a variable number of disk 
- *  (or disk like devices) sharing a common amount of RAM 
- *  
+ *  This version is more generic, simulating a variable number of disk
+ *  (or disk like devices) sharing a common amount of RAM
+ *
  *
  *  For documentation see http://www.torque.net/sg/sdebug25.html
  *
@@ -55,7 +55,8 @@
 #include "scsi_logging.h"
 #include "scsi_debug.h"
 
-static const char * scsi_debug_version_str = "Version: 1.71 (20031007)";
+#define SCSI_DEBUG_VERSION "1.73"
+static const char * scsi_debug_version_date = "20040518";
 
 /* Additional Sense Code (ASC) used */
 #define NO_ADDED_SENSE 0x0
@@ -76,11 +77,13 @@ static const char * scsi_debug_version_str = "Version: 1.71 (20031007)";
 /* With these defaults, this driver will make 1 host with 1 target
  * (id 0) containing 1 logical unit (lun 0). That is 1 device.
  */
+#define DEF_DELAY   1
 #define DEF_DEV_SIZE_MB   8
 #define DEF_EVERY_NTH   0
-#define DEF_DELAY   1
-#define DEF_SCSI_LEVEL   3
+#define DEF_NUM_PARTS   0
 #define DEF_OPTS   0
+#define DEF_SCSI_LEVEL   3
+#define DEF_PTYPE   0
 
 /* bit mask values for scsi_debug_opts */
 #define SCSI_DEBUG_OPT_NOISE   1
@@ -101,19 +104,21 @@ static const char * scsi_debug_version_str = "Version: 1.71 (20031007)";
  * or "peripheral device" addressing (value 0) */
 #define SAM2_LUN_ADDRESS_METHOD 0
 
+static int scsi_debug_add_host = DEF_NUM_HOST;
+static int scsi_debug_delay = DEF_DELAY;
 static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB;
-static int scsi_debug_num_tgts = DEF_NUM_TGTS; /* targets per host */
-static int scsi_debug_opts = DEF_OPTS;
 static int scsi_debug_every_nth = DEF_EVERY_NTH;
-static int scsi_debug_cmnd_count = 0;
-static int scsi_debug_delay = DEF_DELAY;
 static int scsi_debug_max_luns = DEF_MAX_LUNS;
+static int scsi_debug_num_parts = DEF_NUM_PARTS;
+static int scsi_debug_num_tgts = DEF_NUM_TGTS; /* targets per host */
+static int scsi_debug_opts = DEF_OPTS;
 static int scsi_debug_scsi_level = DEF_SCSI_LEVEL;
-static int scsi_debug_add_host = DEF_NUM_HOST;
+static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */
+
+static int scsi_debug_cmnd_count = 0;
 
 #define DEV_READONLY(TGT)      (0)
 #define DEV_REMOVEABLE(TGT)    (0)
-#define PERIPH_DEVICE_TYPE(TGT) (TYPE_DISK);
 
 static unsigned long sdebug_store_size;        /* in bytes */
 static sector_t sdebug_capacity;       /* in sectors */
@@ -129,6 +134,8 @@ static int sdebug_sectors_per;              /* sectors per cylinder */
 #define SECT_SIZE (1 << POW2_SECT_SIZE)
 #define SECT_SIZE_PER(TGT) SECT_SIZE
 
+#define SDEBUG_MAX_PARTS 4
+
 #define SDEBUG_SENSE_LEN 32
 
 struct sdebug_dev_info {
@@ -215,7 +222,7 @@ static struct device_driver sdebug_driverfs_driver = {
        .remove         = sdebug_driver_remove,
 };
 
-static const int check_condition_result = 
+static const int check_condition_result =
                (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
 
 /* function declarations */
@@ -224,7 +231,7 @@ static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff,
 static int resp_mode_sense(unsigned char * cmd, int target,
                           unsigned char * buff, int bufflen,
                           struct sdebug_dev_info * devip);
-static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, 
+static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
                     int num, struct sdebug_dev_info * devip);
 static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block,
                      int num, struct sdebug_dev_info * devip);
@@ -232,14 +239,15 @@ static int resp_report_luns(unsigned char * cmd, unsigned char * buff,
                            int bufflen, struct sdebug_dev_info * devip);
 static void timer_intr_handler(unsigned long);
 static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev);
-static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, 
+static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
                            int asc, int asq, int inbandLen);
-static int check_reset(struct scsi_cmnd * SCpnt, 
+static int check_reset(struct scsi_cmnd * SCpnt,
                       struct sdebug_dev_info * devip);
-static int schedule_resp(struct scsi_cmnd * cmnd, 
-                        struct sdebug_dev_info * devip, 
+static int schedule_resp(struct scsi_cmnd * cmnd,
+                        struct sdebug_dev_info * devip,
                         done_funct_t done, int scsi_result, int delta_jiff);
-static void init_all_queued(void);
+static void __init sdebug_build_parts(unsigned char * ramp);
+static void __init init_all_queued(void);
 static void stop_all_queued(void);
 static int stop_queued_cmnd(struct scsi_cmnd * cmnd);
 static int inquiry_evpd_83(unsigned char * arr, int dev_id_num,
@@ -249,6 +257,8 @@ static void do_remove_driverfs_files(void);
 
 static int sdebug_add_adapter(void);
 static void sdebug_remove_adapter(void);
+static void sdebug_max_tgts_luns(void);
+
 static struct device pseudo_primary;
 static struct bus_type pseudo_lld_bus;
 
@@ -257,7 +267,7 @@ static unsigned char * scatg2virt(const struct scatterlist * sclp)
        if (NULL == sclp)
                return NULL;
        else if (sclp->page)
-               return (unsigned char *)page_address(sclp->page) + 
+               return (unsigned char *)page_address(sclp->page) +
                       sclp->offset;
        else
                return NULL;
@@ -288,7 +298,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
                bufflen = sgpnt[0].length;
                /* READ and WRITE process scatterlist themselves */
        }
-       else 
+       else
                buff = (unsigned char *) SCpnt->request_buffer;
        if (NULL == buff) {
                buff = spare_buff;      /* assume cmd moves no data */
@@ -304,11 +314,11 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
         }
 
        if (SCpnt->device->lun >= scsi_debug_max_luns)
-               return schedule_resp(SCpnt, NULL, done, 
+               return schedule_resp(SCpnt, NULL, done,
                                     DID_NO_CONNECT << 16, 0);
        devip = devInfoReg(SCpnt->device);
        if (NULL == devip)
-               return schedule_resp(SCpnt, NULL, done, 
+               return schedule_resp(SCpnt, NULL, done,
                                     DID_NO_CONNECT << 16, 0);
 
         if ((scsi_debug_every_nth > 0) &&
@@ -331,7 +341,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
                 * shouldn't need to call REQUEST_SENSE */
                if (devip) {
                        sbuff = devip->sense_buff;
-                       memcpy(buff, sbuff, (bufflen < SDEBUG_SENSE_LEN) ? 
+                       memcpy(buff, sbuff, (bufflen < SDEBUG_SENSE_LEN) ?
                                             bufflen : SDEBUG_SENSE_LEN);
                        mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0, 7);
                } else {
@@ -392,29 +402,29 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
                        break;
                upper_blk = 0;
                if ((*cmd) == READ_16) {
-                       upper_blk = cmd[5] + (cmd[4] << 8) + 
+                       upper_blk = cmd[5] + (cmd[4] << 8) +
                                    (cmd[3] << 16) + (cmd[2] << 24);
-                       block = cmd[9] + (cmd[8] << 8) + 
+                       block = cmd[9] + (cmd[8] << 8) +
                                (cmd[7] << 16) + (cmd[6] << 24);
-                       num = cmd[13] + (cmd[12] << 8) + 
+                       num = cmd[13] + (cmd[12] << 8) +
                                (cmd[11] << 16) + (cmd[10] << 24);
                } else if ((*cmd) == READ_12) {
-                       block = cmd[5] + (cmd[4] << 8) + 
+                       block = cmd[5] + (cmd[4] << 8) +
                                (cmd[3] << 16) + (cmd[2] << 24);
-                       num = cmd[9] + (cmd[8] << 8) + 
+                       num = cmd[9] + (cmd[8] << 8) +
                                (cmd[7] << 16) + (cmd[6] << 24);
                } else if ((*cmd) == READ_10) {
-                       block = cmd[5] + (cmd[4] << 8) + 
+                       block = cmd[5] + (cmd[4] << 8) +
                                (cmd[3] << 16) + (cmd[2] << 24);
                        num = cmd[8] + (cmd[7] << 8);
                } else {
-                       block = cmd[3] + (cmd[2] << 8) + 
+                       block = cmd[3] + (cmd[2] << 8) +
                                ((cmd[1] & 0x1f) << 16);
                        num = cmd[4];
                }
                errsts = resp_read(SCpnt, upper_blk, block, num, devip);
                if (inj_recovered && (0 == errsts)) {
-                       mk_sense_buffer(devip, RECOVERED_ERROR, 
+                       mk_sense_buffer(devip, RECOVERED_ERROR,
                                        THRESHHOLD_EXCEEDED, 0, 18);
                        errsts = check_condition_result;
                }
@@ -430,29 +440,29 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
                        break;
                upper_blk = 0;
                if ((*cmd) == WRITE_16) {
-                       upper_blk = cmd[5] + (cmd[4] << 8) + 
+                       upper_blk = cmd[5] + (cmd[4] << 8) +
                                    (cmd[3] << 16) + (cmd[2] << 24);
-                       block = cmd[9] + (cmd[8] << 8) + 
+                       block = cmd[9] + (cmd[8] << 8) +
                                (cmd[7] << 16) + (cmd[6] << 24);
-                       num = cmd[13] + (cmd[12] << 8) + 
+                       num = cmd[13] + (cmd[12] << 8) +
                                (cmd[11] << 16) + (cmd[10] << 24);
                } else if ((*cmd) == WRITE_12) {
-                       block = cmd[5] + (cmd[4] << 8) + 
+                       block = cmd[5] + (cmd[4] << 8) +
                                (cmd[3] << 16) + (cmd[2] << 24);
-                       num = cmd[9] + (cmd[8] << 8) + 
+                       num = cmd[9] + (cmd[8] << 8) +
                                (cmd[7] << 16) + (cmd[6] << 24);
                } else if ((*cmd) == WRITE_10) {
-                       block = cmd[5] + (cmd[4] << 8) + 
+                       block = cmd[5] + (cmd[4] << 8) +
                                (cmd[3] << 16) + (cmd[2] << 24);
                        num = cmd[8] + (cmd[7] << 8);
                } else {
-                       block = cmd[3] + (cmd[2] << 8) + 
+                       block = cmd[3] + (cmd[2] << 8) +
                                ((cmd[1] & 0x1f) << 16);
                        num = cmd[4];
                }
                errsts = resp_write(SCpnt, upper_blk, block, num, devip);
                if (inj_recovered && (0 == errsts)) {
-                       mk_sense_buffer(devip, RECOVERED_ERROR, 
+                       mk_sense_buffer(devip, RECOVERED_ERROR,
                                        THRESHHOLD_EXCEEDED, 0, 18);
                        errsts = check_condition_result;
                }
@@ -500,7 +510,7 @@ static const char * vendor_id = "Linux   ";
 static const char * product_id = "scsi_debug      ";
 static const char * product_rev = "0004";
 
-static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, 
+static int inquiry_evpd_83(unsigned char * arr, int dev_id_num,
                           const char * dev_id_str, int dev_id_str_len)
 {
        int num;
@@ -537,7 +547,7 @@ static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff,
 {
        unsigned char pq_pdt;
        unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ];
-       int min_len = bufflen > SDEBUG_MAX_INQ_ARR_SZ ? 
+       int min_len = bufflen > SDEBUG_MAX_INQ_ARR_SZ ?
                        SDEBUG_MAX_INQ_ARR_SZ : bufflen;
 
        if (bufflen < cmd[4])
@@ -545,7 +555,7 @@ static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff,
                       "< alloc_length=%d\n", bufflen, (int)cmd[4]);
        memset(buff, 0, bufflen);
        memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ);
-       pq_pdt = PERIPH_DEVICE_TYPE(target);
+       pq_pdt = (scsi_debug_ptype & 0x1f);
        arr[0] = pq_pdt;
        if (0x2 & cmd[1]) {  /* CMDDT bit set */
                mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
@@ -573,11 +583,11 @@ static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff,
                                                 dev_id_str, len);
                } else {
                        /* Illegal request, invalid field in cdb */
-                       mk_sense_buffer(devip, ILLEGAL_REQUEST, 
+                       mk_sense_buffer(devip, ILLEGAL_REQUEST,
                                        INVALID_FIELD_IN_CDB, 0, 18);
                        return check_condition_result;
                }
-               memcpy(buff, arr, min_len); 
+               memcpy(buff, arr, min_len);
                return 0;
        }
        /* drops through here for a standard inquiry */
@@ -592,11 +602,11 @@ static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff,
        return 0;
 }
 
-/* <<Following mode page info copied from ST318451LW>> */ 
+/* <<Following mode page info copied from ST318451LW>> */
 
 static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target)
 {      /* Read-Write Error Recovery page for mode_sense */
-       unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0, 
+       unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
                                        5, 0, 0xff, 0xff};
 
        memcpy(p, err_recov_pg, sizeof(err_recov_pg));
@@ -607,7 +617,7 @@ static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target)
 
 static int resp_disconnect_pg(unsigned char * p, int pcontrol, int target)
 {      /* Disconnect-Reconnect page for mode_sense */
-       unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0, 
+       unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
                                         0, 0, 0, 0, 0, 0, 0, 0};
 
        memcpy(p, disconnect_pg, sizeof(disconnect_pg));
@@ -636,7 +646,7 @@ static int resp_format_pg(unsigned char * p, int pcontrol, int target)
 
 static int resp_caching_pg(unsigned char * p, int pcontrol, int target)
 {      /* Caching page for mode_sense */
-       unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0, 
+       unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0,
                0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0,     0, 0, 0, 0};
 
        memcpy(p, caching_pg, sizeof(caching_pg));
@@ -678,7 +688,7 @@ static int resp_mode_sense(unsigned char * cmd, int target,
        int alloc_len, msense_6, offset, len;
        unsigned char * ap;
        unsigned char arr[SDEBUG_MAX_MSENSE_SZ];
-       int min_len = bufflen > SDEBUG_MAX_MSENSE_SZ ? 
+       int min_len = bufflen > SDEBUG_MAX_MSENSE_SZ ?
                        SDEBUG_MAX_MSENSE_SZ : bufflen;
 
        SCSI_LOG_LLQUEUE(3, printk("Mode sense ...(%p %d)\n", buff, bufflen));
@@ -753,14 +763,14 @@ static int resp_mode_sense(unsigned char * cmd, int target,
                arr[0] = offset - 1;
        else {
                offset -= 2;
-               arr[0] = (offset >> 8) & 0xff; 
-               arr[1] = offset & 0xff; 
+               arr[0] = (offset >> 8) & 0xff;
+               arr[1] = offset & 0xff;
        }
        memcpy(buff, arr, min_len);
        return 0;
 }
 
-static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, 
+static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
                     int num, struct sdebug_dev_info * devip)
 {
         unsigned char *buff = (unsigned char *) SCpnt->request_buffer;
@@ -770,14 +780,14 @@ static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
        unsigned long iflags;
 
        if (upper_blk || (block + num > sdebug_capacity)) {
-               mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, 
+               mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE,
                                0, 18);
                return check_condition_result;
        }
        if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) &&
-           (block <= OPT_MEDIUM_ERR_ADDR) && 
+           (block <= OPT_MEDIUM_ERR_ADDR) &&
            ((block + num) > OPT_MEDIUM_ERR_ADDR)) {
-               mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 
+               mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR,
                                0, 18);
                /* claim unrecoverable read error */
                return check_condition_result;
@@ -785,7 +795,7 @@ static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
        read_lock_irqsave(&atomic_rw, iflags);
         sgcount = 0;
        nbytes = bufflen;
-       /* printk(KERN_INFO "scsi_debug_read: block=%d, tot_bufflen=%d\n", 
+       /* printk(KERN_INFO "scsi_debug_read: block=%d, tot_bufflen=%d\n",
               block, bufflen); */
        if (SCpnt->use_sg) {
                sgcount = 0;
@@ -857,7 +867,7 @@ static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block,
 static int resp_report_luns(unsigned char * cmd, unsigned char * buff,
                            int bufflen, struct sdebug_dev_info * devip)
 {
-       unsigned int alloc_len; 
+       unsigned int alloc_len;
        int lun_cnt, i, upper;
        int select_report = (int)cmd[2];
        struct scsi_lun *one_lun;
@@ -868,19 +878,19 @@ static int resp_report_luns(unsigned char * cmd, unsigned char * buff,
                                0, 18);
                return check_condition_result;
        }
-       if (bufflen > 8) { /* can produce response with up to 16k luns 
+       if (bufflen > 8) { /* can produce response with up to 16k luns
                              (lun 0 to lun 16383) */
                memset(buff, 0, bufflen);
                lun_cnt = scsi_debug_max_luns;
                buff[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff;
                buff[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff;
-               lun_cnt = min((int)((bufflen - 8) / sizeof(struct scsi_lun)), 
+               lun_cnt = min((int)((bufflen - 8) / sizeof(struct scsi_lun)),
                              lun_cnt);
                one_lun = (struct scsi_lun *) &buff[8];
                for (i = 0; i < lun_cnt; i++) {
                        upper = (i >> 8) & 0x3f;
                        if (upper)
-                               one_lun[i].scsi_lun[0] = 
+                               one_lun[i].scsi_lun[0] =
                                    (upper | (SAM2_LUN_ADDRESS_METHOD << 6));
                        one_lun[i].scsi_lun[1] = i & 0xff;
                }
@@ -926,7 +936,7 @@ static int scsi_debug_slave_alloc(struct scsi_device * sdp)
 
 static int scsi_debug_slave_configure(struct scsi_device * sdp)
 {
-       struct sdebug_dev_info * devip; 
+       struct sdebug_dev_info * devip;
 
        if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
                printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n",
@@ -936,14 +946,14 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp)
        devip = devInfoReg(sdp);
        sdp->hostdata = devip;
        if (sdp->host->cmd_per_lun)
-               scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, 
+               scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING,
                                        sdp->host->cmd_per_lun);
        return 0;
 }
 
 static void scsi_debug_slave_destroy(struct scsi_device * sdp)
 {
-       struct sdebug_dev_info * devip = 
+       struct sdebug_dev_info * devip =
                                (struct sdebug_dev_info *)sdp->hostdata;
 
        if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
@@ -980,6 +990,18 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
                                open_devip = devip;
                }
        }
+       if (NULL == open_devip) { /* try and make a new one */
+               open_devip = kmalloc(sizeof(*open_devip),GFP_KERNEL);
+               if (NULL == open_devip) {
+                       printk(KERN_ERR "%s: out of memory at line %d\n",
+                               __FUNCTION__, __LINE__);
+                       return NULL;
+               }
+               memset(open_devip, 0, sizeof(*open_devip));
+               open_devip->sdbg_host = sdbg_host;
+               list_add_tail(&open_devip->dev_list,
+               &sdbg_host->dev_info_list);
+       }
         if (open_devip) {
                open_devip->channel = sdev->channel;
                open_devip->target = sdev->id;
@@ -994,7 +1016,7 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
         return NULL;
 }
 
-static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, 
+static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
                            int asc, int asq, int inbandLen)
 {
        unsigned char * sbuff;
@@ -1029,7 +1051,7 @@ static int scsi_debug_biosparam(struct scsi_device *sdev,
                printk(KERN_INFO "scsi_debug: biosparam\n");
        buf = scsi_bios_ptable(bdev);
        if (buf) {
-               res = scsi_partsize(buf, capacity, 
+               res = scsi_partsize(buf, capacity,
                                    &info[2], &info[0], &info[1]);
                kfree(buf);
                if (! res)
@@ -1138,7 +1160,7 @@ static void stop_all_queued(void)
 }
 
 /* Initializes timers in queued array */
-static void init_all_queued(void)
+static void __init init_all_queued(void)
 {
        unsigned long iflags;
        int k;
@@ -1154,11 +1176,61 @@ static void init_all_queued(void)
        spin_unlock_irqrestore(&queued_arr_lock, iflags);
 }
 
-static int schedule_resp(struct scsi_cmnd * cmnd, 
+static void __init sdebug_build_parts(unsigned char * ramp)
+{
+       struct partition * pp;
+       int starts[SDEBUG_MAX_PARTS + 2];
+       int sectors_per_part, num_sectors, k;
+       int heads_by_sects, start_sec, end_sec;
+
+       /* assume partition table already zeroed */
+       if ((scsi_debug_num_parts < 1) || (sdebug_store_size < 1048576))
+               return;
+       if (scsi_debug_num_parts > SDEBUG_MAX_PARTS) {
+               scsi_debug_num_parts = SDEBUG_MAX_PARTS;
+               printk(KERN_WARNING "scsi_debug:build_parts: reducing "
+                                   "partitions to %d\n", SDEBUG_MAX_PARTS);
+       }
+       num_sectors = (int)(sdebug_store_size / SECT_SIZE);
+       sectors_per_part = (num_sectors - sdebug_sectors_per)
+                          / scsi_debug_num_parts;
+       heads_by_sects = sdebug_heads * sdebug_sectors_per;
+        starts[0] = sdebug_sectors_per;
+       for (k = 1; k < scsi_debug_num_parts; ++k)
+               starts[k] = ((k * sectors_per_part) / heads_by_sects)
+                           * heads_by_sects;
+       starts[scsi_debug_num_parts] = num_sectors;
+       starts[scsi_debug_num_parts + 1] = 0;
+
+       ramp[510] = 0x55;       /* magic partition markings */
+       ramp[511] = 0xAA;
+       pp = (struct partition *)(ramp + 0x1be);
+       for (k = 0; starts[k + 1]; ++k, ++pp) {
+               start_sec = starts[k];
+               end_sec = starts[k + 1] - 1;
+               pp->boot_ind = 0;
+
+               pp->cyl = start_sec / heads_by_sects;
+               pp->head = (start_sec - (pp->cyl * heads_by_sects))
+                          / sdebug_sectors_per;
+               pp->sector = (start_sec % sdebug_sectors_per) + 1;
+
+               pp->end_cyl = end_sec / heads_by_sects;
+               pp->end_head = (end_sec - (pp->end_cyl * heads_by_sects))
+                              / sdebug_sectors_per;
+               pp->end_sector = (end_sec % sdebug_sectors_per) + 1;
+
+               pp->start_sect = start_sec;
+               pp->nr_sects = end_sec - start_sec + 1;
+               pp->sys_ind = 0x83;     /* plain Linux partition */
+       }
+}
+
+static int schedule_resp(struct scsi_cmnd * cmnd,
                         struct sdebug_dev_info * devip,
                         done_funct_t done, int scsi_result, int delta_jiff)
 {
-       int k, num; 
+       int k, num;
 
        if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmnd) {
                printk(KERN_INFO "scsi_debug: cmd ");
@@ -1176,7 +1248,7 @@ static int schedule_resp(struct scsi_cmnd * cmnd,
        if (cmnd && devip) {
                /* simulate autosense by this driver */
                if (SAM_STAT_CHECK_CONDITION == (scsi_result & 0xff))
-                       memcpy(cmnd->sense_buffer, devip->sense_buff, 
+                       memcpy(cmnd->sense_buffer, devip->sense_buff,
                               (SCSI_SENSE_BUFFERSIZE > SDEBUG_SENSE_LEN) ?
                               SDEBUG_SENSE_LEN : SCSI_SENSE_BUFFERSIZE);
        }
@@ -1219,38 +1291,43 @@ static int schedule_resp(struct scsi_cmnd * cmnd,
 
 /* Set 'perm' (4th argument) to 0 to disable module_param's definition
  * of sysfs parameters (which module_param doesn't yet support).
- * Sysfs parameters defined explicitly below. 
+ * Sysfs parameters defined explicitly below.
  */
-module_param_named(num_tgts, scsi_debug_num_tgts, int, 0);
-module_param_named(max_luns, scsi_debug_max_luns, int, 0);
-module_param_named(scsi_level, scsi_debug_scsi_level, int, 0);
+module_param_named(add_host, scsi_debug_add_host, int, 0); /* perm=0644 */
+module_param_named(delay, scsi_debug_delay, int, 0); /* perm=0644 */
 module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, 0);
-module_param_named(opts, scsi_debug_opts, int, 0); /* perm=0644 */
 module_param_named(every_nth, scsi_debug_every_nth, int, 0);
-module_param_named(delay, scsi_debug_delay, int, 0); /* perm=0644 */
-module_param_named(add_host, scsi_debug_add_host, int, 0); /* perm=0644 */
+module_param_named(max_luns, scsi_debug_max_luns, int, 0);
+module_param_named(num_parts, scsi_debug_num_parts, int, 0);
+module_param_named(num_tgts, scsi_debug_num_tgts, int, 0);
+module_param_named(opts, scsi_debug_opts, int, 0); /* perm=0644 */
+module_param_named(ptype, scsi_debug_ptype, int, 0);
+module_param_named(scsi_level, scsi_debug_scsi_level, int, 0);
 
 MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert");
 MODULE_DESCRIPTION("SCSI debug adapter driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(SCSI_DEBUG_VERSION);
 
-MODULE_PARM_DESC(num_tgts, "number of SCSI targets per host to simulate");
-MODULE_PARM_DESC(max_luns, "number of SCSI LUNs per target to simulate");
-MODULE_PARM_DESC(scsi_level, "SCSI level to simulate");
+MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)");
+MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)");
 MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs");
-MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->...");
 MODULE_PARM_DESC(every_nth, "timeout every nth command(def=100)");
-MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)");
-MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)");
+MODULE_PARM_DESC(max_luns, "number of SCSI LUNs per target to simulate");
+MODULE_PARM_DESC(num_parts, "number of partitions(def=0)");
+MODULE_PARM_DESC(num_tgts, "number of SCSI targets per host to simulate");
+MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->...");
+MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");
+MODULE_PARM_DESC(scsi_level, "SCSI level to simulate");
 
 
 static char sdebug_info[256];
 
 static const char * scsi_debug_info(struct Scsi_Host * shp)
 {
-       sprintf(sdebug_info, "scsi_debug, %s, num_tgts=%d, "
-               "dev_size_mb=%d, opts=0x%x", scsi_debug_version_str,
-               scsi_debug_num_tgts, scsi_debug_dev_size_mb,
+       sprintf(sdebug_info, "scsi_debug, version %s [%s], "
+               "dev_size_mb=%d, opts=0x%x", SCSI_DEBUG_VERSION,
+               scsi_debug_version_date, scsi_debug_dev_size_mb,
                scsi_debug_opts);
        return sdebug_info;
 }
@@ -1282,14 +1359,15 @@ static int scsi_debug_proc_info(struct Scsi_Host *host, char *buffer, char **sta
                return length;
        }
        begin = 0;
-       pos = len = sprintf(buffer, "scsi_debug adapter driver, %s\n"
+       pos = len = sprintf(buffer, "scsi_debug adapter driver, version "
+           "%s [%s]\n"
            "num_tgts=%d, shared (ram) size=%d MB, opts=0x%x, "
            "every_nth=%d(curr:%d)\n"
            "delay=%d, max_luns=%d, scsi_level=%d\n"
            "sector_size=%d bytes, cylinders=%d, heads=%d, sectors=%d\n"
-           "number of aborts=%d, device_reset=%d, bus_resets=%d, " 
+           "number of aborts=%d, device_reset=%d, bus_resets=%d, "
            "host_resets=%d\n",
-           scsi_debug_version_str, scsi_debug_num_tgts, 
+           SCSI_DEBUG_VERSION, scsi_debug_version_date, scsi_debug_num_tgts,
            scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth,
            scsi_debug_cmnd_count, scsi_debug_delay,
            scsi_debug_max_luns, scsi_debug_scsi_level,
@@ -1306,12 +1384,12 @@ static int scsi_debug_proc_info(struct Scsi_Host *host, char *buffer, char **sta
        return len;
 }
 
-static ssize_t sdebug_delay_show(struct device_driver * ddp, char * buf) 
+static ssize_t sdebug_delay_show(struct device_driver * ddp, char * buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_delay);
 }
 
-static ssize_t sdebug_delay_store(struct device_driver * ddp, 
+static ssize_t sdebug_delay_store(struct device_driver * ddp,
                                  const char * buf, size_t count)
 {
         int delay;
@@ -1325,15 +1403,15 @@ static ssize_t sdebug_delay_store(struct device_driver * ddp,
        }
        return -EINVAL;
 }
-DRIVER_ATTR(delay, S_IRUGO | S_IWUSR, sdebug_delay_show, 
+DRIVER_ATTR(delay, S_IRUGO | S_IWUSR, sdebug_delay_show,
            sdebug_delay_store)
 
-static ssize_t sdebug_opts_show(struct device_driver * ddp, char * buf) 
+static ssize_t sdebug_opts_show(struct device_driver * ddp, char * buf)
 {
         return scnprintf(buf, PAGE_SIZE, "0x%x\n", scsi_debug_opts);
 }
 
-static ssize_t sdebug_opts_store(struct device_driver * ddp, 
+static ssize_t sdebug_opts_store(struct device_driver * ddp,
                                 const char * buf, size_t count)
 {
         int opts;
@@ -1354,38 +1432,62 @@ opts_done:
        scsi_debug_cmnd_count = 0;
        return count;
 }
-DRIVER_ATTR(opts, S_IRUGO | S_IWUSR, sdebug_opts_show, 
+DRIVER_ATTR(opts, S_IRUGO | S_IWUSR, sdebug_opts_show,
            sdebug_opts_store)
 
-static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf) 
+static ssize_t sdebug_ptype_show(struct device_driver * ddp, char * buf)
+{
+        return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_ptype);
+}
+static ssize_t sdebug_ptype_store(struct device_driver * ddp,
+                                 const char * buf, size_t count)
+{
+        int n;
+
+       if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
+               scsi_debug_ptype = n;
+               return count;
+       }
+       return -EINVAL;
+}
+DRIVER_ATTR(ptype, S_IRUGO | S_IWUSR, sdebug_ptype_show, sdebug_ptype_store)
+
+static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_tgts);
 }
-static ssize_t sdebug_num_tgts_store(struct device_driver * ddp, 
+static ssize_t sdebug_num_tgts_store(struct device_driver * ddp,
                                     const char * buf, size_t count)
 {
         int n;
 
        if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
                scsi_debug_num_tgts = n;
+               sdebug_max_tgts_luns();
                return count;
        }
        return -EINVAL;
 }
-DRIVER_ATTR(num_tgts, S_IRUGO | S_IWUSR, sdebug_num_tgts_show, 
-           sdebug_num_tgts_store) 
+DRIVER_ATTR(num_tgts, S_IRUGO | S_IWUSR, sdebug_num_tgts_show,
+           sdebug_num_tgts_store)
 
-static ssize_t sdebug_dev_size_mb_show(struct device_driver * ddp, char * buf) 
+static ssize_t sdebug_dev_size_mb_show(struct device_driver * ddp, char * buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_dev_size_mb);
 }
-DRIVER_ATTR(dev_size_mb, S_IRUGO, sdebug_dev_size_mb_show, NULL) 
+DRIVER_ATTR(dev_size_mb, S_IRUGO, sdebug_dev_size_mb_show, NULL)
+
+static ssize_t sdebug_num_parts_show(struct device_driver * ddp, char * buf)
+{
+        return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_parts);
+}
+DRIVER_ATTR(num_parts, S_IRUGO, sdebug_num_parts_show, NULL)
 
-static ssize_t sdebug_every_nth_show(struct device_driver * ddp, char * buf) 
+static ssize_t sdebug_every_nth_show(struct device_driver * ddp, char * buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_every_nth);
 }
-static ssize_t sdebug_every_nth_store(struct device_driver * ddp, 
+static ssize_t sdebug_every_nth_store(struct device_driver * ddp,
                                      const char * buf, size_t count)
 {
         int nth;
@@ -1398,38 +1500,39 @@ static ssize_t sdebug_every_nth_store(struct device_driver * ddp,
        return -EINVAL;
 }
 DRIVER_ATTR(every_nth, S_IRUGO | S_IWUSR, sdebug_every_nth_show,
-           sdebug_every_nth_store) 
+           sdebug_every_nth_store)
 
-static ssize_t sdebug_max_luns_show(struct device_driver * ddp, char * buf) 
+static ssize_t sdebug_max_luns_show(struct device_driver * ddp, char * buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_max_luns);
 }
-static ssize_t sdebug_max_luns_store(struct device_driver * ddp, 
+static ssize_t sdebug_max_luns_store(struct device_driver * ddp,
                                     const char * buf, size_t count)
 {
         int n;
 
        if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
                scsi_debug_max_luns = n;
+               sdebug_max_tgts_luns();
                return count;
        }
        return -EINVAL;
 }
-DRIVER_ATTR(max_luns, S_IRUGO | S_IWUSR, sdebug_max_luns_show, 
-           sdebug_max_luns_store) 
+DRIVER_ATTR(max_luns, S_IRUGO | S_IWUSR, sdebug_max_luns_show,
+           sdebug_max_luns_store)
 
-static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf) 
+static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_scsi_level);
 }
-DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL) 
+DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL)
 
-static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf) 
+static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf)
 {
         return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host);
 }
 
-static ssize_t sdebug_add_host_store(struct device_driver * ddp, 
+static ssize_t sdebug_add_host_store(struct device_driver * ddp,
                                     const char * buf, size_t count)
 {
         int delta_hosts;
@@ -1461,28 +1564,32 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp,
 DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, 
            sdebug_add_host_store)
 
-static void do_create_driverfs_files()
+static void do_create_driverfs_files(void)
 {
+       driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
        driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
        driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
        driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
        driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
+       driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
+       driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
+       driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype);
+       driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
        driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
 }
 
-static void do_remove_driverfs_files()
+static void do_remove_driverfs_files(void)
 {
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host);
        driver_remove_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
+       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_opts);
+       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ptype);
+       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
+       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
        driver_remove_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
        driver_remove_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
        driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
-       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_opts);
        driver_remove_file(&sdebug_driverfs_driver, &driver_attr_delay);
+       driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host);
 }
 
 static int __init scsi_debug_init(void)
@@ -1491,23 +1598,25 @@ static int __init scsi_debug_init(void)
        int host_to_add;
        int k;
 
+       if (scsi_debug_dev_size_mb < 1)
+               scsi_debug_dev_size_mb = 1;  /* force minimum 1 MB ramdisk */
        sdebug_store_size = (unsigned long)scsi_debug_dev_size_mb * 1048576;
        sdebug_capacity = sdebug_store_size / SECT_SIZE;
 
        /* play around with geometry, don't waste too much on track 0 */
        sdebug_heads = 8;
        sdebug_sectors_per = 32;
-       if (scsi_debug_dev_size_mb >= 16) 
+       if (scsi_debug_dev_size_mb >= 16)
                sdebug_heads = 32;
        else if (scsi_debug_dev_size_mb >= 256)
                sdebug_heads = 64;
-       sdebug_cylinders_per = (unsigned long)sdebug_capacity / 
+       sdebug_cylinders_per = (unsigned long)sdebug_capacity /
                               (sdebug_sectors_per * sdebug_heads);
-       if (sdebug_cylinders_per >= 1024) { 
+       if (sdebug_cylinders_per >= 1024) {
                /* other LLDs do this; implies >= 1GB ram disk ... */
                sdebug_heads = 255;
                sdebug_sectors_per = 63;
-               sdebug_cylinders_per = (unsigned long)sdebug_capacity / 
+               sdebug_cylinders_per = (unsigned long)sdebug_capacity /
                               (sdebug_sectors_per * sdebug_heads);
        }
 
@@ -1518,6 +1627,8 @@ static int __init scsi_debug_init(void)
                return -ENOMEM;
        }
        memset(fake_storep, 0, sz);
+       if (scsi_debug_num_parts > 0)
+               sdebug_build_parts(fake_storep);
 
        init_all_queued();
 
@@ -1575,7 +1686,7 @@ static struct device pseudo_primary = {
        .release        = pseudo_0_release,
 };
 
-static int pseudo_lld_bus_match(struct device *dev, 
+static int pseudo_lld_bus_match(struct device *dev,
                           struct device_driver *dev_driver)
 {
         return 1;
@@ -1594,7 +1705,7 @@ static void sdebug_release_adapter(struct device * dev)
         kfree(sdbg_host);
 }
 
-static int sdebug_add_adapter()
+static int sdebug_add_adapter(void)
 {
        int k, devs_per_host;
         int error = 0;
@@ -1657,7 +1768,7 @@ clean:
         return error;
 }
 
-static void sdebug_remove_adapter()
+static void sdebug_remove_adapter(void)
 {
         struct sdebug_host_info * sdbg_host = NULL;
 
@@ -1737,3 +1848,21 @@ static int sdebug_driver_remove(struct device * dev)
         scsi_host_put(sdbg_host->shost);
         return 0;
 }
+
+static void sdebug_max_tgts_luns(void)
+{
+       struct sdebug_host_info * sdbg_host;
+       struct Scsi_Host *hpnt;
+
+       spin_lock(&sdebug_host_list_lock);
+       list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
+               hpnt = sdbg_host->shost;
+               if ((hpnt->this_id >= 0) &&
+                   (scsi_debug_num_tgts > hpnt->this_id))
+                       hpnt->max_id = scsi_debug_num_tgts + 1;
+               else
+                       hpnt->max_id = scsi_debug_num_tgts;
+               hpnt->max_lun = scsi_debug_max_luns;
+       }
+       spin_unlock(&sdebug_host_list_lock);
+}
index 58f98af..a6c6ec9 100644 (file)
@@ -5,7 +5,7 @@
 static int scsi_debug_slave_alloc(struct scsi_device *);
 static int scsi_debug_slave_configure(struct scsi_device *);
 static void scsi_debug_slave_destroy(struct scsi_device *);
-static int scsi_debug_queuecommand(struct scsi_cmnd *, 
+static int scsi_debug_queuecommand(struct scsi_cmnd *,
                                   void (*done) (struct scsi_cmnd *));
 static int scsi_debug_ioctl(struct scsi_device *, int, void *);
 static int scsi_debug_biosparam(struct scsi_device *, struct block_device *,
@@ -17,9 +17,6 @@ static int scsi_debug_host_reset(struct scsi_cmnd *);
 static int scsi_debug_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 static const char * scsi_debug_info(struct Scsi_Host *);
 
-/*
- * This driver is written for the lk 2.5 series
- */
 #define SCSI_DEBUG_CANQUEUE  255       /* needs to be >= 1 */
 
 #define SCSI_DEBUG_MAX_CMD_LEN 16
index 0dedc42..7bcadb6 100644 (file)
@@ -27,7 +27,7 @@ struct scsi_dev_info_list {
 static const char spaces[] = "                "; /* 16 of them */
 static unsigned scsi_default_dev_flags;
 static LIST_HEAD(scsi_dev_info_list);
-static __init char scsi_dev_flags[256];
+static __initdata char scsi_dev_flags[256];
 
 /*
  * scsi_static_device_list: deprecated list of devices that require
@@ -118,7 +118,7 @@ static struct {
        {"ADAPTEC", "AACRAID", NULL, BLIST_FORCELUN},
        {"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN},
        {"AFT PRO", "-IX CF", "0.0>", BLIST_FORCELUN},
-       {"BELKIN", "USB 2 HS-CF", "1.95",  BLIST_SPARSELUN},
+       {"BELKIN", "USB 2 HS-CF", "1.95",  BLIST_FORCELUN},
        {"CANON", "IPUBJD", NULL, BLIST_SPARSELUN},
        {"CBOX3", "USB Storage-SMC", "300A", BLIST_FORCELUN},
        {"CMD", "CRA-7280", NULL, BLIST_SPARSELUN},     /* CMD RAID Controller */
@@ -142,7 +142,6 @@ static struct {
        {"EMULEX", "MD21/S2     ESDI", NULL, BLIST_SINGLELUN},
        {"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
        {"Generic", "USB SD Reader", "1.00", BLIST_FORCELUN},
-       {"Generic", "USB Storage-SMC", "0090", BLIST_FORCELUN},
        {"Generic", "USB Storage-SMC", "0180", BLIST_FORCELUN},
        {"Generic", "USB Storage-SMC", "0207", BLIST_FORCELUN},
        {"HITACHI", "DF400", "*", BLIST_SPARSELUN},
@@ -155,7 +154,6 @@ static struct {
        {"HP", "C1557A", NULL, BLIST_FORCELUN},
        {"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN},
        {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-       {"ICSI", "SD Card", "2.7C", BLIST_FORCELUN},
        {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
        {"IOMEGA", "Io20S         *F", NULL, BLIST_KEY},
        {"INSITE", "Floptical   F*8I", NULL, BLIST_KEY},
index 05ebb8c..b0b35af 100644 (file)
 #include "scsi_priv.h"
 #include "scsi_logging.h"
 
-#ifdef DEBUG
-#define SENSE_TIMEOUT SCSI_TIMEOUT
-#else
-#define SENSE_TIMEOUT (10*HZ)
-#endif
-
-#define START_UNIT_TIMEOUT (30*HZ)
+#define SENSE_TIMEOUT          (10*HZ)
+#define START_UNIT_TIMEOUT     (30*HZ)
 
 /*
  * These should *probably* be handled by the host itself.
  * Since it is allowed to sleep, it probably should.
  */
-#define BUS_RESET_SETTLE_TIME   10*HZ
-#define HOST_RESET_SETTLE_TIME  10*HZ
+#define BUS_RESET_SETTLE_TIME   (10*HZ)
+#define HOST_RESET_SETTLE_TIME  (10*HZ)
 
 /* called with shost->host_lock held */
 void scsi_eh_wakeup(struct Scsi_Host *shost)
@@ -1026,7 +1021,8 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
        spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
        if (rtn == SUCCESS) {
-               scsi_sleep(BUS_RESET_SETTLE_TIME);
+               if (!scmd->device->host->hostt->skip_settle_delay)
+                       scsi_sleep(BUS_RESET_SETTLE_TIME);
                spin_lock_irqsave(scmd->device->host->host_lock, flags);
                scsi_report_bus_reset(scmd->device->host, scmd->device->channel);
                spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
@@ -1057,7 +1053,8 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
        spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
        if (rtn == SUCCESS) {
-               scsi_sleep(HOST_RESET_SETTLE_TIME);
+               if (!scmd->device->host->hostt->skip_settle_delay)
+                       scsi_sleep(HOST_RESET_SETTLE_TIME);
                spin_lock_irqsave(scmd->device->host->host_lock, flags);
                scsi_report_bus_reset(scmd->device->host, scmd->device->channel);
                spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
index 76f0a64..faab1a0 100644 (file)
@@ -447,19 +447,3 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
        }
        return -EINVAL;
 }
-
-/*
- * Just like scsi_ioctl, only callable from kernel space with no 
- * fs segment fiddling.
- */
-
-int kernel_scsi_ioctl(struct scsi_device *sdev, int cmd, void *arg)
-{
-       mm_segment_t oldfs;
-       int tmp;
-       oldfs = get_fs();
-       set_fs(get_ds());
-       tmp = scsi_ioctl(sdev, cmd, arg);
-       set_fs(oldfs);
-       return tmp;
-}
index f77d2e8..beb5841 100644 (file)
@@ -255,7 +255,6 @@ void scsi_wait_req(struct scsi_request *sreq, const void *cmnd, void *buffer,
        sreq->sr_request->rq_status = RQ_SCSI_BUSY;
        scsi_do_req(sreq, cmnd, buffer, bufflen, scsi_wait_done,
                        timeout, retries);
-       generic_unplug_device(sreq->sr_device->request_queue);
        wait_for_completion(&wait);
        sreq->sr_request->waiting = NULL;
        if (sreq->sr_request->rq_status != RQ_SCSI_DONE)
index 699d274..1f006bf 100644 (file)
 #define ALLOC_FAILURE_MSG      KERN_ERR "%s: Allocation failure during" \
        " SCSI scanning, some SCSI devices might not be configured\n"
 
+/*
+ * Default timeout
+ */
+#define SCSI_TIMEOUT (2*HZ)
+
 /*
  * Prefix values for the SCSI id's (stored in driverfs name field)
  */
index 48126e1..417790d 100644 (file)
@@ -46,15 +46,14 @@ EXPORT_SYMBOL(scsicam_bios_param);
 EXPORT_SYMBOL(scsi_partsize);
 EXPORT_SYMBOL(scsi_bios_ptable);
 EXPORT_SYMBOL(scsi_ioctl);
-EXPORT_SYMBOL(print_command);
-EXPORT_SYMBOL(print_sense);
-EXPORT_SYMBOL(print_req_sense);
-EXPORT_SYMBOL(print_msg);
-EXPORT_SYMBOL(print_status);
+EXPORT_SYMBOL(scsi_print_command);
+EXPORT_SYMBOL(__scsi_print_command);
+EXPORT_SYMBOL(scsi_print_sense);
+EXPORT_SYMBOL(scsi_print_req_sense);
+EXPORT_SYMBOL(scsi_print_msg);
+EXPORT_SYMBOL(scsi_print_status);
 EXPORT_SYMBOL(scsi_sense_key_string);
 EXPORT_SYMBOL(scsi_extd_sense_format);
-EXPORT_SYMBOL(kernel_scsi_ioctl);
-EXPORT_SYMBOL(print_Scsi_Cmnd);
 EXPORT_SYMBOL(scsi_block_when_processing_errors);
 EXPORT_SYMBOL(scsi_ioctl_send_command);
 EXPORT_SYMBOL(scsi_set_medium_removal);
index f2cd32a..3b30baf 100644 (file)
@@ -173,7 +173,7 @@ store_spi_revalidate(struct class_device *cdev, const char *buf, size_t count)
        spi_dv_device(sdev);
        return count;
 }
-static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate)
+static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate);
 
 /* Translate the period into ns according to the current spec
  * for SDTR/PPR messages */
@@ -390,10 +390,11 @@ spi_dv_retrain(struct scsi_request *sreq, u8 *buffer, u8 *ptr,
 {
        struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt);
        struct scsi_device *sdev = sreq->sr_device;
-       int period, prevperiod = 0; 
+       int period = 0, prevperiod = 0; 
 
 
        for (;;) {
+               int newperiod;
                if (compare_fn(sreq, buffer, ptr, DV_LOOPS))
                        /* Successful DV */
                        break;
@@ -401,7 +402,8 @@ spi_dv_retrain(struct scsi_request *sreq, u8 *buffer, u8 *ptr,
                /* OK, retrain, fallback */
                if (i->f->get_period)
                        i->f->get_period(sdev);
-               period = spi_period(sdev);
+               newperiod = spi_period(sdev);
+               period = newperiod > period ? newperiod : period;
                if (period < 0x0d)
                        period++;
                else
index b9285e5..181cd48 100644 (file)
@@ -12,7 +12,7 @@ dc390_freetag (PDCB pDCB, PSRB pSRB)
                pDCB->TagMask &= ~(1 << pSRB->TagNumber);   /* free tag mask */
                pSRB->TagNumber = 255;
        }
-};
+}
 
 
 static UCHAR
@@ -75,7 +75,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
                printk (KERN_WARNING "DC390: Out of tags for Dev. %02x %02x\n", pDCB->TargetID, pDCB->TargetLUN); 
                return 1;
                //goto no_tag;
-       };
+       }
        DC390_write8 (ScsiFifo, SIMPLE_QUEUE_TAG);
        pDCB->TagMask |= (1 << tag_no); pSRB->TagNumber = tag_no;
        DC390_write8 (ScsiFifo, tag_no);
@@ -86,7 +86,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
       {
 //      no_tag:
        DEBUG1(printk (KERN_DEBUG "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", (disc_allowed?"":"o"), pSRB->pcmd->pid, pSRB));
-      };
+      }
 
     pSRB->SRBState = SRB_START_;
 
@@ -104,7 +104,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
        //pSRB->SRBState = SRB_MSGOUT_;
        pSRB->SRBState |= DO_SYNC_NEGO;
        cmd = SEL_W_ATN_STOP;
-      };
+      }
 
     /* Command is written in CommandPhase, if SEL_W_ATN_STOP ... */
     if (cmd != SEL_W_ATN_STOP)
@@ -125,7 +125,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
            ptr = (PUCHAR) pSRB->pcmd->cmnd;
            for (i=0; i<pSRB->pcmd->cmd_len; i++)
              DC390_write8 (ScsiFifo, *(ptr++));
-         };
+         }
       }
     DEBUG0(if (pACB->pActiveDCB)       \
           printk (KERN_WARNING "DC390: ActiveDCB != 0\n"));
@@ -141,7 +141,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
        //DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
        pACB->SelLost++;
        return 1;
-    };
+    }
     DC390_write8 (ScsiCmd, cmd);
     pACB->pActiveDCB = pDCB; pDCB->pActiveSRB = pSRB;
     pACB->Connected = 1;
@@ -176,7 +176,7 @@ dc390_dma_intr (PACB pACB)
     {
        printk (KERN_ERR "DC390: DMA error (%02x)!\n", dstate);
        return dstate;
-    };
+    }
   if (dstate & DMA_XFER_DONE)
     {
        UINT residual, xferCnt; int ctr = 6000000;
@@ -253,7 +253,7 @@ DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
       {
        DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n"));
        return IRQ_NONE;
-      };
+      }
 #else
     //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
     //dstatus = DC390_read8 (DMA_Status);
@@ -313,7 +313,7 @@ DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
        {
                printk (KERN_ERR "DC390: Suc. op/ Serv. req: pActiveDCB = 0!\n");
                goto unlock;
-       };
+       }
        pSRB = pDCB->pActiveSRB;
        if( pDCB->DCBFlag & ABORT_DEV_ )
          dc390_EnableMsgOut_Abort (pACB, pSRB);
@@ -549,7 +549,7 @@ dc390_reprog (PACB pACB, PDCB pDCB)
   DC390_write8 (CtrlReg3, pDCB->CtrlR3);
   DC390_write8 (CtrlReg4, pDCB->CtrlR4);
   dc390_SetXferRate (pACB, pDCB);
-};
+}
 
 
 #ifdef DC390_DEBUG0
@@ -561,7 +561,7 @@ dc390_printMsg (UCHAR *MsgBuf, UCHAR len)
   for (i = 1; i < len; i++)
     printk (" %02x", MsgBuf[i]);
   printk ("\n");
-};
+}
 #endif
 
 #define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD)
@@ -671,11 +671,11 @@ dc390_MsgIn_set_sync (PACB pACB, PSRB pSRB)
        {
          printk (KERN_INFO "DC390: Set sync nego period to %ins\n", pDCB->NegoPeriod << 2);
          pSRB->MsgInBuf[3] = pDCB->NegoPeriod;
-       };
+       }
       memcpy (pSRB->MsgOutBuf, pSRB->MsgInBuf, 5);
       pSRB->MsgCnt = 5;
       DC390_ENABLE_MSGOUT;
-    };
+    }
 
   pSRB->SRBState &= ~DO_SYNC_NEGO;
   pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;
@@ -713,7 +713,7 @@ dc390_MsgIn_set_sync (PACB pACB, PSRB pSRB)
     }
   
   dc390_reprog (pACB, pDCB);
-};
+}
 
 
 /* handle RESTORE_PTR */
@@ -761,7 +761,7 @@ dc390_restore_ptr (PACB pACB, PSRB pSRB)
     }
 
   pSRB->TotalXferredLen = pSRB->Saved_Ptr;
-};
+}
 
 
 /* According to the docs, the AM53C974 reads the message and 
@@ -789,7 +789,7 @@ dc390_MsgIn_complete (UCHAR *msgbuf, UINT len)
 
 
 /* read and eval received messages */
-void
+static void
 dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
 {
     PDCB   pDCB = pACB->pActiveDCB;
@@ -832,7 +832,7 @@ dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
                  dc390_MsgIn_set_async (pACB, pSRB);
                else
                  dc390_MsgIn_set_sync (pACB, pSRB);
-             };
+             }
            
            // nothing has to be done
          case COMMAND_COMPLETE: break;
@@ -948,7 +948,7 @@ dc390_DataInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
     dc390_DataIO_Comm (pACB, pSRB, READ_DIRECTION);
 }
 
-void
+static void
 dc390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
 {
     PDCB   pDCB;
@@ -989,7 +989,7 @@ dc390_StatusPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
     //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
 }
 
-void
+static void
 dc390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
 {
     UCHAR   bval, i, cnt;
@@ -1097,7 +1097,7 @@ dc390_SetXferRate( PACB pACB, PDCB pDCB )
 }
 
 
-void
+static void
 dc390_Disconnect( PACB pACB )
 {
     PDCB   pDCB;
@@ -1179,7 +1179,7 @@ disc1:
 }
 
 
-void
+static void
 dc390_Reselect( PACB pACB )
 {
     PDCB   pDCB;
@@ -1276,7 +1276,7 @@ dc390_remove_dev (PACB pACB, PDCB pDCB)
        DCBDEBUG(printk (KERN_INFO "DC390: Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i\n",\
                pDCB->TargetID, pDCB->TargetLUN, (int)pDCB, pDCB->GoingSRBCnt));
        return;
-     };
+     }
    pACB->DCBmap[pDCB->TargetID] &= ~(1 << pDCB->TargetLUN);
    
    // The first one
@@ -1302,8 +1302,7 @@ dc390_remove_dev (PACB pACB, PDCB pDCB)
    if (pDCB == pACB->pDCBRunRobin) pACB->pDCBRunRobin = pDCB->pNextDCB;
    kfree (pDCB); 
    pACB->DCBCnt--;
-   /* pACB->DeviceCnt--; */
-};
+}
 
 
 static UCHAR __inline__
@@ -1314,7 +1313,7 @@ dc390_tagq_blacklist (char* name)
      if (memcmp (name, dc390_baddevname1[i], 28) == 0)
        return 1;
    return 0;
-};
+}
    
 
 static void 
@@ -1336,7 +1335,7 @@ dc390_disc_tagq_set (PDCB pDCB, PSCSI_INQDATA ptr)
        else
             pDCB->MaxCommand = 1;
      }
-};
+}
 
 
 static void 
@@ -1346,13 +1345,13 @@ dc390_add_dev (PACB pACB, PDCB pDCB, PSCSI_INQDATA ptr)
    pDCB->DevType = bval1;
    /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */
        dc390_disc_tagq_set (pDCB, ptr);
-};
+}
 
 
-void
+static void
 dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
 {
-    UCHAR  bval, status, i, DCB_removed;
+    UCHAR  bval, status, i;
     PSCSICMD pcmd;
     PSCSI_INQDATA  ptr;
     PSGL   ptr2;
@@ -1362,11 +1361,10 @@ dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
     /* KG: Moved pci_unmap here */
     dc390_pci_unmap(pSRB);
 
-    DCB_removed = 0;
     status = pSRB->TargetStatus;
     ptr = (PSCSI_INQDATA) (pcmd->request_buffer);
     if( pcmd->use_sg )
-       ptr = (PSCSI_INQDATA) sg_dma_address((PSGL) ptr);
+       ptr = (PSCSI_INQDATA) (page_address(((PSGL) ptr)->page) + ((PSGL) ptr)->offset);
        
     DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,\
                pSRB, pcmd->pid));
@@ -1564,55 +1562,22 @@ ckc_e:
                                   pcmd->sense_buffer[2], pcmd->sense_buffer[3]);
            else printk ("\n");
 #endif
-           if( (host_byte(pcmd->result) != DID_OK && !(status_byte(pcmd->result) & CHECK_CONDITION) && !(status_byte(pcmd->result) & BUSY)) ||
-              ((driver_byte(pcmd->result) & DRIVER_SENSE) && (pcmd->sense_buffer[0] & 0x70) == 0x70 &&
-               (pcmd->sense_buffer[2] & 0xf) == ILLEGAL_REQUEST) || host_byte(pcmd->result) & DID_ERROR )
-           {
-              /* device not present: remove */ 
-              //dc390_Going_remove (pDCB, pSRB);
-              dc390_remove_dev (pACB, pDCB); DCB_removed = 1;
-              
-              if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) &&
-                 ((pcmd->device->lun == 0) || (pcmd->device->lun == pACB->pScsiHost->max_lun - 1)) )
-                pACB->scan_devices = 0;
-           }
-           else
-           {
-               /* device present: add */
-               if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) && 
-                   (pcmd->device->lun == pACB->pScsiHost->max_lun - 1) )
-                   pACB->scan_devices = END_SCAN ;
-               /* pACB->DeviceCnt++; */ /* Dev is added on INQUIRY */
-           }
        }
     }
-   
-    //if( pSRB->pcmd->cmnd[0] == INQUIRY && 
-    //  (host_byte(pcmd->result) == DID_OK || status_byte(pcmd->result) & CHECK_CONDITION) )
+
     if( pcmd->cmnd[0] == INQUIRY && 
        (pcmd->result == (DID_OK << 16) || status_byte(pcmd->result) & CHECK_CONDITION) )
      {
-       if ((ptr->DevType & SCSI_DEVTYPE) == TYPE_NODEV && !DCB_removed)
-         {
-            //printk ("DC390: Type = nodev! (%02i-%i)\n", pcmd->target, pcmd->lun);
-            /* device not present: remove */
-            //dc390_Going_remove (pDCB, pSRB);
-            dc390_remove_dev (pACB, pDCB); DCB_removed = 1;
-         }
-       else
+       if ((ptr->DevType & SCSI_DEVTYPE) != TYPE_NODEV)
          {
             /* device found: add */ 
             dc390_add_dev (pACB, pDCB, ptr);
-            if (pACB->scan_devices) pACB->DeviceCnt++;
          }
-       if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) &&
-           (pcmd->device->lun == pACB->pScsiHost->max_lun - 1) )
-         pACB->scan_devices = 0;
-     };
+     }
 
     pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen;
 
-    if (!DCB_removed) dc390_Going_remove (pDCB, pSRB);
+    dc390_Going_remove (pDCB, pSRB);
     /* Add to free list */
     dc390_Free_insert (pACB, pSRB);
 
@@ -1625,7 +1590,7 @@ ckc_e:
 
 
 /* Remove all SRBs from Going list and inform midlevel */
-void
+static void
 dc390_DoingSRB_Done( PACB pACB, PSCSICMD cmd )
 {
     PDCB   pDCB, pdcb;
@@ -1760,4 +1725,3 @@ dc390_InvalidCmd( PACB pACB )
     if( pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_+SRB_MSGOUT) )
        DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
 }
-
index 99a8df7..b9420b5 100644 (file)
@@ -763,11 +763,11 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt)
                                good_bytes = 0;
                        break;
 
-               case RECOVERED_ERROR:
+               case RECOVERED_ERROR: /* an error occurred, but it recovered */
+               case NO_SENSE: /* LLDD got sense data */
                        /*
-                        * An error occurred, but it recovered.  Inform the
-                        * user, but make sure that it's not treated as a
-                        * hard error.
+                        * Inform the user, but make sure that it's not treated
+                        * as a hard error.
                         */
                        print_sense("sd", SCpnt);
                        SCpnt->result = 0;
index e0f17f0..a3e68b4 100644 (file)
@@ -42,7 +42,6 @@ static int sg_version_num = 30531;    /* 2 digits for each component */
 #include <linux/fcntl.h>
 #include <linux/init.h>
 #include <linux/poll.h>
-#include <linux/vmalloc.h>
 #include <linux/smp_lock.h>
 #include <linux/moduleparam.h>
 #include <linux/devfs_fs_kernel.h>
@@ -60,7 +59,7 @@ static int sg_version_num = 30531;    /* 2 digits for each component */
 
 #ifdef CONFIG_SCSI_PROC_FS
 #include <linux/proc_fs.h>
-static char *sg_version_date = "20040513";
+static char *sg_version_date = "20040516";
 
 static int sg_proc_init(void);
 static void sg_proc_cleanup(void);
@@ -73,7 +72,7 @@ static void sg_proc_cleanup(void);
 #define SG_ALLOW_DIO_DEF 0
 #define SG_ALLOW_DIO_CODE /* compile out by commenting this define */
 
-#define SG_MAX_DEVS 8192
+#define SG_MAX_DEVS 32768
 
 /*
  * Suppose you want to calculate the formula muldiv(x,m,d)=int(x * m / d)
@@ -724,7 +723,6 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
                    (void *) SRpnt->sr_buffer, hp->dxfer_len,
                    sg_cmd_done, timeout, SG_DEFAULT_RETRIES);
        /* dxfer_len overwrites SRpnt->sr_bufflen, hence need for b_malloc_len */
-       generic_unplug_device(q);
        return 0;
 }
 
@@ -1337,9 +1335,11 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
        void *old_sg_dev_arr = NULL;
        int k, error;
 
-       sdp = vmalloc(sizeof(Sg_device));
-       if (!sdp)
+       sdp = kmalloc(sizeof(Sg_device), GFP_KERNEL);
+       if (!sdp) {
+               printk(KERN_WARNING "kmalloc Sg_device failure\n");
                return -ENOMEM;
+       }
 
        write_lock_irqsave(&sg_dev_arr_lock, iflags);
        if (unlikely(sg_nr_dev >= sg_dev_max)) {        /* try to resize */
@@ -1347,7 +1347,7 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
                int tmp_dev_max = sg_nr_dev + SG_DEV_ARR_LUMP;
                write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
 
-               tmp_da = vmalloc(tmp_dev_max * sizeof(Sg_device *));
+               tmp_da = kmalloc(tmp_dev_max * sizeof(Sg_device *), GFP_KERNEL);
                if (unlikely(!tmp_da))
                        goto expand_failed;
 
@@ -1381,12 +1381,12 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
 
  out:
        if (error < 0)
-               vfree(sdp);
-       vfree(old_sg_dev_arr);
+               kfree(sdp);
+       kfree(old_sg_dev_arr);
        return error;
 
  expand_failed:
-       printk(KERN_ERR "sg_alloc: device array cannot be resized\n");
+       printk(KERN_WARNING "sg_alloc: device array cannot be resized\n");
        error = -ENOMEM;
        goto out;
 
@@ -1410,20 +1410,26 @@ sg_add(struct class_device *cl_dev)
        int error, k;
 
        disk = alloc_disk(1);
-       if (!disk)
+       if (!disk) {
+               printk(KERN_WARNING "alloc_disk failed\n");
                return -ENOMEM;
+       }
        disk->major = SCSI_GENERIC_MAJOR;
 
        error = -ENOMEM;
        cdev = cdev_alloc();
-       if (!cdev)
+       if (!cdev) {
+               printk(KERN_WARNING "cdev_alloc failed\n");
                goto out;
+       }
        cdev->owner = THIS_MODULE;
        cdev->ops = &sg_fops;
 
        error = sg_alloc(disk, scsidp);
-       if (error < 0)
+       if (error < 0) {
+               printk(KERN_WARNING "sg_alloc failed\n");
                goto out;
+       }
        k = error;
        sdp = sg_dev_arr[k];
 
@@ -1531,7 +1537,7 @@ sg_remove(struct class_device *cl_dev)
                put_disk(sdp->disk);
                sdp->disk = NULL;
                if (NULL == sdp->headfp)
-                       vfree((char *) sdp);
+                       kfree((char *) sdp);
        }
 
        if (delay)
@@ -1596,7 +1602,7 @@ exit_sg(void)
        unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
                                 SG_MAX_DEVS);
        if (sg_dev_arr != NULL) {
-               vfree((char *) sg_dev_arr);
+               kfree((char *) sg_dev_arr);
                sg_dev_arr = NULL;
        }
        sg_dev_max = 0;
@@ -2498,7 +2504,7 @@ sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
                        }
                        if (k < maxd)
                                sg_dev_arr[k] = NULL;
-                       vfree((char *) sdp);
+                       kfree((char *) sdp);
                        res = 1;
                }
                write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
index 7abd5d1..f73bf83 100644 (file)
@@ -35,9 +35,8 @@
 #include <linux/mca.h>
 #include <linux/eisa.h>
 #include <linux/interrupt.h>
-
-#include "scsi.h"
 #include <scsi/scsi_host.h>
+
 #include "53c700.h"
 
 
@@ -86,7 +85,7 @@ param_setup(char *str)
 }
 __setup("sim710=", param_setup);
 
-static Scsi_Host_Template sim710_driver_template = {
+static struct scsi_host_template sim710_driver_template = {
        .name                   = "LSI (Symbios) 710 MCA/EISA",
        .proc_name              = "sim710",
        .this_id                = 7,
index 4713c80..db0d11d 100644 (file)
@@ -754,12 +754,11 @@ Enomem:
 static void get_capabilities(struct scsi_cd *cd)
 {
        unsigned char *buffer;
-       int rc, n, mrw_write = 0, mrw = 1,ram_write=0;
        struct scsi_mode_data data;
        struct scsi_request *SRpnt;
        unsigned char cmd[MAX_COMMAND_SIZE];
        unsigned int the_result;
-       int retries;
+       int retries, rc, n;
 
        static char *loadmech[] =
        {
@@ -831,19 +830,6 @@ static void get_capabilities(struct scsi_cd *cd)
                return;
        }
 
-       if (cdrom_is_mrw(&cd->cdi, &mrw_write)) {
-               mrw = 0;
-               cd->cdi.mask |= CDC_MRW;
-               cd->cdi.mask |= CDC_MRW_W;
-       }
-       if (!mrw_write)
-               cd->cdi.mask |= CDC_MRW_W;
-
-       if (cdrom_is_random_writable(&cd->cdi, &ram_write))
-               cd->cdi.mask |= CDC_RAM;
-       if (!ram_write)
-               cd->cdi.mask |= CDC_RAM;
-
        n = data.header_length + data.block_descriptor_length;
        cd->cdi.speed = ((buffer[n + 8] << 8) + buffer[n + 9]) / 176;
        cd->readcd_known = 1;
index 0534885..e94c3a2 100644 (file)
@@ -331,6 +331,9 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
        int result;
        unsigned char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
 
+       if (!buffer)
+               return -ENOMEM;
+
        memset(&cgc, 0, sizeof(struct packet_command));
        cgc.timeout = IOCTL_TIMEOUT;
 
index 8e1433f..24a3c49 100644 (file)
@@ -176,8 +176,8 @@ static int modes_defined;
 static ST_buffer *new_tape_buffer(int, int, int);
 static int enlarge_buffer(ST_buffer *, int, int);
 static void normalize_buffer(ST_buffer *);
-static int append_to_buffer(const char *, ST_buffer *, int);
-static int from_buffer(ST_buffer *, char *, int);
+static int append_to_buffer(const char __user *, ST_buffer *, int);
+static int from_buffer(ST_buffer *, char __user *, int);
 static void move_buffer_data(ST_buffer *, int);
 static void buf_to_sg(ST_buffer *, unsigned int);
 
@@ -1276,7 +1276,7 @@ static ssize_t rw_checks(Scsi_Tape *STp, struct file *filp, size_t count, loff_t
 }
 
 
-static int setup_buffering(Scsi_Tape *STp, const char *buf, size_t count, int is_read)
+static int setup_buffering(Scsi_Tape *STp, const char __user *buf, size_t count, int is_read)
 {
        int i, bufsize, retval = 0;
        ST_buffer *STbp = STp->buffer;
@@ -1348,7 +1348,7 @@ static void release_buffering(Scsi_Tape *STp)
 
 /* Write command */
 static ssize_t
- st_write(struct file *filp, const char *buf, size_t count, loff_t * ppos)
+st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
 {
        ssize_t total;
        ssize_t i, do_count, blks, transfer;
@@ -1356,7 +1356,7 @@ static ssize_t
        int undone, retry_eot = 0, scode;
        int async_write;
        unsigned char cmd[MAX_COMMAND_SIZE];
-       const char *b_point;
+       const char __user *b_point;
        Scsi_Request *SRpnt = NULL;
        Scsi_Tape *STp = filp->private_data;
        ST_mode *STm;
@@ -1817,7 +1817,7 @@ static long read_tape(Scsi_Tape *STp, long count, Scsi_Request ** aSRpnt)
 
 /* Read command */
 static ssize_t
- st_read(struct file *filp, char *buf, size_t count, loff_t * ppos)
+st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
 {
        ssize_t total;
        ssize_t retval = 0;
@@ -3527,7 +3527,7 @@ static void normalize_buffer(ST_buffer * STbuffer)
 
 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
    negative error code. */
-static int append_to_buffer(const char *ubp, ST_buffer * st_bp, int do_count)
+static int append_to_buffer(const char __user *ubp, ST_buffer * st_bp, int do_count)
 {
        int i, cnt, res, offset;
 
@@ -3558,7 +3558,7 @@ static int append_to_buffer(const char *ubp, ST_buffer * st_bp, int do_count)
 
 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
    negative error code. */
-static int from_buffer(ST_buffer * st_bp, char *ubp, int do_count)
+static int from_buffer(ST_buffer * st_bp, char __user *ubp, int do_count)
 {
        int i, cnt, res, offset;
 
index 9712b58..de5cc59 100644 (file)
@@ -622,12 +622,13 @@ void sym53c416_probe(void)
        int ints[2];
 
        ints[0] = 1;
-       for(; *base; base++)
-       {
-               if(!check_region(*base, IO_RANGE) && sym53c416_test(*base))
-               {
-                       ints[1] = *base;
-                       sym53c416_setup(NULL, ints);
+       for(; *base; base++) {
+               if (request_region(*base, IO_RANGE, ID)) {
+                       if (sym53c416_test(*base)) {
+                               ints[1] = *base;
+                               sym53c416_setup(NULL, ints);
+                       }
+                       release_region(*base, IO_RANGE);
                }
        }
 }
@@ -702,44 +703,42 @@ int __init sym53c416_detect(Scsi_Host_Template *tpnt)
        sym53c416_probe();
 
        /* Now we register and set up each host adapter found... */
-       for(count = 0, i = 0; i < host_index; i++)
-       {
-               if(!sym53c416_test(hosts[i].base))
+       for(count = 0, i = 0; i < host_index; i++) {
+               if (!request_region(hosts[i].base, IO_RANGE, ID))
+                       continue;
+               if (!sym53c416_test(hosts[i].base)) {
                        printk(KERN_WARNING "No sym53c416 found at address 0x%03x\n", hosts[i].base);
-               else
-               {
-                       if(hosts[i].irq == 0)
-                       /* We don't have an irq yet, so we should probe for one */
-                               if((hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id)) == 0)
-                                       printk(KERN_WARNING "IRQ autoprobing failed for sym53c416 at address 0x%03x\n", hosts[i].base);
-                       if(hosts[i].irq && !check_region(hosts[i].base, IO_RANGE))
-                       {
-                               shpnt = scsi_register(tpnt, 0);
-                               if(shpnt==NULL)
-                                       continue;
-                               spin_lock_irqsave(&sym53c416_lock, flags);
-                               /* Request for specified IRQ */
-                               if(request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, shpnt))
-                               {
-                                       spin_unlock_irqrestore(&sym53c416_lock, flags);
-                                       printk(KERN_ERR "sym53c416: Unable to assign IRQ %d\n", hosts[i].irq);
-                                       scsi_unregister(shpnt);
-                               }
-                               else
-                               {
-                                       /* Inform the kernel of our IO range */
-                                       request_region(hosts[i].base, IO_RANGE, ID);
-                                       shpnt->unique_id = hosts[i].base;
-                                       shpnt->io_port = hosts[i].base;
-                                       shpnt->n_io_port = IO_RANGE;
-                                       shpnt->irq = hosts[i].irq;
-                                       shpnt->this_id = hosts[i].scsi_id;
-                                       sym53c416_init(hosts[i].base, hosts[i].scsi_id);
-                                       count++;
-                                       spin_unlock_irqrestore(&sym53c416_lock, flags);
-                               }
-                       }
+                       goto fail_release_region;
                }
+
+               /* We don't have an irq yet, so we should probe for one */
+               if (!hosts[i].irq)
+                       hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id);
+               if (!hosts[i].irq)
+                       goto fail_release_region;
+       
+               shpnt = scsi_register(tpnt, 0);
+               if (!shpnt)
+                       goto fail_release_region;
+               /* Request for specified IRQ */
+               if (request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, shpnt))
+                       goto fail_free_host;
+
+               spin_lock_irqsave(&sym53c416_lock, flags);
+               shpnt->unique_id = hosts[i].base;
+               shpnt->io_port = hosts[i].base;
+               shpnt->n_io_port = IO_RANGE;
+               shpnt->irq = hosts[i].irq;
+               shpnt->this_id = hosts[i].scsi_id;
+               sym53c416_init(hosts[i].base, hosts[i].scsi_id);
+               count++;
+               spin_unlock_irqrestore(&sym53c416_lock, flags);
+               continue;
+
+ fail_free_host:
+               scsi_unregister(shpnt);
+ fail_release_region:
+               release_region(hosts[i].base, IO_RANGE);
        }
        return count;
 }
index dd51823..d336e30 100644 (file)
  *     2.1b1 04/01/31  GL      (applied 05.04) Remove internal         *
  *                             command-queuing.                        *
  *     2.1b2 04/02/01  CH      (applied 05.04) Fix error-handling      *
+ *     2.1c  04/05/23  GL      Update to use the new pci_driver API,   *
+ *                             some scsi EH updates, more cleanup.     *
+ *     2.1d  04/05/27  GL      Moved setting of scan_devices to        *
+ *                             slave_alloc/_configure/_destroy, as     *
+ *                             suggested by CH.                        *
  ***********************************************************************/
 
 /* Uncomment SA_INTERRUPT, if the driver refuses to share its IRQ with other devices */
 #include <linux/init.h>
 #include <linux/spinlock.h>
 
-#if defined(MODULE)
 static struct pci_device_id tmscsim_pci_tbl[] = {
        {
                .vendor         = PCI_VENDOR_ID_AMD,
@@ -278,8 +282,7 @@ static struct pci_device_id tmscsim_pci_tbl[] = {
        { }             /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, tmscsim_pci_tbl);
-#endif
-       
+
 #define USE_SPINLOCKS 1
 
 #define DC390_IFLAGS unsigned long iflags
@@ -342,6 +345,8 @@ static void   dc390_updateDCB (PACB pACB, PDCB pDCB);
 
 static int DC390_release(struct Scsi_Host *host);
 static int dc390_shutdown (struct Scsi_Host *host);
+static int DC390_proc_info (struct Scsi_Host *shpnt, char *buffer, char **start,
+                           off_t offset, int length, int inout);
 
 static PACB    dc390_pACB_start= NULL;
 static PACB    dc390_pACB_current = NULL;
@@ -351,16 +356,14 @@ static UCHAR      dc390_adapterCnt = 0;
 
 /* Startup values, to be overriden on the commandline */
 static int tmscsim[] = {-2, -2, -2, -2, -2, -2};
+static int tmscsim_paramnum = ARRAY_SIZE(tmscsim);
 
-#if defined(MODULE)
-MODULE_PARM(tmscsim, "1-6i");
+module_param_array(tmscsim, int, tmscsim_paramnum, 0);
 MODULE_PARM_DESC(tmscsim, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)");
 MODULE_AUTHOR("C.L. Huang / Kurt Garloff");
 MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters");
 MODULE_LICENSE("GPL");
-
 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
-#endif
 
 static PVOID dc390_phase0[]={
        dc390_DataOut_0,
@@ -913,6 +916,14 @@ static void dc390_SendSRB( PACB pACB, PSRB pSRB )
     }
 }
 
+static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length)
+{
+       memset(sg, 0, sizeof(struct scatterlist));
+       sg->page        = virt_to_page(addr);
+       sg->length      = length;
+       sg->offset      = (unsigned long)addr & ~PAGE_MASK;
+       return sg;
+}
 
 /* Create pci mapping */
 static int dc390_pci_map (PSRB pSRB)
@@ -921,40 +932,43 @@ static int dc390_pci_map (PSRB pSRB)
        Scsi_Cmnd *pcmd = pSRB->pcmd;
        struct pci_dev *pdev = pSRB->pSRBDCB->pDCBACB->pdev;
        dc390_cmd_scp_t* cmdp = ((dc390_cmd_scp_t*)(&pcmd->SCp));
+
        /* Map sense buffer */
        if (pSRB->SRBFlag & AUTO_REQSENSE) {
-               sg_dma_address(&pSRB->Segmentx) = cmdp->saved_dma_handle = 
-                       pci_map_page(pdev, virt_to_page(pcmd->sense_buffer),
-                                    (unsigned long)pcmd->sense_buffer & ~PAGE_MASK, sizeof(pcmd->sense_buffer),
-                                    DMA_FROM_DEVICE);
-               sg_dma_len(&pSRB->Segmentx) = sizeof(pcmd->sense_buffer);
-               pSRB->SGcount = 1;
-               pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
+               pSRB->pSegmentList      = dc390_sg_build_single(&pSRB->Segmentx, pcmd->sense_buffer, sizeof(pcmd->sense_buffer));
+               pSRB->SGcount           = pci_map_sg(pdev, pSRB->pSegmentList, 1,
+                                                    DMA_FROM_DEVICE);
+               cmdp->saved_dma_handle  = sg_dma_address(pSRB->pSegmentList);
+
+               /* TODO: error handling */
+               if (pSRB->SGcount != 1)
+                       error = 1;
                DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __FUNCTION__, pcmd->sense_buffer, cmdp->saved_dma_handle));
-       /* Make SG list */      
+       /* Map SG list */
        } else if (pcmd->use_sg) {
-               pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
-               pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList,
-                                          pcmd->use_sg,
-                                          scsi_to_pci_dma_dir(pcmd->sc_data_direction));
+               pSRB->pSegmentList      = (PSGL) pcmd->request_buffer;
+               pSRB->SGcount           = pci_map_sg(pdev, pSRB->pSegmentList, pcmd->use_sg,
+                                                    scsi_to_pci_dma_dir(pcmd->sc_data_direction));
                /* TODO: error handling */
                if (!pSRB->SGcount)
                        error = 1;
-               DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n", __FUNCTION__, pcmd->request_buffer, pSRB->SGcount, pcmd->use_sg));
+               DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n",\
+                             __FUNCTION__, pcmd->request_buffer, pSRB->SGcount, pcmd->use_sg));
        /* Map single segment */
        } else if (pcmd->request_buffer && pcmd->request_bufflen) {
-               sg_dma_address(&pSRB->Segmentx) = cmdp->saved_dma_handle =
-                       pci_map_page(pdev, virt_to_page(pcmd->request_buffer),
-                                    (unsigned long)pcmd->request_buffer & ~PAGE_MASK,
-                                    pcmd->request_bufflen, scsi_to_pci_dma_dir(pcmd->sc_data_direction));
+               pSRB->pSegmentList      = dc390_sg_build_single(&pSRB->Segmentx, pcmd->request_buffer, pcmd->request_bufflen);
+               pSRB->SGcount           = pci_map_sg(pdev, pSRB->pSegmentList, 1,
+                                                    scsi_to_pci_dma_dir(pcmd->sc_data_direction));
+               cmdp->saved_dma_handle  = sg_dma_address(pSRB->pSegmentList);
+
                /* TODO: error handling */
-               sg_dma_len(&pSRB->Segmentx) = pcmd->request_bufflen;
-               pSRB->SGcount = 1;
-               pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
+               if (pSRB->SGcount != 1)
+                       error = 1;
                DEBUG1(printk("%s(): Mapped request buffer %p at %x\n", __FUNCTION__, pcmd->request_buffer, cmdp->saved_dma_handle));
        /* No mapping !? */     
        } else
                pSRB->SGcount = 0;
+
        return error;
 }
 
@@ -963,21 +977,16 @@ static void dc390_pci_unmap (PSRB pSRB)
 {
        Scsi_Cmnd* pcmd = pSRB->pcmd;
        struct pci_dev *pdev = pSRB->pSRBDCB->pDCBACB->pdev;
-       dc390_cmd_scp_t* cmdp = ((dc390_cmd_scp_t*)(&pcmd->SCp));
+       DEBUG1(dc390_cmd_scp_t* cmdp = ((dc390_cmd_scp_t*)(&pcmd->SCp)));
 
        if (pSRB->SRBFlag) {
-               pci_unmap_page(pdev, cmdp->saved_dma_handle,
-                              sizeof(pcmd->sense_buffer), DMA_FROM_DEVICE);
+               pci_unmap_sg(pdev, &pSRB->Segmentx, 1, DMA_FROM_DEVICE);
                DEBUG1(printk("%s(): Unmapped sense buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle));
        } else if (pcmd->use_sg) {
-               pci_unmap_sg(pdev, pcmd->request_buffer, pcmd->use_sg,
-                            scsi_to_pci_dma_dir(pcmd->sc_data_direction));
+               pci_unmap_sg(pdev, pcmd->request_buffer, pcmd->use_sg, scsi_to_pci_dma_dir(pcmd->sc_data_direction));
                DEBUG1(printk("%s(): Unmapped SG at %p with %d elements\n", __FUNCTION__, pcmd->request_buffer, pcmd->use_sg));
        } else if (pcmd->request_buffer && pcmd->request_bufflen) {
-               pci_unmap_page(pdev,
-                              cmdp->saved_dma_handle,
-                              pcmd->request_bufflen,
-                              scsi_to_pci_dma_dir(pcmd->sc_data_direction));
+               pci_unmap_sg(pdev, &pSRB->Segmentx, 1, scsi_to_pci_dma_dir(pcmd->sc_data_direction));
                DEBUG1(printk("%s(): Unmapped request buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle));
        }
 }
@@ -1031,15 +1040,15 @@ static void dc390_BuildSRB (Scsi_Cmnd* pcmd, PDCB pDCB, PSRB pSRB)
  * 2.0.x: always return 0
  * 2.1.x: old model: (use_new_eh_code == 0): like 2.0.x
  *       TO BE DONE:
- *       new model: return 0 if successful
- *                  return 1 if command cannot be queued (queue full)
+ *       new model: return 0 if successful, or must not be re-queued
+ *                  return 1 if command cannot be queued (queue full)
  *                  command will be inserted in midlevel queue then ...
  *
  ***********************************************************************/
 
 static int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
 {
-    PDCB   pDCB;
+    PDCB   pDCB = (PDCB) cmd->device->hostdata;
     PSRB   pSRB;
     PACB   pACB = (PACB) cmd->device->host->hostdata;
 
@@ -1050,42 +1059,19 @@ static int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
     /* TODO: Change the policy: Always accept TEST_UNIT_READY or INQUIRY 
      * commands and alloc a DCB for the device if not yet there. DCB will
      * be removed in dc390_SRBdone if SEL_TIMEOUT */
-
-    if( (pACB->scan_devices == END_SCAN) && (cmd->cmnd[0] != INQUIRY) )
-       pACB->scan_devices = 0;
-
-    else if( (pACB->scan_devices) && (cmd->cmnd[0] == READ_6) )
-       pACB->scan_devices = 0;
-
-    if( (pACB->scan_devices || cmd->cmnd[0] == TEST_UNIT_READY || cmd->cmnd[0] == INQUIRY) && 
-       !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) )
-    {
-        pACB->scan_devices = 1;
-
-       dc390_initDCB( pACB, &pDCB, cmd->device->id, cmd->device->lun );
-       if (!pDCB)
-         {
-           printk (KERN_ERR "DC390: kmalloc for DCB failed, target %02x lun %02x\n", 
-                   cmd->device->id, cmd->device->lun);
-           goto fail;
-         }
-            
-    }
-    else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) )
-    {
+    if (!(pACB->scan_devices) && !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun))) {
        printk(KERN_INFO "DC390: Ignore target %02x lun %02x\n",
                cmd->device->id, cmd->device->lun); 
        goto fail;
     }
-    else
-    {
-       pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun);
-       if (!pDCB)
-        {  /* should never happen */
-           printk (KERN_ERR "DC390: no DCB failed, target %02x lun %02x\n", 
-                   cmd->device->id, cmd->device->lun);
-           goto fail;
-        }
+
+    /* Should it be: BUG_ON(!pDCB); ? */
+
+    if (!pDCB)
+    {  /* should never happen */
+       printk (KERN_ERR "DC390: no DCB found, target %02x lun %02x\n", 
+               cmd->device->id, cmd->device->lun);
+       goto fail;
     }
 
     pACB->Cmds++;
@@ -1304,7 +1290,7 @@ static void dc390_dumpinfo (PACB pACB, PDCB pDCB, PSRB pSRB)
 
 static int DC390_abort (Scsi_Cmnd *cmd)
 {
-    PDCB  pDCB;
+    PDCB  pDCB = (PDCB) cmd->device->hostdata;
     PSRB  pSRB, psrb;
     UINT  count, i;
     int   status;
@@ -1314,7 +1300,6 @@ static int DC390_abort (Scsi_Cmnd *cmd)
     printk ("DC390: Abort command (pid %li, Device %02i-%02i)\n",
            cmd->pid, cmd->device->id, cmd->device->lun);
 
-    pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun);
     if( !pDCB ) goto  NOT_RUN;
 
     /* Added 98/07/02 KG */
@@ -1561,15 +1546,16 @@ static void dc390_initDCB( PACB pACB, PDCB *ppDCB, UCHAR id, UCHAR lun )
 {
     PEEprom    prom;
     UCHAR      index;
-    PDCB pDCB, pDCB2;
+    PDCB       pDCB, pDCB2 = 0;
 
     pDCB = kmalloc (sizeof(DC390_DCB), GFP_ATOMIC);
     DCBDEBUG(printk (KERN_INFO "DC390: alloc mem for DCB (ID %i, LUN %i): %p\n",       \
                     id, lun, pDCB));
+
     *ppDCB = pDCB;
-    if (!pDCB) return;
-    pDCB2 = 0;
+    if (!pDCB)
+       return;
+
     if( pACB->DCBCnt == 0 )
     {
        pACB->pLinkDCB = pDCB;
@@ -1745,8 +1731,6 @@ static void __init dc390_initACB (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index
     pACB->SRBCount = MAX_SRB_CNT;
     pACB->AdapterIndex = index;
     pACB->status = 0;
-    psh->this_id = dc390_eepromBuf[index][EE_ADAPT_SCSI_ID];
-    pACB->DeviceCnt = 0;
     pACB->DCBCnt = 0;
     pACB->TagMaxNum = 2 << dc390_eepromBuf[index][EE_TAG_CMD_NUM];
     pACB->ACBFlag = 0;
@@ -1856,7 +1840,7 @@ static int __init dc390_initAdapter (PSH psh, ULONG io_port, UCHAR Irq, UCHAR in
  *
  * Inputs : host - pointer to this host adapter's structure
  *         io_port - IO ports mapped to this adapter
- *         Irq - IRQ assigned to this adpater
+ *         irq - IRQ assigned to this adpater
  *         struct pci_dev - PCI access handle
  *         index - Adapter index
  *
@@ -1865,10 +1849,8 @@ static int __init dc390_initAdapter (PSH psh, ULONG io_port, UCHAR Irq, UCHAR in
  * Note: written in capitals, because the locking is only done here,
  *     not in DC390_detect, called from outside 
  ***********************************************************************/
-
-static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, struct pci_dev *pdev, UCHAR index)
+static int __init dc390_init (PSH psh, unsigned long io_port, u8 irq, struct pci_dev *pdev, UCHAR index)
 {
-    PSH   psh;
     PACB  pACB;
 
     if (dc390_CheckEEpromCheckSum (PDEV, index))
@@ -1890,25 +1872,16 @@ static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, struct pci_de
        dc390_check_for_safe_settings ();
        dc390_EEprom_Override (index);
     }
-   
-    psh = scsi_register( psht, sizeof(DC390_ACB) );
-    if( !psh ) return( -1 );
-       
-    scsi_set_device(psh, &pdev->dev);
     pACB = (PACB) psh->hostdata;
 
     DEBUG0(printk(KERN_INFO "DC390: pSH = %8x, Index %02i\n", (UINT) psh, index));
 
-    dc390_initACB( psh, io_port, Irq, index );
+    dc390_initACB( psh, io_port, irq, index );
         
     PDEVSET;
 
-    if( !dc390_initAdapter( psh, io_port, Irq, index ) )
+    if( !dc390_initAdapter( psh, io_port, irq, index ) )
     {
-       DEBUG0(printk("DC390: pACB = %8x, pDCBmap = %8x, pSRB_array = %8x\n",\
-                     (UINT) pACB, (UINT) pACB->DCBmap, (UINT) pACB->SRB_array));
-       DEBUG0(printk("DC390: ACB size= %4x, DCB size= %4x, SRB size= %4x\n",\
-                     sizeof(DC390_ACB), sizeof(DC390_DCB), sizeof(DC390_SRB) ));
         return (0);
     }
     else
@@ -1927,42 +1900,131 @@ static void __init dc390_set_pci_cfg (PDEVDECL)
        PCI_WRITE_CONFIG_WORD (PDEV, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));
 }
 
-int __init DC390_detect (Scsi_Host_Template *psht)
+/**
+ * dc390_slave_alloc - Called by the scsi mid layer to tell us about a new
+ * scsi device that we need to deal with.
+ *
+ * @scsi_device: The new scsi device that we need to handle.
+ */
+static int dc390_slave_alloc(struct scsi_device *scsi_device)
+{
+       PDCB pDCB;
+       PACB pACB = (PACB) scsi_device->host->hostdata;
+       dc390_initDCB(pACB, &pDCB, scsi_device->id, scsi_device->lun);
+       if (pDCB != NULL) {
+               scsi_device->hostdata = pDCB;
+               pACB->scan_devices = 1;
+               return 0;
+       }
+       return -ENOMEM;
+}
+
+/**
+ * dc390_slave_destroy - Called by the scsi mid layer to tell us about a
+ * device that is going away.
+ *
+ * @scsi_device: The scsi device that we need to remove.
+ */
+static void dc390_slave_destroy(struct scsi_device *scsi_device)
+{
+       PACB pACB = (PACB) scsi_device->host->hostdata;
+       PDCB pDCB = (PDCB) scsi_device->hostdata;
+       pACB->scan_devices = 0;
+       if (pDCB != NULL)
+               dc390_remove_dev(pACB, pDCB);
+       else
+               printk(KERN_ERR"%s() called for non-existing device!\n", __FUNCTION__);
+}
+
+static int dc390_slave_configure(struct scsi_device *scsi_device)
 {
-    struct pci_dev *pdev = NULL;
-    UCHAR   irq;
-    ULONG   io_port;
+       PACB pACB = (PACB) scsi_device->host->hostdata;
+       pACB->scan_devices = 0;
+       return 0;
+}
 
-    dc390_pACB_start = NULL;
+static Scsi_Host_Template driver_template = {
+       .module                 = THIS_MODULE,
+       .proc_name              = "tmscsim", 
+       .proc_info              = DC390_proc_info,
+       .name                   = DC390_BANNER " V" DC390_VERSION,
+       .slave_alloc            = dc390_slave_alloc,
+       .slave_configure        = dc390_slave_configure,
+       .slave_destroy          = dc390_slave_destroy,
+       .queuecommand           = DC390_queue_command,
+       .eh_abort_handler       = DC390_abort,
+       .eh_bus_reset_handler   = DC390_reset,
+       .bios_param             = DC390_bios_param,
+       .can_queue              = 42,
+       .this_id                = 7,
+       .sg_tablesize           = SG_ALL,
+       .cmd_per_lun            = 16,
+       .use_clustering         = DISABLE_CLUSTERING,
+};
 
-    if ( PCI_PRESENT )
-           while ((pdev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD53C974, pdev)))
-       {
-           if (pci_enable_device (pdev))
-               continue;
+static int __devinit dc390_init_one(struct pci_dev *dev,
+                                   const struct pci_device_id *id)
+{
+       struct Scsi_Host *scsi_host;
+       unsigned long io_port;
+       u8 irq;
+       PACB  pACB;
+       int ret = -ENOMEM;
 
-           if (pci_set_dma_mask(pdev, 0xffffffff)) {
-                   printk(KERN_ERR "DC390(%i): No suitable DMA available.\n", dc390_adapterCnt);
-                   continue;
-           }
-           PCI_GET_IO_AND_IRQ;
-           DEBUG0(printk(KERN_INFO "DC390(%i): IO_PORT=%04x,IRQ=%x\n", dc390_adapterCnt, (UINT) io_port, irq));
+       if (pci_enable_device(dev))
+               return -ENODEV;
 
-           if( !DC390_init(psht, io_port, irq, PDEV, dc390_adapterCnt))
-           {
-               pci_set_master(pdev);
-               dc390_set_pci_cfg (PDEV);
-               dc390_adapterCnt++;
-           }
+       io_port = pci_resource_start(dev, 0);
+       irq = dev->irq;
+
+       /* allocate scsi host information (includes out adapter) */
+       scsi_host = scsi_host_alloc(&driver_template, sizeof(struct _ACB));
+       if (!scsi_host)
+               goto nomem;
+
+       pACB = (PACB) scsi_host->hostdata;
+
+       if (dc390_init(scsi_host, io_port, irq, dev, dc390_adapterCnt)) {
+               ret = -EBUSY;
+               goto busy;
        }
-    else
-       printk (KERN_ERR "DC390: No PCI BIOS found!\n");
-   
-    if (dc390_adapterCnt)
-       psht->proc_name = "tmscsim";
 
-    printk(KERN_INFO "DC390: %i adapters found\n", dc390_adapterCnt);
-    return( dc390_adapterCnt );
+       pci_set_master(dev);
+       dc390_set_pci_cfg(dev);
+       dc390_adapterCnt++;
+
+       /* get the scsi mid level to scan for new devices on the bus */
+       if (scsi_add_host(scsi_host, &dev->dev)) {
+               ret = -ENODEV;
+               goto nodev;
+       }
+       pci_set_drvdata(dev, scsi_host);
+       scsi_scan_host(scsi_host);
+
+       return 0;
+
+nodev:
+busy:
+       scsi_host_put(scsi_host);
+nomem:
+       pci_disable_device(dev);
+       return ret;
+}
+
+/**
+ * dc390_remove_one - Called to remove a single instance of the adapter.
+ *
+ * @dev: The PCI device to remove.
+ */
+static void __devexit dc390_remove_one(struct pci_dev *dev)
+{
+       struct Scsi_Host *scsi_host = pci_get_drvdata(dev);
+
+       scsi_remove_host(scsi_host);
+       DC390_release(scsi_host);
+       pci_disable_device(dev);
+       scsi_host_put(scsi_host);
+       pci_set_drvdata(dev, NULL);
 }
 
 /********************************************************************
@@ -2035,7 +2097,7 @@ static int DC390_proc_info (struct Scsi_Host *shpnt, char *buffer, char **start,
   SPRINTF("            Lost arbitrations %i, Sel. connected %i, Connected: %s\n", 
          pACB->SelLost, pACB->SelConn, pACB->Connected? "Yes": "No");
    
-  SPRINTF("Nr of attached devices: %i, Nr of DCBs: %i\n", pACB->DeviceCnt, pACB->DCBCnt);
+  SPRINTF("Nr of DCBs: %i\n", pACB->DCBCnt);
   SPRINTF("Map of attached LUNs: %02x %02x %02x %02x %02x %02x %02x %02x\n",
          pACB->DCBmap[0], pACB->DCBmap[1], pACB->DCBmap[2], pACB->DCBmap[3], 
          pACB->DCBmap[4], pACB->DCBmap[5], pACB->DCBmap[6], pACB->DCBmap[7]);
@@ -2122,7 +2184,7 @@ static int DC390_proc_info (struct Scsi_Host *shpnt, char *buffer, char **start,
 static int dc390_shutdown (struct Scsi_Host *host)
 {
     UCHAR    bval;
-    PACB pACB = (PACB)(host->hostdata);
+    PACB pACB = (PACB) host->hostdata;
    
 /*  pACB->soft_reset(host); */
 
@@ -2142,7 +2204,7 @@ static int dc390_shutdown (struct Scsi_Host *host)
 static void dc390_freeDCBs (struct Scsi_Host *host)
 {
     PDCB pDCB, nDCB;
-    PACB pACB = (PACB)(host->hostdata);
+    PACB pACB = (PACB) host->hostdata;
     
     pDCB = pACB->pLinkDCB;
     if (!pDCB) return;
@@ -2161,7 +2223,7 @@ static void dc390_freeDCBs (struct Scsi_Host *host)
 static int DC390_release (struct Scsi_Host *host)
 {
     DC390_IFLAGS;
-    PACB pACB = (PACB)(host->hostdata);
+    PACB pACB = (PACB) host->hostdata;
 
     DC390_LOCK_IO(host);
 
@@ -2177,24 +2239,25 @@ static int DC390_release (struct Scsi_Host *host)
     release_region(host->io_port,host->n_io_port);
     dc390_freeDCBs (host);
     DC390_UNLOCK_IO(host);
-    scsi_unregister(host);
     return( 1 );
 }
 
-static Scsi_Host_Template driver_template = {
-   .proc_name      = "tmscsim", 
-   .proc_info      = DC390_proc_info,
-   .name           = DC390_BANNER " V" DC390_VERSION,
-   .detect         = DC390_detect,
-   .release        = DC390_release,
-   .queuecommand   = DC390_queue_command,
-   .eh_abort_handler           = DC390_abort,
-   .eh_bus_reset_handler       = DC390_reset,
-   .bios_param     = DC390_bios_param,
-   .can_queue      = 42,
-   .this_id        = 7,
-   .sg_tablesize   = SG_ALL,
-   .cmd_per_lun    = 16,
-   .use_clustering = DISABLE_CLUSTERING,
+static struct pci_driver dc390_driver = {
+       .name           = "tmscsim",
+       .id_table       = tmscsim_pci_tbl,
+       .probe          = dc390_init_one,
+       .remove         = __devexit_p(dc390_remove_one),
 };
-#include "scsi_module.c"
+
+static int __init dc390_module_init(void)
+{
+       return pci_module_init(&dc390_driver);
+}
+
+static void __exit dc390_module_exit(void)
+{
+       pci_unregister_driver(&dc390_driver);
+}
+
+module_init(dc390_module_init);
+module_exit(dc390_module_exit);
index fd12e60..7f3ad62 100644 (file)
@@ -22,8 +22,6 @@
 
 #define SEL_TIMEOUT            153     /* 250 ms selection timeout (@ 40 MHz) */
 
-#define END_SCAN               2
-
 #define pci_dma_lo32(a)                        (a & 0xffffffff)
 
 typedef u8             UCHAR;  /*  8 bits */
@@ -196,10 +194,8 @@ UCHAR              status;
 
 UCHAR          SRBCount;
 UCHAR          AdapterIndex;   /*; nth Adapter this driver */
-UCHAR          DeviceCnt;
 UCHAR          DCBCnt;
 
-/* 0x10: */
 UCHAR          TagMaxNum;
 UCHAR          ACBFlag;
 UCHAR          Gmode2;
@@ -213,13 +209,11 @@ PDCB              pActiveDCB;
 PSRB           pFreeSRB;
 PSRB           pTmpSRB;
 
-/* 0x2c: */
 UCHAR          msgin123[4];
 UCHAR          DCBmap[MAX_SCSI_ID];
 UCHAR          Connected;
 UCHAR          pad;
 
-/* 0x30: */
 #if defined(USE_SPINLOCKS) && USE_SPINLOCKS > 1 && (defined(CONFIG_SMP) || DEBUG_SPINLOCKS > 0)
 spinlock_t     lock;
 #endif
@@ -230,20 +224,17 @@ UCHAR             MsgLen;
 UCHAR          Ignore_IRQ;     /* Not used */
 
 PDEVDECL1;                     /* Pointer to PCI cfg. space */
-/* 0x40/0x3c: */
+
 ULONG          Cmds;
 UINT           SelLost;
 UINT           SelConn;
 UINT           CmdInQ;
 UINT           CmdOutOfSRB;
        
-/* 0x54/0x50: */
 struct timer_list      Waiting_Timer;
-/* 0x68/0x64: */
+
 DC390_SRB      TmpSRB;
-/* 0xcc/0xc8: */
 DC390_SRB      SRB_array[MAX_SRB_CNT];         /* 50 SRBs */
-/* 0xfa4/0xfa0: */
 };
 
 typedef  struct  _ACB   DC390_ACB, *PACB;
index 042b47a..037e1ab 100644 (file)
@@ -1605,6 +1605,7 @@ static int wd7000_release(struct Scsi_Host *shost)
        return 0;
 }
 
+#if 0
 /*
  *  I have absolutely NO idea how to do an abort with the WD7000...
  */
@@ -1619,7 +1620,7 @@ static int wd7000_abort(Scsi_Cmnd * SCpnt)
        }
        return FAILED;
 }
-
+#endif
 
 /*
  *  I also have no idea how to do a reset...
index d8c8a81..99ff672 100644 (file)
@@ -57,28 +57,18 @@ static acpi_status acpi_serial_port(struct serial_struct *req,
 static acpi_status acpi_serial_ext_irq(struct serial_struct *req,
                                       struct acpi_resource_ext_irq *ext_irq)
 {
-       if (ext_irq->number_of_interrupts > 0) {
-#ifdef CONFIG_IA64
-               req->irq = acpi_register_irq(ext_irq->interrupts[0],
-                         ext_irq->active_high_low, ext_irq->edge_level);
-#else
-               req->irq = ext_irq->interrupts[0];
-#endif
-       }
+       if (ext_irq->number_of_interrupts > 0)
+               req->irq = acpi_register_gsi(ext_irq->interrupts[0],
+                         ext_irq->edge_level, ext_irq->active_high_low);
        return AE_OK;
 }
 
 static acpi_status acpi_serial_irq(struct serial_struct *req,
                                   struct acpi_resource_irq *irq)
 {
-       if (irq->number_of_interrupts > 0) {
-#ifdef CONFIG_IA64
-               req->irq = acpi_register_irq(irq->interrupts[0],
-                         irq->active_high_low, irq->edge_level);
-#else
-               req->irq = irq->interrupts[0];
-#endif
-       }
+       if (irq->number_of_interrupts > 0)
+               req->irq = acpi_register_gsi(irq->interrupts[0],
+                         irq->edge_level, irq->active_high_low);
        return AE_OK;
 }
 
index e7b573f..4be2e60 100644 (file)
@@ -183,16 +183,12 @@ setup_serial_hcdp(void *tablep)
                }
 
                if (HCDP_IRQ_SUPPORTED(hcdp_dev)) {
-#ifdef CONFIG_IA64
                        if (HCDP_PCI_UART(hcdp_dev))
-                               port.irq = acpi_register_irq(gsi,
-                                       ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE);
+                               port.irq = acpi_register_gsi(gsi,
+                                       ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
                        else
-                               port.irq = acpi_register_irq(gsi,
-                                       ACPI_ACTIVE_HIGH, ACPI_EDGE_SENSITIVE);
-#else
-                       port.irq = gsi;
-#endif
+                               port.irq = acpi_register_gsi(gsi,
+                                       ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH);
                        port.flags |= UPF_AUTO_IRQ;
 
                        if (HCDP_PCI_UART(hcdp_dev))
index a0d988d..2f215ce 100644 (file)
@@ -361,9 +361,6 @@ static int __devinit check_resources(struct pnp_option *option)
                            ((port->min == 0x2f8) ||
                             (port->min == 0x3f8) ||
                             (port->min == 0x2e8) ||
-#ifdef CONFIG_X86_PC9800
-                            (port->min == 0x8b0) ||
-#endif
                             (port->min == 0x3e8)))
                                return 1;
        }
@@ -437,7 +434,7 @@ static struct pnp_driver serial_pnp_driver = {
        .name           = "serial",
        .id_table       = pnp_dev_table,
        .probe          = serial_pnp_probe,
-       .remove         = serial_pnp_remove,
+       .remove         = __devexit_p(serial_pnp_remove),
 };
 
 static int __init serial8250_pnp_init(void)
index 23f452a..e5ce98e 100644 (file)
@@ -259,6 +259,7 @@ config SERIAL_S3C2410
 config SERIAL_S3C2410_CONSOLE
        bool "Support for console on S3C2410 serial port"
        depends on SERIAL_S3C2410=y
+       select SERIAL_CORE_CONSOLE
        help
          Allow selection of the S3C2410 on-board serial ports for use as
          an virtual console.
@@ -517,19 +518,6 @@ config V850E_UART_CONSOLE
        depends on V850E_UART
        select SERIAL_CORE_CONSOLE
 
-config SERIAL98
-       tristate "PC-9800 8251-based primary serial port support"
-       depends on X86_PC9800
-       select SERIAL_CORE
-       help
-         If you want to use standard primary serial ports on PC-9800, 
-         say Y.  Otherwise, say N.
-
-config SERIAL98_CONSOLE
-        bool "Support for console on PC-9800 standard serial port"
-        depends on SERIAL98=y
-       select SERIAL_CORE_CONSOLE
-
 config SERIAL_SH_SCI
        tristate "SH SCI(F) serial port support"
        depends on SUPERH || H8300
index 1252dfb..c2eb159 100644 (file)
@@ -33,7 +33,6 @@ obj-$(CONFIG_SERIAL_68328) += 68328serial.o
 obj-$(CONFIG_SERIAL_68360) += 68360serial.o
 obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o
 obj-$(CONFIG_V850E_UART) += v850e_uart.o
-obj-$(CONFIG_SERIAL98) += serial98.o
 obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
 obj-$(CONFIG_SERIAL_AU1X00) += au1x00_uart.o
 obj-$(CONFIG_SERIAL_DZ) += dz.o
index f902474..c91f6b1 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/hardware/amba.h>
+#include <asm/hardware/clock.h>
 
 #if defined(CONFIG_SERIAL_AMBA_PL011_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 #define SUPPORT_SYSRQ
@@ -68,6 +69,7 @@
  */
 struct uart_amba_port {
        struct uart_port        port;
+       struct clk              *clk;
        unsigned int            im;     /* interrupt mask */
        unsigned int            old_status;
 };
@@ -351,12 +353,21 @@ static int pl011_startup(struct uart_port *port)
        unsigned int cr;
        int retval;
 
+       /*
+        * Try to enable the clock producer.
+        */
+       retval = clk_enable(uap->clk);
+       if (retval)
+               goto out;
+
+       uap->port.uartclk = clk_get_rate(uap->clk);
+
        /*
         * Allocate the IRQ
         */
        retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
        if (retval)
-               goto out;
+               goto clk_dis;
 
        writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
               uap->port.membase + UART011_IFLS);
@@ -391,6 +402,8 @@ static int pl011_startup(struct uart_port *port)
 
        return 0;
 
+ clk_dis:
+       clk_disable(uap->clk);
  out:
        return retval;
 }
@@ -425,6 +438,11 @@ static void pl011_shutdown(struct uart_port *port)
        val = readw(uap->port.membase + UART011_LCRH);
        val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN);
        writew(val, uap->port.membase + UART011_LCRH);
+
+       /*
+        * Shut down the clock producer
+        */
+       clk_disable(uap->clk);
 }
 
 static void
@@ -594,38 +612,40 @@ static struct uart_amba_port *amba_ports[UART_NR];
 #ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE
 
 static inline void
-pl011_console_write_char(struct uart_port *port, char ch)
+pl011_console_write_char(struct uart_amba_port *uap, char ch)
 {
        unsigned int status;
 
        do {
-               status = readw(port->membase + UART01x_FR);
+               status = readw(uap->port.membase + UART01x_FR);
        } while (status & UART01x_FR_TXFF);
-       writew(ch, port->membase + UART01x_DR);
+       writew(ch, uap->port.membase + UART01x_DR);
 }
 
 static void
 pl011_console_write(struct console *co, const char *s, unsigned int count)
 {
-       struct uart_port *port = &amba_ports[co->index]->port;
+       struct uart_amba_port *uap = amba_ports[co->index];
        unsigned int status, old_cr, new_cr;
        int i;
 
+       clk_enable(uap->clk);
+
        /*
         *      First save the CR then disable the interrupts
         */
-       old_cr = readw(port->membase + UART011_CR);
+       old_cr = readw(uap->port.membase + UART011_CR);
        new_cr = old_cr & ~UART011_CR_CTSEN;
        new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
-       writew(new_cr, port->membase + UART011_CR);
+       writew(new_cr, uap->port.membase + UART011_CR);
 
        /*
         *      Now, do each character
         */
        for (i = 0; i < count; i++) {
-               pl011_console_write_char(port, s[i]);
+               pl011_console_write_char(uap, s[i]);
                if (s[i] == '\n')
-                       pl011_console_write_char(port, '\r');
+                       pl011_console_write_char(uap, '\r');
        }
 
        /*
@@ -633,19 +653,21 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
         *      and restore the TCR
         */
        do {
-               status = readw(port->membase + UART01x_FR);
+               status = readw(uap->port.membase + UART01x_FR);
        } while (status & UART01x_FR_BUSY);
-       writew(old_cr, port->membase + UART011_CR);
+       writew(old_cr, uap->port.membase + UART011_CR);
+
+       clk_disable(uap->clk);
 }
 
 static void __init
-pl011_console_get_options(struct uart_port *port, int *baud,
+pl011_console_get_options(struct uart_amba_port *uap, int *baud,
                             int *parity, int *bits)
 {
-       if (readw(port->membase + UART011_CR) & UART01x_CR_UARTEN) {
+       if (readw(uap->port.membase + UART011_CR) & UART01x_CR_UARTEN) {
                unsigned int lcr_h, ibrd, fbrd;
 
-               lcr_h = readw(port->membase + UART011_LCRH);
+               lcr_h = readw(uap->port.membase + UART011_LCRH);
 
                *parity = 'n';
                if (lcr_h & UART01x_LCRH_PEN) {
@@ -660,10 +682,10 @@ pl011_console_get_options(struct uart_port *port, int *baud,
                else
                        *bits = 8;
 
-               ibrd = readw(port->membase + UART011_IBRD);
-               fbrd = readw(port->membase + UART011_FBRD);
+               ibrd = readw(uap->port.membase + UART011_IBRD);
+               fbrd = readw(uap->port.membase + UART011_FBRD);
 
-               *baud = port->uartclk * 4 / (64 * ibrd + fbrd);
+               *baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd);
        }
 }
 
@@ -685,10 +707,12 @@ static int __init pl011_console_setup(struct console *co, char *options)
                co->index = 0;
        uap = amba_ports[co->index];
 
+       uap->port.uartclk = clk_get_rate(uap->clk);
+
        if (options)
                uart_parse_options(options, &baud, &parity, &bits, &flow);
        else
-               pl011_console_get_options(&uap->port, &baud, &parity, &bits);
+               pl011_console_get_options(uap, &baud, &parity, &bits);
 
        return uart_set_options(&uap->port, co, baud, parity, bits, flow);
 }
@@ -747,16 +771,21 @@ static int pl011_probe(struct amba_device *dev, void *id)
        }
 
        memset(uap, 0, sizeof(struct uart_amba_port));
+       uap->clk = clk_get(&dev->dev, "UARTCLK");
+       if (IS_ERR(uap->clk)) {
+               ret = PTR_ERR(uap->clk);
+               goto unmap;
+       }
+
+       ret = clk_use(uap->clk);
+       if (ret)
+               goto putclk;
+
        uap->port.dev = &dev->dev;
        uap->port.mapbase = dev->res.start;
        uap->port.membase = base;
        uap->port.iotype = UPIO_MEM;
        uap->port.irq = dev->irq[0];
-#if 0 /* FIXME */
-       uap->port.uartclk = 14745600;
-#else
-       uap->port.uartclk = 24000000;
-#endif
        uap->port.fifosize = 16;
        uap->port.ops = &amba_pl011_pops;
        uap->port.flags = UPF_BOOT_AUTOCONF;
@@ -769,6 +798,10 @@ static int pl011_probe(struct amba_device *dev, void *id)
        if (ret) {
                amba_set_drvdata(dev, NULL);
                amba_ports[i] = NULL;
+               clk_unuse(uap->clk);
+ putclk:
+               clk_put(uap->clk);
+ unmap:
                iounmap(base);
  free:
                kfree(uap);
@@ -791,6 +824,8 @@ static int pl011_remove(struct amba_device *dev)
                        amba_ports[i] = NULL;
 
        iounmap(uap->port.membase);
+       clk_unuse(uap->clk);
+       clk_put(uap->clk);
        kfree(uap);
        return 0;
 }
index 84b4a8e..22a02bd 100644 (file)
@@ -37,7 +37,7 @@
 
 #define SERIAL_S3C2410_NAME    "ttySAC"
 #define SERIAL_S3C2410_MAJOR   204
-#define SERIAL_S3C2410_MINOR   4
+#define SERIAL_S3C2410_MINOR   64
 
 /* we can support 3 uarts, but not always use them */
 
index 5778788..b6cfcd2 100644 (file)
@@ -461,8 +461,8 @@ static void DAA_Coeff_Japan(IXJ *j);
 static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf);
 static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr);
 static int ixj_init_tone(IXJ *j, IXJ_TONE * ti);
-static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp);
-static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp);
+static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp);
+static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp);
 /* Serial Control Interface funtions */
 static int SCI_Control(IXJ *j, int control);
 static int SCI_Prepare(IXJ *j);
@@ -2855,7 +2855,7 @@ static void alaw2ulaw(unsigned char *buff, unsigned long len)
        }
 }
 
-static ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
+static ssize_t ixj_read(struct file * file_p, char __user *buf, size_t length, loff_t * ppos)
 {
        unsigned long i = *ppos;
        IXJ * j = get_ixj(NUM(file_p->f_dentry->d_inode));
@@ -2910,7 +2910,7 @@ static ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t *
        }
 }
 
-static ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
+static ssize_t ixj_enhanced_read(struct file * file_p, char __user *buf, size_t length,
                          loff_t * ppos)
 {
        int pre_retval;
@@ -2935,7 +2935,7 @@ static ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
        return read_retval;
 }
 
-static ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ixj_write(struct file *file_p, const char __user *buf, size_t count, loff_t * ppos)
 {
        unsigned long i = *ppos;
        IXJ *j = file_p->private_data;
@@ -2989,7 +2989,7 @@ static ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, lof
        return min(count, j->write_buffer_size);
 }
 
-static ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ixj_enhanced_write(struct file * file_p, const char __user *buf, size_t count, loff_t * ppos)
 {
        int pre_retval;
        ssize_t write_retval = 0;
@@ -5938,31 +5938,41 @@ static void ixj_testram(IXJ *j)
        ixj_WriteDSPCommand(0x3001, j); /* Test External SRAM */
 }
 
-static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp)
+static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp)
 {
-       IXJ_CADENCE *lcp;
+       ixj_cadence *lcp;
+       IXJ_CADENCE_ELEMENT __user *cep;
        IXJ_CADENCE_ELEMENT *lcep;
        IXJ_TONE ti;
+       int err;
 
-       lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
+       lcp = kmalloc(sizeof(ixj_cadence), GFP_KERNEL);
        if (lcp == NULL)
                return -ENOMEM;
-       if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)) || (unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT) )
-        {
-                kfree(lcp);
-                return -EFAULT;
-        }
+
+       err = -EFAULT;
+       if (copy_from_user(&lcp->elements_used,
+                          &cp->elements_used, sizeof(int)))
+               goto out;
+       if (copy_from_user(&lcp->termination,
+                          &cp->termination, sizeof(IXJ_CADENCE_TERM)))
+               goto out;
+       if (get_user(cep, &cp->ce))
+               goto out;
+
+       err = -EINVAL;
+       if ((unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT))
+               goto out;
+
+       err = -ENOMEM;
        lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL);
-       if (lcep == NULL) {
-               kfree(lcp);
-               return -ENOMEM;
-       }
-       if (copy_from_user(lcep, lcp->ce, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used))
-       {
-               kfree(lcep);
-               kfree(lcp);
-               return -EFAULT;
-       }
+       if (!lcep)
+               goto out;
+
+       err = -EFAULT;
+       if (copy_from_user(lcep, cep, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used))
+               goto out1;
+
        if (j->cadence_t) {
                kfree(j->cadence_t->ce);
                kfree(j->cadence_t);
@@ -5982,9 +5992,14 @@ static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp)
        }
        ixj_play_tone(j, lcp->ce[0].index);
        return 1;
+out1:
+       kfree(lcep);
+out:
+       kfree(lcp);
+       return err;
 }
 
-static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp)
+static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp)
 {
        IXJ_FILTER_CADENCE *lcp;
        lcp = kmalloc(sizeof(IXJ_FILTER_CADENCE), GFP_KERNEL);
@@ -5994,7 +6009,7 @@ static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp)
                }
                return -ENOMEM;
         }
-       if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE))) {
+       if (copy_from_user(lcp, cp, sizeof(IXJ_FILTER_CADENCE))) {
                if(ixjdebug & 0x0001) {
                        printk(KERN_INFO "Could not copy cadence to kernel\n");
                }
@@ -6206,6 +6221,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
        IXJ_TONE ti;
        IXJ_FILTER jf;
        IXJ_FILTER_RAW jfr;
+       void __user *argp = (void __user *)arg;
 
        unsigned int raise, mant;
        unsigned int minor = iminor(inode);
@@ -6251,7 +6267,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
                retval = j->serial;
                break;
        case IXJCTL_VERSION:
-               if (copy_to_user((char *) arg, ixj_c_revision, strlen(ixj_c_revision))) 
+               if (copy_to_user(argp, ixj_c_revision, strlen(ixj_c_revision))) 
                        retval = -EFAULT;
                break;
        case PHONE_RING_CADENCE:
@@ -6259,7 +6275,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
                break;
        case IXJCTL_CIDCW:
                if(arg) {
-                       if (copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID))) {
+                       if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {
                                retval = -EFAULT;
                                break;
                        }
@@ -6274,7 +6290,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
                 /* Fall through */
        case PHONE_RING_START:
                if(arg) {
-                       if (copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID))) {
+                       if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {
                                retval = -EFAULT;
                                break;
                        }
@@ -6432,22 +6448,22 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
                        samplerate = arg;
                break;
        case IXJCTL_DRYBUFFER_READ:
-               put_user(j->drybuffer, (unsigned long *) arg);
+               put_user(j->drybuffer, (unsigned long __user *) argp);
                break;
        case IXJCTL_DRYBUFFER_CLEAR:
                j->drybuffer = 0;
                break;
        case IXJCTL_FRAMES_READ:
-               put_user(j->framesread, (unsigned long *) arg);
+               put_user(j->framesread, (unsigned long __user *) argp);
                break;
        case IXJCTL_FRAMES_WRITTEN:
-               put_user(j->frameswritten, (unsigned long *) arg);
+               put_user(j->frameswritten, (unsigned long __user *) argp);
                break;
        case IXJCTL_READ_WAIT:
-               put_user(j->read_wait, (unsigned long *) arg);
+               put_user(j->read_wait, (unsigned long __user *) argp);
                break;
        case IXJCTL_WRITE_WAIT:
-               put_user(j->write_wait, (unsigned long *) arg);
+               put_user(j->write_wait, (unsigned long __user *) argp);
                break;
        case PHONE_MAXRINGS:
                j->maxrings = arg;
@@ -6573,7 +6589,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
                         12, 10, 16, 9, 8, 48, 5,
                         40, 40, 80, 40, 40, 6
                 };
-                if(copy_from_user(&pd, (void *)arg, sizeof(pd))) {
+                if(copy_from_user(&pd, argp, sizeof(pd))) {
                         retval = -EFAULT;
                        break;
                }
@@ -6590,7 +6606,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
                         default:val=proto_size[pd.type]*3;break;
                 }
                 pd.buf_min=pd.buf_max=pd.buf_opt=val;
-                if(copy_to_user((void *)arg, &pd, sizeof(pd)))
+                if(copy_to_user(argp, &pd, sizeof(pd)))
                         retval = -EFAULT;
                break;
         }
@@ -6644,7 +6660,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
                ixj_write_vmwi(j, arg);
                break;
        case IXJCTL_CID:
-               if (copy_to_user((char *) arg, &j->cid, sizeof(PHONE_CID))) 
+               if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID))) 
                        retval = -EFAULT;
                j->ex.bits.caller_id = 0;
                break;
@@ -6666,13 +6682,13 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
                break;
        case PHONE_CAPABILITIES_LIST:
                add_caps(j);
-               if (copy_to_user((char *) arg, j->caplist, sizeof(struct phone_capability) * j->caps)) 
+               if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps)) 
                        retval = -EFAULT;
                break;
        case PHONE_CAPABILITIES_CHECK:
                {
                        struct phone_capability cap;
-                       if (copy_from_user(&cap, (char *) arg, sizeof(cap))) 
+                       if (copy_from_user(&cap, argp, sizeof(cap))) 
                                retval = -EFAULT;
                        else {
                                add_caps(j);
@@ -6688,12 +6704,12 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
                j->ex.bits.pstn_ring = 0;
                break;
        case IXJCTL_SET_FILTER:
-               if (copy_from_user(&jf, (char *) arg, sizeof(jf))) 
+               if (copy_from_user(&jf, argp, sizeof(jf))) 
                        retval = -EFAULT;
                retval = ixj_init_filter(j, &jf);
                break;
        case IXJCTL_SET_FILTER_RAW:
-               if (copy_from_user(&jfr, (char *) arg, sizeof(jfr))) 
+               if (copy_from_user(&jfr, argp, sizeof(jfr))) 
                        retval = -EFAULT;
                else
                        retval = ixj_init_filter_raw(j, &jfr);
@@ -6705,19 +6721,19 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
                        retval = j->filter_hist[arg];
                break;
        case IXJCTL_INIT_TONE:
-               if (copy_from_user(&ti, (char *) arg, sizeof(ti)))
+               if (copy_from_user(&ti, argp, sizeof(ti)))
                        retval = -EFAULT;
                else
                        retval = ixj_init_tone(j, &ti);
                break;
        case IXJCTL_TONE_CADENCE:
-               retval = ixj_build_cadence(j, (IXJ_CADENCE *) arg);
+               retval = ixj_build_cadence(j, argp);
                break;
        case IXJCTL_FILTER_CADENCE:
-               retval = ixj_build_filter_cadence(j, (IXJ_FILTER_CADENCE *) arg);
+               retval = ixj_build_filter_cadence(j, argp);
                break;
        case IXJCTL_SIGCTL:
-               if (copy_from_user(&j->sigdef, (char *)arg, sizeof(IXJ_SIGDEF))) {
+               if (copy_from_user(&j->sigdef, argp, sizeof(IXJ_SIGDEF))) {
                        retval = -EFAULT;
                        break;
                }
index 65d837d..ad23b28 100644 (file)
@@ -1166,6 +1166,12 @@ typedef struct {
 *
 ******************************************************************************/
 
+typedef struct {
+       int elements_used;
+       IXJ_CADENCE_TERM termination;
+       IXJ_CADENCE_ELEMENT *ce;
+} ixj_cadence;
+
 typedef struct {
        struct phone_device p;
        struct timer_list timer;
@@ -1220,8 +1226,8 @@ typedef struct {
        char tone_index;
        char tone_state;
        char maxrings;
-       IXJ_CADENCE *cadence_t;
-       IXJ_CADENCE *cadence_r;
+       ixj_cadence *cadence_t;
+       ixj_cadence *cadence_r;
        int tone_cadence_state;
        IXJ_CADENCE_F cadence_f[6];
        DTMF dtmf;
index 4c74401..0e805e4 100644 (file)
@@ -7,7 +7,7 @@ menu "USB support"
 # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
 config USB
        tristate "Support for Host-side USB"
-       depends on PCI || SA1111 || ARCH_OMAP1510 || ARCH_OMAP1610
+       depends on PCI || SA1111 || ARCH_OMAP1510 || ARCH_OMAP1610 || ARCH_LH7A404
        ---help---
          Universal Serial Bus (USB) is a specification for a serial bus
          subsystem which offers higher speeds and more features than the
index 4aa2235..96a1c02 100644 (file)
@@ -2008,6 +2008,7 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
 {
        struct usb_mixerdev *ms = (struct usb_mixerdev *)file->private_data;
        int i, j, val;
+       int __user *user_arg = (int __user *)arg;
 
        if (!ms->state->usbdev)
                return -ENODEV;
@@ -2034,7 +2035,7 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
                return 0;
        }
        if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, (int *)arg);
+               return put_user(SOUND_VERSION, user_arg);
        if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
                return -EINVAL;
        if (_IOC_DIR(cmd) == _IOC_READ) {
@@ -2043,27 +2044,27 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
                        val = get_rec_src(ms);
                        if (val < 0)
                                return val;
-                       return put_user(val, (int *)arg);
+                       return put_user(val, user_arg);
 
                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
                        for (val = i = 0; i < ms->numch; i++)
                                val |= 1 << ms->ch[i].osschannel;
-                       return put_user(val, (int *)arg);
+                       return put_user(val, user_arg);
 
                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
                        for (val = i = 0; i < ms->numch; i++)
                                if (ms->ch[i].slctunitid)
                                        val |= 1 << ms->ch[i].osschannel;
-                       return put_user(val, (int *)arg);
+                       return put_user(val, user_arg);
 
                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
                        for (val = i = 0; i < ms->numch; i++)
                                if (ms->ch[i].flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))
                                        val |= 1 << ms->ch[i].osschannel;
-                       return put_user(val, (int *)arg);
+                       return put_user(val, user_arg);
                        
                case SOUND_MIXER_CAPS:
-                       return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg);
+                       return put_user(SOUND_CAP_EXCL_INPUT, user_arg);
 
                default:
                        i = _IOC_NR(cmd);
@@ -2071,7 +2072,7 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
                                return -EINVAL;
                        for (j = 0; j < ms->numch; j++) {
                                if (ms->ch[j].osschannel == i) {
-                                       return put_user(ms->ch[j].value, (int *)arg);
+                                       return put_user(ms->ch[j].value, user_arg);
                                }
                        }
                        return -EINVAL;
@@ -2082,7 +2083,7 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
        ms->modcnt++;
        switch (_IOC_NR(cmd)) {
        case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-               if (get_user(val, (int *)arg))
+               if (get_user(val, user_arg))
                        return -EFAULT;
                return set_rec_src(ms, val);
 
@@ -2093,11 +2094,11 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
                for (j = 0; j < ms->numch && ms->ch[j].osschannel != i; j++);
                if (j >= ms->numch)
                        return -EINVAL;
-               if (get_user(val, (int *)arg))
+               if (get_user(val, user_arg))
                        return -EFAULT;
                if (wrmixer(ms, j, val))
                        return -EIO;
-               return put_user(ms->ch[j].value, (int *)arg);
+               return put_user(ms->ch[j].value, user_arg);
        }
 }
 
@@ -2370,6 +2371,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
 {
        struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
        struct usb_audio_state *s = as->state;
+       int __user *user_arg = (int __user *)arg;
        unsigned long flags;
        audio_buf_info abinfo;
        count_info cinfo;
@@ -2387,7 +2389,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
 #endif
        switch (cmd) {
        case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, (int *)arg);
+               return put_user(SOUND_VERSION, user_arg);
 
        case SNDCTL_DSP_SYNC:
                if (file->f_mode & FMODE_WRITE)
@@ -2399,7 +2401,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
 
        case SNDCTL_DSP_GETCAPS:
                return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | 
-                               DSP_CAP_MMAP | DSP_CAP_BATCH, (int *)arg);
+                               DSP_CAP_MMAP | DSP_CAP_BATCH, user_arg);
 
        case SNDCTL_DSP_RESET:
                if (file->f_mode & FMODE_WRITE) {
@@ -2413,7 +2415,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                return 0;
 
        case SNDCTL_DSP_SPEED:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, user_arg))
                        return -EFAULT;
                if (val >= 0) {
                        if (val < 4000)
@@ -2423,10 +2425,12 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                        if (set_format(as, file->f_mode, AFMT_QUERY, val))
                                return -EIO;
                }
-               return put_user((file->f_mode & FMODE_READ) ? as->usbin.dma.srate : as->usbout.dma.srate, (int *)arg);
+               return put_user((file->f_mode & FMODE_READ) ? 
+                               as->usbin.dma.srate : as->usbout.dma.srate,
+                               user_arg);
 
        case SNDCTL_DSP_STEREO:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, user_arg))
                        return -EFAULT;
                val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
                if (val)
@@ -2438,7 +2442,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                return 0;
 
        case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, user_arg))
                        return -EFAULT;
                if (val != 0) {
                        val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
@@ -2450,14 +2454,14 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                                return -EIO;
                }
                val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
-               return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, (int *)arg);
+               return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, user_arg);
 
        case SNDCTL_DSP_GETFMTS: /* Returns a mask */
                return put_user(AFMT_U8 | AFMT_U16_LE | AFMT_U16_BE |
-                               AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE, (int *)arg);
+                               AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE, user_arg);
 
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, (int *)arg))
+               if (get_user(val, user_arg))
                        return -EFAULT;
                if (val != AFMT_QUERY) {
                        if (hweight32(val) != 1)
@@ -2471,7 +2475,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                                return -EIO;
                }
                val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
-               return put_user(val2 & ~AFMT_STEREO, (int *)arg);
+               return put_user(val2 & ~AFMT_STEREO, user_arg);
 
        case SNDCTL_DSP_POST:
                return 0;
@@ -2482,10 +2486,10 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                        val |= PCM_ENABLE_INPUT;
                if (file->f_mode & FMODE_WRITE && as->usbout.flags & FLG_RUNNING) 
                        val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, (int *)arg);
+               return put_user(val, user_arg);
 
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, user_arg))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
@@ -2543,7 +2547,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                spin_lock_irqsave(&as->lock, flags);
                val = as->usbout.dma.count;
                spin_unlock_irqrestore(&as->lock, flags);
-               return put_user(val, (int *)arg);
+               return put_user(val, user_arg);
 
        case SNDCTL_DSP_GETIPTR:
                if (!(file->f_mode & FMODE_READ))
@@ -2577,14 +2581,14 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                if (file->f_mode & FMODE_WRITE) {
                        if ((val = prog_dmabuf_out(as)))
                                return val;
-                       return put_user(as->usbout.dma.fragsize, (int *)arg);
+                       return put_user(as->usbout.dma.fragsize, user_arg);
                }
                if ((val = prog_dmabuf_in(as)))
                        return val;
-               return put_user(as->usbin.dma.fragsize, (int *)arg);
+               return put_user(as->usbin.dma.fragsize, user_arg);
 
        case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, user_arg))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        as->usbin.dma.ossfragshift = val & 0xffff;
@@ -2612,7 +2616,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                if ((file->f_mode & FMODE_READ && as->usbin.dma.subdivision) ||
                    (file->f_mode & FMODE_WRITE && as->usbout.dma.subdivision))
                        return -EINVAL;
-               if (get_user(val, (int *)arg))
+               if (get_user(val, user_arg))
                        return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
@@ -2623,15 +2627,17 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
                return 0;
 
        case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ? as->usbin.dma.srate : as->usbout.dma.srate, (int *)arg);
+               return put_user((file->f_mode & FMODE_READ) ? 
+                               as->usbin.dma.srate : as->usbout.dma.srate,
+                               user_arg);
 
        case SOUND_PCM_READ_CHANNELS:
                val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
-               return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, (int *)arg);
+               return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, user_arg);
 
        case SOUND_PCM_READ_BITS:
                val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
-               return put_user(AFMT_IS16BIT(val2) ? 16 : 8, (int *)arg);
+               return put_user(AFMT_IS16BIT(val2) ? 16 : 8, user_arg);
 
        case SOUND_PCM_WRITE_FILTER:
        case SNDCTL_DSP_SETSYNCRO:
index 0c2ca79..e4c5c6d 100644 (file)
@@ -27,6 +27,7 @@
  *     v0.22 - probe only the control interface. if usbcore doesn't choose the
  *             config we want, sysadmin changes bConfigurationValue in sysfs.
  *     v0.23 - use softirq for rx processing, as needed by tty layer
+ *     v0.24 - change probe method to evaluate CDC union descriptor
  */
 
 /*
@@ -60,6 +61,8 @@
 #include <linux/usb.h>
 #include <asm/byteorder.h>
 
+#include "cdc-acm.h"
+
 /*
  * Version Information
  */
 #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"
 #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
 
-/*
- * CMSPAR, some architectures can't have space and mark parity.
- */
-
-#ifndef CMSPAR
-#define CMSPAR                 0
-#endif
-
-/*
- * Major and minor numbers.
- */
-
-#define ACM_TTY_MAJOR          166
-#define ACM_TTY_MINORS         32
-
-/*
- * Requests.
- */
-
-#define USB_RT_ACM             (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
-
-#define ACM_REQ_COMMAND                0x00
-#define ACM_REQ_RESPONSE       0x01
-#define ACM_REQ_SET_FEATURE    0x02
-#define ACM_REQ_GET_FEATURE    0x03
-#define ACM_REQ_CLEAR_FEATURE  0x04
-
-#define ACM_REQ_SET_LINE       0x20
-#define ACM_REQ_GET_LINE       0x21
-#define ACM_REQ_SET_CONTROL    0x22
-#define ACM_REQ_SEND_BREAK     0x23
-
-/*
- * IRQs.
- */
-
-#define ACM_IRQ_NETWORK                0x00
-#define ACM_IRQ_LINE_STATE     0x20
-
-/*
- * Output control lines.
- */
-
-#define ACM_CTRL_DTR           0x01
-#define ACM_CTRL_RTS           0x02
-
-/*
- * Input control lines and line errors.
- */
-
-#define ACM_CTRL_DCD           0x01
-#define ACM_CTRL_DSR           0x02
-#define ACM_CTRL_BRK           0x04
-#define ACM_CTRL_RI            0x08
-
-#define ACM_CTRL_FRAMING       0x10
-#define ACM_CTRL_PARITY                0x20
-#define ACM_CTRL_OVERRUN       0x40
-
-/*
- * Line speed and caracter encoding.
- */
-
-struct acm_line {
-       __u32 speed;
-       __u8 stopbits;
-       __u8 parity;
-       __u8 databits;
-} __attribute__ ((packed));
-
-/*
- * Internal driver structures.
- */
-
-struct acm {
-       struct usb_device *dev;                         /* the corresponding usb device */
-       struct usb_interface *control;                  /* control interface */
-       struct usb_interface *data;                     /* data interface */
-       struct tty_struct *tty;                         /* the corresponding tty */
-       struct urb *ctrlurb, *readurb, *writeurb;       /* urbs */
-       struct acm_line line;                           /* line coding (bits, stop, parity) */
-       struct work_struct work;                        /* work queue entry for line discipline waking up */
-       struct tasklet_struct bh;                       /* rx processing */
-       unsigned int ctrlin;                            /* input control lines (DCD, DSR, RI, break, overruns) */
-       unsigned int ctrlout;                           /* output control lines (DTR, RTS) */
-       unsigned int writesize;                         /* max packet size for the output bulk endpoint */
-       unsigned int used;                              /* someone has this acm's device open */
-       unsigned int minor;                             /* acm minor number */
-       unsigned char throttle;                         /* throttled by tty layer */
-       unsigned char clocal;                           /* termios CLOCAL */
-};
-
 static struct usb_driver acm_driver;
 static struct tty_driver *acm_tty_driver;
 static struct acm *acm_table[ACM_TTY_MINORS];
 
+static DECLARE_MUTEX(open_sem);
+
 #define ACM_READY(acm) (acm && acm->dev && acm->used)
 
 /*
@@ -310,12 +223,14 @@ static void acm_write_bulk(struct urb *urb, struct pt_regs *regs)
        struct acm *acm = (struct acm *)urb->context;
 
        if (!ACM_READY(acm))
-               return;
+               goto out;
 
        if (urb->status)
                dbg("nonzero write bulk status received: %d", urb->status);
 
        schedule_work(&acm->work);
+out:
+       acm->ready_for_write = 1;
 }
 
 static void acm_softint(void *private)
@@ -346,22 +261,23 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
        tty->driver_data = acm;
        acm->tty = tty;
 
-        lock_kernel();
+        down(&open_sem);
 
-       if (acm->used++) {
-                unlock_kernel();
-                return 0;
+       if (acm->used) {
+               goto done;
         }
 
-        unlock_kernel();
-
        acm->ctrlurb->dev = acm->dev;
-       if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL))
+       if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) {
                dbg("usb_submit_urb(ctrl irq) failed");
+               goto bail_out;
+       }
 
        acm->readurb->dev = acm->dev;
-       if (usb_submit_urb(acm->readurb, GFP_KERNEL))
+       if (usb_submit_urb(acm->readurb, GFP_KERNEL)) {
                dbg("usb_submit_urb(read bulk) failed");
+               goto bail_out_and_unlink;
+       }
 
        acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS);
 
@@ -369,7 +285,16 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
           otherwise it is scheduled, and with high data rates data can get lost. */
        tty->low_latency = 1;
 
+done:
+       acm->used++;
+       up(&open_sem);
        return 0;
+
+bail_out_and_unlink:
+       usb_unlink_urb(acm->ctrlurb);
+bail_out:
+       up(&open_sem);
+       return -EIO;
 }
 
 static void acm_tty_close(struct tty_struct *tty, struct file *filp)
@@ -379,6 +304,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
        if (!acm || !acm->used)
                return;
 
+       down(&open_sem);
        if (!--acm->used) {
                if (acm->dev) {
                        acm_set_control(acm, acm->ctrlout = 0);
@@ -394,6 +320,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
                        kfree(acm);
                }
        }
+       up(&open_sem);
 }
 
 static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
@@ -403,7 +330,7 @@ static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned c
 
        if (!ACM_READY(acm))
                return -EINVAL;
-       if (acm->writeurb->status == -EINPROGRESS)
+       if (!acm->ready_for_write)
                return 0;
        if (!count)
                return 0;
@@ -419,10 +346,11 @@ static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned c
        acm->writeurb->transfer_buffer_length = count;
        acm->writeurb->dev = acm->dev;
 
-       /* GFP_KERNEL probably works if from_user */
-       stat = usb_submit_urb(acm->writeurb, GFP_ATOMIC);
+       acm->ready_for_write = 0;
+       stat = usb_submit_urb(acm->writeurb, GFP_NOIO);
        if (stat < 0) {
                dbg("usb_submit_urb(write bulk) failed");
+               acm->ready_for_write = 1;
                return stat;
        }
 
@@ -434,7 +362,7 @@ static int acm_tty_write_room(struct tty_struct *tty)
        struct acm *acm = tty->driver_data;
        if (!ACM_READY(acm))
                return -EINVAL;
-       return acm->writeurb->status == -EINPROGRESS ? 0 : acm->writesize;
+       return !acm->ready_for_write ? 0 : acm->writesize;
 }
 
 static int acm_tty_chars_in_buffer(struct tty_struct *tty)
@@ -442,7 +370,7 @@ static int acm_tty_chars_in_buffer(struct tty_struct *tty)
        struct acm *acm = tty->driver_data;
        if (!ACM_READY(acm))
                return -EINVAL;
-       return acm->writeurb->status == -EINPROGRESS ? acm->writeurb->transfer_buffer_length : 0;
+       return !acm->ready_for_write ? acm->writeurb->transfer_buffer_length : 0;
 }
 
 static void acm_tty_throttle(struct tty_struct *tty)
@@ -567,77 +495,102 @@ static void acm_tty_set_termios(struct tty_struct *tty, struct termios *termios_
  * USB probe and disconnect routines.
  */
 
-#define CHECK_XFERTYPE(descr, xfer_type) (((descr)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == xfer_type)
-                       
 static int acm_probe (struct usb_interface *intf,
                      const struct usb_device_id *id)
 {
-       struct usb_device *dev;
+       struct union_desc *union_header = NULL;
+       char *buffer = intf->altsetting->extra;
+       int buflen = intf->altsetting->extralen;
+       struct usb_interface *control_interface;
+       struct usb_interface *data_interface;
+       struct usb_endpoint_descriptor *epctrl;
+       struct usb_endpoint_descriptor *epread;
+       struct usb_endpoint_descriptor *epwrite;
+       struct usb_device *usb_dev = interface_to_usbdev(intf);
        struct acm *acm;
-       struct usb_host_config *cfacm;
-       struct usb_interface *data = NULL;
-       struct usb_host_interface *ifcom, *ifdata = NULL;
-       struct usb_endpoint_descriptor *epctrl = NULL;
-       struct usb_endpoint_descriptor *epread = NULL;
-       struct usb_endpoint_descriptor *epwrite = NULL;
-       int readsize, ctrlsize, minor, j;
-       unsigned char *buf;
-
-       dev = interface_to_usbdev (intf);
-
-       cfacm = dev->actconfig;
-
-       /* We know we're probe()d with the control interface. */
-       ifcom = intf->cur_altsetting;
-
-       /* ACM doesn't guarantee the data interface is
-        * adjacent to the control interface, or that if one
-        * is there it's not for call management ... so find
-        * it
-        */
-       for (j = 0; j < cfacm->desc.bNumInterfaces; j++) {
-               ifdata = cfacm->interface[j]->cur_altsetting;
-               data = cfacm->interface[j];
-
-               if (ifdata->desc.bInterfaceClass == USB_CLASS_CDC_DATA
-                   && ifdata->desc.bNumEndpoints == 2) {
-                       
-                       epctrl = &ifcom->endpoint[0].desc;
-                       epread = &ifdata->endpoint[0].desc;
-                       epwrite = &ifdata->endpoint[1].desc;
-
-                       if ((epctrl->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN
-                           || !CHECK_XFERTYPE(epctrl,  USB_ENDPOINT_XFER_INT)
-                           || !CHECK_XFERTYPE(epread,  USB_ENDPOINT_XFER_BULK)
-                           || !CHECK_XFERTYPE(epwrite, USB_ENDPOINT_XFER_BULK)
-                           || ((epread->bEndpointAddress & USB_DIR_IN)
-                               ^ (epwrite->bEndpointAddress & USB_DIR_IN)) != USB_DIR_IN) {
-                               /* not suitable */
-                               goto next_interface;
-                       }
-                       
-                       if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) {
-                               /* descriptors are swapped */
-                               epread = &ifdata->endpoint[1].desc;
-                               epwrite = &ifdata->endpoint[0].desc;
-                       }
-                       dev_dbg(&intf->dev, "found data interface at %d\n", j);
-                       break;
-               } else {
-next_interface:
-                       ifdata = NULL;
-                       data = NULL;
+       int minor;
+       int ctrlsize,readsize;
+       char *buf;
+
+       if (!buffer) {
+               err("Wierd descriptor references");
+               return -EINVAL;
+       }
+
+       while (buflen > 0) {
+               if (buffer [1] != USB_DT_CS_INTERFACE) {
+                       err("skipping garbage");
+                       goto next_desc;
                }
+
+               switch (buffer [2]) {
+                       case CDC_UNION_TYPE: /* we've found it */
+                               if (union_header) {
+                                       err("More than one union descriptor, skipping ...");
+                                       goto next_desc;
+                               }
+                               union_header = (struct union_desc *)buffer;
+                               break;
+                       default:
+                               err("Ignoring extra header");
+                               break;
+                       }
+next_desc:
+               buflen -= buffer[0];
+               buffer += buffer[0];
+       }
+
+       if (!union_header) {
+               dev_dbg(&intf->dev,"No union descriptor, giving up\n");
+               return -ENODEV;
        }
 
-       /* there's been a problem */
-       if (!ifdata) {
-               dev_dbg(&intf->dev, "data interface not found\n");
+       control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
+       data_interface = usb_ifnum_to_if(usb_dev, union_header->bSlaveInterface0);
+       if (!control_interface || !data_interface) {
+               dev_dbg(&intf->dev,"no interfaces\n");
                return -ENODEV;
+       }
+
+       if (usb_interface_claimed(data_interface)) { /* valid in this context */
+               dev_dbg(&intf->dev,"The data interface isn't available\n");
+               return -EBUSY;
+       }
+
+       /*workaround for switched interfaces */
+       if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) {
+               if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) {
+                       struct usb_interface *t;
+                       dev_dbg(&intf->dev,"Your device has switched interfaces.\n");
 
+                       t = control_interface;
+                       control_interface = data_interface;
+                       data_interface = t;
+               } else {
+                       return -EINVAL;
+               }
        }
+       if (data_interface->cur_altsetting->desc.bNumEndpoints < 2)
+               return -EINVAL;
+
+       epctrl = &control_interface->cur_altsetting->endpoint[0].desc;
+       epread = &data_interface->cur_altsetting->endpoint[0].desc;
+       epwrite = &data_interface->cur_altsetting->endpoint[1].desc;
+
 
+       /* workaround for switched endpoints */
+       if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) {
+               /* descriptors are swapped */
+               struct usb_endpoint_descriptor *t;
+               dev_dbg(&intf->dev,"The data interface has switched endpoints\n");
+               
+               t = epread;
+               epread = epwrite;
+               epwrite = t;
+       }
+       dbg("interfaces are valid");
        for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
+
        if (acm_table[minor]) {
                err("no more free acm devices");
                return -ENODEV;
@@ -647,20 +600,21 @@ next_interface:
                dev_dbg(&intf->dev, "out of memory (acm kmalloc)\n");
                return -ENOMEM;
        }
-       
        memset(acm, 0, sizeof(struct acm));
 
        ctrlsize = epctrl->wMaxPacketSize;
        readsize = epread->wMaxPacketSize;
        acm->writesize = epwrite->wMaxPacketSize;
-       acm->control = intf;
-       acm->data = data;
+       acm->control = control_interface;
+       acm->data = data_interface;
        acm->minor = minor;
-       acm->dev = dev;
+       acm->dev = usb_dev;
 
        acm->bh.func = acm_rx_tasklet;
        acm->bh.data = (unsigned long) acm;
        INIT_WORK(&acm->work, acm_softint, acm);
+       acm->ready_for_write = 1;
+
 
        if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
                dev_dbg(&intf->dev, "out of memory (buf kmalloc)\n");
@@ -693,29 +647,17 @@ next_interface:
                return -ENOMEM;
        }
 
-       usb_fill_int_urb(acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress),
-               buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
+       usb_fill_int_urb(acm->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress),
+                        buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
 
-       usb_fill_bulk_urb(acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
-               buf += ctrlsize, readsize, acm_read_bulk, acm);
+       usb_fill_bulk_urb(acm->readurb, usb_dev, usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress),
+                         buf += ctrlsize, readsize, acm_read_bulk, acm);
        acm->readurb->transfer_flags |= URB_NO_FSBR;
 
-       usb_fill_bulk_urb(acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
-               buf += readsize, acm->writesize, acm_write_bulk, acm);
+       usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
+                         buf += readsize, acm->writesize, acm_write_bulk, acm);
        acm->writeurb->transfer_flags |= URB_NO_FSBR;
 
-       if ( (j = usb_driver_claim_interface(&acm_driver, data, acm)) != 0) {
-               err("claim failed");
-               usb_free_urb(acm->ctrlurb);
-               usb_free_urb(acm->readurb);
-               usb_free_urb(acm->writeurb);
-               kfree(acm);
-               kfree(buf);
-               return j;
-       } 
-
-       tty_register_device(acm_tty_driver, minor, &intf->dev);
-
        dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
 
        acm_set_control(acm, acm->ctrlout);
@@ -724,11 +666,14 @@ next_interface:
        acm->line.databits = 8;
        acm_set_line(acm, &acm->line);
 
+       usb_driver_claim_interface(&acm_driver, data_interface, acm);
+
+       tty_register_device(acm_tty_driver, minor, &intf->dev);
+
        acm_table[minor] = acm;
        usb_set_intfdata (intf, acm);
        return 0;
 }
-#undef CHECK_XFERTYPE
 
 static void acm_disconnect(struct usb_interface *intf)
 {
@@ -746,6 +691,8 @@ static void acm_disconnect(struct usb_interface *intf)
        usb_unlink_urb(acm->readurb);
        usb_unlink_urb(acm->writeurb);
 
+       flush_scheduled_work(); /* wait for acm_softint */
+
        kfree(acm->ctrlurb->transfer_buffer);
 
        usb_driver_release_interface(&acm_driver, acm->data);
index 8836be0..20a717f 100644 (file)
@@ -75,6 +75,7 @@
 #define IOCNR_HP_SET_CHANNEL           4
 #define IOCNR_GET_BUS_ADDRESS          5
 #define IOCNR_GET_VID_PID              6
+#define IOCNR_SOFT_RESET               7
 /* Get device_id string: */
 #define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
 /* The following ioctls were added for http://hpoj.sourceforge.net: */
@@ -90,6 +91,8 @@
 #define LPIOC_GET_BUS_ADDRESS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_BUS_ADDRESS, len)
 /* Get two-int array: [0]=vendor ID, [1]=product ID: */
 #define LPIOC_GET_VID_PID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_VID_PID, len)
+/* Perform class specific soft reset */
+#define LPIOC_SOFT_RESET _IOC(_IOC_NONE, 'P', IOCNR_SOFT_RESET, 0);
 
 /*
  * A DEVICE_ID string may include the printer's serial number.
@@ -587,6 +590,13 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                                        usblp->minor, twoints[0], twoints[1]);
                                break;
 
+                       case IOCNR_SOFT_RESET:
+                               if (_IOC_DIR(cmd) != _IOC_NONE) {
+                                       retval = -EINVAL;
+                                       goto done;
+                               }
+                               retval = usblp_reset(usblp);
+                               break;
                        default:
                                retval = -ENOTTY;
                }
@@ -761,6 +771,7 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count,
                        usblp->minor, usblp->readurb->status);
                usblp->readurb->dev = usblp->dev;
                usblp->readcount = 0;
+               usblp->rcomplete = 0;
                if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0)
                        dbg("error submitting urb");
                count = -EIO;
index 30b4378..5541363 100644 (file)
@@ -589,6 +589,8 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbyte
                bus = list_entry(buslist, struct usb_bus, bus_list);
 
                /* recurse through all children of the root hub */
+               if (!bus->root_hub)
+                       continue;
                down(&bus->root_hub->serialize);
                ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
                up(&bus->root_hub->serialize);
index 734ba0a..3b7f089 100644 (file)
@@ -558,7 +558,7 @@ static int proc_control(struct dev_state *ps, void __user *arg)
                        if (usbfs_snoop) {
                                dev_info(&dev->dev, "control read: data ");
                                for (j = 0; j < ctrl.wLength; ++j)
-                                       printk ("%02x ", (unsigned char)((char *)ctrl.data)[j]);
+                                       printk ("%02x ", (unsigned char)(tbuf)[j]);
                                printk("\n");
                        }
                        if (copy_to_user(ctrl.data, tbuf, ctrl.wLength)) {
@@ -578,7 +578,7 @@ static int proc_control(struct dev_state *ps, void __user *arg)
                if (usbfs_snoop) {
                        dev_info(&dev->dev, "control write: data: ");
                        for (j = 0; j < ctrl.wLength; ++j)
-                               printk ("%02x ", (unsigned char)((char *)ctrl.data)[j]);
+                               printk ("%02x ", (unsigned char)(tbuf)[j]);
                        printk("\n");
                }
                i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType,
@@ -719,7 +719,7 @@ static int proc_connectinfo(struct dev_state *ps, void __user *arg)
 
 static int proc_resetdevice(struct dev_state *ps)
 {
-       return usb_reset_device(ps->dev);
+       return __usb_reset_device(ps->dev);
 
 }
 
@@ -862,7 +862,7 @@ static int proc_submiturb(struct dev_state *ps, void __user *arg)
                isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb.number_of_packets;
                if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL)))
                        return -ENOMEM;
-               if (copy_from_user(isopkt, &((struct usbdevfs_urb *)arg)->iso_frame_desc, isofrmlen)) {
+               if (copy_from_user(isopkt, &((struct usbdevfs_urb __user *)arg)->iso_frame_desc, isofrmlen)) {
                        kfree(isopkt);
                        return -EFAULT;
                }
@@ -1023,7 +1023,7 @@ static int proc_reapurb(struct dev_state *ps, void __user *arg)
                free_async(as);
                if (ret)
                        return ret;
-               if (put_user(addr, (void **)arg))
+               if (put_user(addr, (void __user * __user *)arg))
                        return -EFAULT;
                return 0;
        }
@@ -1045,7 +1045,7 @@ static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg)
        free_async(as);
        if (ret)
                return ret;
-       if (put_user(addr, (void **)arg))
+       if (put_user(addr, (void __user * __user *)arg))
                return -EFAULT;
        return 0;
 }
@@ -1174,6 +1174,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 {
        struct dev_state *ps = (struct dev_state *)file->private_data;
        struct usb_device *dev = ps->dev;
+       void __user *p = (void __user *)arg;
        int ret = -ENOTTY;
 
        if (!(file->f_mode & FMODE_WRITE))
@@ -1187,21 +1188,21 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
        switch (cmd) {
        case USBDEVFS_CONTROL:
                snoop(&dev->dev, "%s: CONTROL\n", __FUNCTION__);
-               ret = proc_control(ps, (void __user *)arg);
+               ret = proc_control(ps, p);
                if (ret >= 0)
                        inode->i_mtime = CURRENT_TIME;
                break;
 
        case USBDEVFS_BULK:
                snoop(&dev->dev, "%s: BULK\n", __FUNCTION__);
-               ret = proc_bulk(ps, (void __user *)arg);
+               ret = proc_bulk(ps, p);
                if (ret >= 0)
                        inode->i_mtime = CURRENT_TIME;
                break;
 
        case USBDEVFS_RESETEP:
                snoop(&dev->dev, "%s: RESETEP\n", __FUNCTION__);
-               ret = proc_resetep(ps, (void __user *)arg);
+               ret = proc_resetep(ps, p);
                if (ret >= 0)
                        inode->i_mtime = CURRENT_TIME;
                break;
@@ -1213,71 +1214,71 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 
        case USBDEVFS_CLEAR_HALT:
                snoop(&dev->dev, "%s: CLEAR_HALT\n", __FUNCTION__);
-               ret = proc_clearhalt(ps, (void __user *)arg);
+               ret = proc_clearhalt(ps, p);
                if (ret >= 0)
                        inode->i_mtime = CURRENT_TIME;
                break;
 
        case USBDEVFS_GETDRIVER:
                snoop(&dev->dev, "%s: GETDRIVER\n", __FUNCTION__);
-               ret = proc_getdriver(ps, (void __user *)arg);
+               ret = proc_getdriver(ps, p);
                break;
 
        case USBDEVFS_CONNECTINFO:
                snoop(&dev->dev, "%s: CONNECTINFO\n", __FUNCTION__);
-               ret = proc_connectinfo(ps, (void __user *)arg);
+               ret = proc_connectinfo(ps, p);
                break;
 
        case USBDEVFS_SETINTERFACE:
                snoop(&dev->dev, "%s: SETINTERFACE\n", __FUNCTION__);
-               ret = proc_setintf(ps, (void __user *)arg);
+               ret = proc_setintf(ps, p);
                break;
 
        case USBDEVFS_SETCONFIGURATION:
                snoop(&dev->dev, "%s: SETCONFIGURATION\n", __FUNCTION__);
-               ret = proc_setconfig(ps, (void __user *)arg);
+               ret = proc_setconfig(ps, p);
                break;
 
        case USBDEVFS_SUBMITURB:
                snoop(&dev->dev, "%s: SUBMITURB\n", __FUNCTION__);
-               ret = proc_submiturb(ps, (void __user *)arg);
+               ret = proc_submiturb(ps, p);
                if (ret >= 0)
                        inode->i_mtime = CURRENT_TIME;
                break;
 
        case USBDEVFS_DISCARDURB:
                snoop(&dev->dev, "%s: DISCARDURB\n", __FUNCTION__);
-               ret = proc_unlinkurb(ps, (void __user *)arg);
+               ret = proc_unlinkurb(ps, p);
                break;
 
        case USBDEVFS_REAPURB:
                snoop(&dev->dev, "%s: REAPURB\n", __FUNCTION__);
-               ret = proc_reapurb(ps, (void __user *)arg);
+               ret = proc_reapurb(ps, p);
                break;
 
        case USBDEVFS_REAPURBNDELAY:
                snoop(&dev->dev, "%s: REAPURBDELAY\n", __FUNCTION__);
-               ret = proc_reapurbnonblock(ps, (void __user *)arg);
+               ret = proc_reapurbnonblock(ps, p);
                break;
 
        case USBDEVFS_DISCSIGNAL:
                snoop(&dev->dev, "%s: DISCSIGNAL\n", __FUNCTION__);
-               ret = proc_disconnectsignal(ps, (void __user *)arg);
+               ret = proc_disconnectsignal(ps, p);
                break;
 
        case USBDEVFS_CLAIMINTERFACE:
                snoop(&dev->dev, "%s: CLAIMINTERFACE\n", __FUNCTION__);
-               ret = proc_claiminterface(ps, (void __user *)arg);
+               ret = proc_claiminterface(ps, p);
                break;
 
        case USBDEVFS_RELEASEINTERFACE:
                snoop(&dev->dev, "%s: RELEASEINTERFACE\n", __FUNCTION__);
-               ret = proc_releaseinterface(ps, (void __user *)arg);
+               ret = proc_releaseinterface(ps, p);
                break;
 
        case USBDEVFS_IOCTL:
                snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__);
-               ret = proc_ioctl(ps, (void __user *) arg);
+               ret = proc_ioctl(ps, p);
                break;
        }
        up(&dev->serialize);
index da209ad..3a710e0 100644 (file)
@@ -229,7 +229,6 @@ EXPORT_SYMBOL (usb_hcd_pci_probe);
 void usb_hcd_pci_remove (struct pci_dev *dev)
 {
        struct usb_hcd          *hcd;
-       struct usb_device       *hub;
 
        hcd = pci_get_drvdata(dev);
        if (!hcd)
@@ -239,12 +238,11 @@ void usb_hcd_pci_remove (struct pci_dev *dev)
        if (in_interrupt ())
                BUG ();
 
-       hub = hcd->self.root_hub;
        if (HCD_IS_RUNNING (hcd->state))
                hcd->state = USB_STATE_QUIESCING;
 
        dev_dbg (hcd->self.controller, "roothub graceful disconnect\n");
-       usb_disconnect (&hub);
+       usb_disconnect (&hcd->self.root_hub);
 
        hcd->driver->stop (hcd);
        hcd_buffer_destroy (hcd);
index 04a8b32..ecac9fa 100644 (file)
@@ -764,8 +764,9 @@ EXPORT_SYMBOL (usb_deregister_bus);
  *
  * The USB host controller calls this function to register the root hub
  * properly with the USB subsystem.  It sets up the device properly in
- * the device model tree, and then calls usb_new_device() to register the
- * usb device.  It also assigns the root hub's USB address (always 1).
+ * the device tree and stores the root_hub pointer in the bus structure,
+ * then calls usb_new_device() to register the usb device.  It also
+ * assigns the root hub's USB address (always 1).
  */
 int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev)
 {
@@ -777,7 +778,10 @@ int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev
        memset (&usb_dev->bus->devmap.devicemap, 0,
                        sizeof usb_dev->bus->devmap.devicemap);
        set_bit (devnum, usb_dev->bus->devmap.devicemap);
-       usb_dev->state = USB_STATE_ADDRESS;
+       usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
+
+       down (&usb_bus_list_lock);
+       usb_dev->bus->root_hub = usb_dev;
 
        usb_dev->epmaxpacketin[0] = usb_dev->epmaxpacketout[0] = 64;
        retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
@@ -787,14 +791,15 @@ int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev
                return (retval < 0) ? retval : -EMSGSIZE;
        }
 
-       (void) usb_get_dev (usb_dev);
        down (&usb_dev->serialize);
        retval = usb_new_device (usb_dev);
-       if (retval)
+       up (&usb_dev->serialize);
+       if (retval) {
+               usb_dev->bus->root_hub = NULL;
                dev_err (parent_dev, "can't register root hub for %s, %d\n",
                                usb_dev->dev.bus_id, retval);
-       up (&usb_dev->serialize);
-       usb_put_dev (usb_dev);
+       }
+       up (&usb_bus_list_lock);
        return retval;
 }
 EXPORT_SYMBOL (usb_register_root_hub);
@@ -1574,11 +1579,13 @@ static void hcd_panic (void *_hcd)
        unsigned                i;
 
        /* hc's root hub is removed later removed in hcd->stop() */
-       hub->state = USB_STATE_NOTATTACHED;
+       down (&hub->serialize);
+       usb_set_device_state(hub, USB_STATE_NOTATTACHED);
        for (i = 0; i < hub->maxchild; i++) {
                if (hub->children [i])
                        usb_disconnect (&hub->children [i]);
        }
+       up (&hub->serialize);
 }
 
 /**
index f56fa80..5d04c9b 100644 (file)
@@ -244,17 +244,10 @@ extern struct usb_device *usb_alloc_dev(struct usb_device *parent,
                                        struct usb_bus *, unsigned port);
 extern int usb_new_device(struct usb_device *dev);
 extern void usb_disconnect(struct usb_device **);
-extern void usb_choose_address(struct usb_device *dev);
-extern void usb_release_address(struct usb_device *dev);
 
-/* exported to hub driver ONLY to support usb_reset_device () */
 extern int usb_get_configuration(struct usb_device *dev);
 extern void usb_destroy_configuration(struct usb_device *dev);
 
-/* use these only before the device's address has been set */
-#define usb_snddefctrl(dev)            ((PIPE_CONTROL << 30))
-#define usb_rcvdefctrl(dev)            ((PIPE_CONTROL << 30) | USB_DIR_IN)
-
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -346,7 +339,8 @@ extern void usb_deregister_bus (struct usb_bus *);
 extern int usb_register_root_hub (struct usb_device *usb_dev,
                struct device *parent_dev);
 
-static inline int hcd_register_root (struct usb_hcd *hcd)
+static inline int hcd_register_root (struct usb_device *usb_dev,
+               struct usb_hcd *hcd)
 {
        /* hcd->driver->start() reported can_wakeup, probably with
         * assistance from board's boot firmware.
@@ -356,8 +350,7 @@ static inline int hcd_register_root (struct usb_hcd *hcd)
                dev_dbg (hcd->self.controller, "supports USB remote wakeup\n");
        hcd->remote_wakeup = hcd->can_wakeup;
 
-       return usb_register_root_hub (
-               hcd_to_bus (hcd)->root_hub, hcd->self.controller);
+       return usb_register_root_hub (usb_dev, hcd->self.controller);
 }
 
 /*-------------------------------------------------------------------------*/
index cdade32..592f289 100644 (file)
@@ -9,6 +9,11 @@
  */
 
 #include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+       #define DEBUG
+#else
+       #undef DEBUG
+#endif
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/ioctl.h>
-#ifdef CONFIG_USB_DEBUG
-       #define DEBUG
-#else
-       #undef DEBUG
-#endif
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/suspend.h>
 #include "hcd.h"
 #include "hub.h"
 
+/* Protect all struct usb_device state members */
+static spinlock_t device_state_lock = SPIN_LOCK_UNLOCKED;
+
 /* Wakes up khubd */
 static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED;
 
 static LIST_HEAD(hub_event_list);      /* List of hubs needing servicing */
-static LIST_HEAD(hub_list);            /* List of all hubs (for cleanup) */
 
 static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);
 static pid_t khubd_pid = 0;                    /* PID of khubd */
@@ -229,6 +231,8 @@ static void hub_irq(struct urb *urb, struct pt_regs *regs)
 {
        struct usb_hub *hub = (struct usb_hub *)urb->context;
        int status;
+       int i;
+       unsigned long bits;
 
        spin_lock(&hub_event_lock);
        hub->urb_active = 0;
@@ -253,6 +257,11 @@ static void hub_irq(struct urb *urb, struct pt_regs *regs)
        
        /* let khubd handle things */
        case 0:                 /* we got data:  port status changed */
+               bits = 0;
+               for (i = 0; i < urb->actual_length; ++i)
+                       bits |= ((unsigned long) ((*hub->buffer)[i]))
+                                       << (i*8);
+               hub->event_bits[0] = bits;
                break;
        }
 
@@ -260,7 +269,7 @@ static void hub_irq(struct urb *urb, struct pt_regs *regs)
 
        /* Something happened, let khubd figure it out */
        if (list_empty(&hub->event_list)) {
-               list_add(&hub->event_list, &hub_event_list);
+               list_add_tail(&hub->event_list, &hub_event_list);
                wake_up(&khubd_wait);
        }
 
@@ -268,7 +277,7 @@ resubmit:
        if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0
                        /* ENODEV means we raced disconnect() */
                        && status != -ENODEV)
-               dev_err (&hub->intf->dev, "resubmit --> %d\n", urb->status);
+               dev_err (&hub->intf->dev, "resubmit --> %d\n", status);
        if (status == 0)
                hub->urb_active = 1;
 done:
@@ -632,7 +641,6 @@ static void hub_disconnect(struct usb_interface *intf)
 {
        struct usb_hub *hub = usb_get_intfdata (intf);
        DECLARE_COMPLETION(urb_complete);
-       unsigned long flags;
 
        if (!hub)
                return;
@@ -641,17 +649,13 @@ static void hub_disconnect(struct usb_interface *intf)
                highspeed_hubs--;
 
        usb_set_intfdata (intf, NULL);
-       spin_lock_irqsave(&hub_event_lock, flags);
+       spin_lock_irq(&hub_event_lock);
        hub->urb_complete = &urb_complete;
 
        /* Delete it and then reset it */
        list_del_init(&hub->event_list);
-       list_del_init(&hub->hub_list);
 
-       spin_unlock_irqrestore(&hub_event_lock, flags);
-
-       down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */
-       up(&hub->khubd_sem);
+       spin_unlock_irq(&hub_event_lock);
 
        /* assuming we used keventd, it must quiesce too */
        if (hub->has_indicators)
@@ -695,7 +699,6 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
        struct usb_device *hdev;
        struct usb_hub *hub;
        struct device *hub_dev;
-       unsigned long flags;
 
        desc = intf->cur_altsetting;
        hdev = interface_to_usbdev(intf);
@@ -711,23 +714,19 @@ descriptor_error:
        }
 
        /* Multiple endpoints? What kind of mutant ninja-hub is this? */
-       if (desc->desc.bNumEndpoints != 1) {
+       if (desc->desc.bNumEndpoints != 1)
                goto descriptor_error;
-       }
 
        endpoint = &desc->endpoint[0].desc;
 
        /* Output endpoint? Curiouser and curiouser.. */
-       if (!(endpoint->bEndpointAddress & USB_DIR_IN)) {
+       if (!(endpoint->bEndpointAddress & USB_DIR_IN))
                goto descriptor_error;
-       }
 
        /* If it's not an interrupt endpoint, we'd better punt! */
        if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-                       != USB_ENDPOINT_XFER_INT) {
+                       != USB_ENDPOINT_XFER_INT)
                goto descriptor_error;
-               return -EIO;
-       }
 
        /* We found a hub */
        dev_info (hub_dev, "USB hub found\n");
@@ -742,15 +741,8 @@ descriptor_error:
 
        INIT_LIST_HEAD(&hub->event_list);
        hub->intf = intf;
-       init_MUTEX(&hub->khubd_sem);
        INIT_WORK(&hub->leds, led_work, hub);
 
-       /* Record the new hub's existence */
-       spin_lock_irqsave(&hub_event_lock, flags);
-       INIT_LIST_HEAD(&hub->hub_list);
-       list_add(&hub->hub_list, &hub_list);
-       spin_unlock_irqrestore(&hub_event_lock, flags);
-
        usb_set_intfdata (intf, hub);
 
        if (hdev->speed == USB_SPEED_HIGH)
@@ -827,6 +819,7 @@ static int hub_reset(struct usb_hub *hub)
        return 0;
 }
 
+/* FIXME!  This routine should be subsumed into hub_reset */
 static void hub_start_disconnect(struct usb_device *hdev)
 {
        struct usb_device *parent = hdev->parent;
@@ -845,6 +838,289 @@ static void hub_start_disconnect(struct usb_device *hdev)
        dev_err(&hdev->dev, "cannot disconnect hub!\n");
 }
 
+
+static void recursively_mark_NOTATTACHED(struct usb_device *udev)
+{
+       int i;
+
+       for (i = 0; i < udev->maxchild; ++i) {
+               if (udev->children[i])
+                       recursively_mark_NOTATTACHED(udev->children[i]);
+       }
+       udev->state = USB_STATE_NOTATTACHED;
+}
+
+/**
+ * usb_set_device_state - change a device's current state (usbcore-internal)
+ * @udev: pointer to device whose state should be changed
+ * @new_state: new state value to be stored
+ *
+ * udev->state is _not_ protected by the udev->serialize semaphore.  This
+ * is so that devices can be marked as disconnected as soon as possible,
+ * without having to wait for the semaphore to be released.  Instead,
+ * changes to the state must be protected by the device_state_lock spinlock.
+ *
+ * Once a device has been added to the device tree, all changes to its state
+ * should be made using this routine.  The state should _not_ be set directly.
+ *
+ * If udev->state is already USB_STATE_NOTATTACHED then no change is made.
+ * Otherwise udev->state is set to new_state, and if new_state is
+ * USB_STATE_NOTATTACHED then all of udev's descendant's states are also set
+ * to USB_STATE_NOTATTACHED.
+ */
+void usb_set_device_state(struct usb_device *udev,
+               enum usb_device_state new_state)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&device_state_lock, flags);
+       if (udev->state == USB_STATE_NOTATTACHED)
+               ;       /* do nothing */
+       else if (new_state != USB_STATE_NOTATTACHED)
+               udev->state = new_state;
+       else
+               recursively_mark_NOTATTACHED(udev);
+       spin_unlock_irqrestore(&device_state_lock, flags);
+}
+
+
+static void choose_address(struct usb_device *udev)
+{
+       int             devnum;
+       struct usb_bus  *bus = udev->bus;
+
+       /* If khubd ever becomes multithreaded, this will need a lock */
+
+       /* Try to allocate the next devnum beginning at bus->devnum_next. */
+       devnum = find_next_zero_bit(bus->devmap.devicemap, 128,
+                       bus->devnum_next);
+       if (devnum >= 128)
+               devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1);
+
+       bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);
+
+       if (devnum < 128) {
+               set_bit(devnum, bus->devmap.devicemap);
+               udev->devnum = devnum;
+       }
+}
+
+static void release_address(struct usb_device *udev)
+{
+       if (udev->devnum > 0) {
+               clear_bit(udev->devnum, udev->bus->devmap.devicemap);
+               udev->devnum = -1;
+       }
+}
+
+/**
+ * usb_disconnect - disconnect a device (usbcore-internal)
+ * @pdev: pointer to device being disconnected
+ * Context: !in_interrupt ()
+ *
+ * Something got disconnected. Get rid of it, and all of its children.
+ * If *pdev is a normal device then the parent hub should be locked.
+ * If *pdev is a root hub then this routine will acquire the
+ * usb_bus_list_lock on behalf of the caller.
+ *
+ * Only hub drivers (including virtual root hub drivers for host
+ * controllers) should ever call this.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ */
+void usb_disconnect(struct usb_device **pdev)
+{
+       struct usb_device       *udev = *pdev;
+       int                     i;
+
+       if (!udev) {
+               pr_debug ("%s nodev\n", __FUNCTION__);
+               return;
+       }
+
+       /* mark the device as inactive, so any further urb submissions for
+        * this device will fail.
+        */
+       usb_set_device_state(udev, USB_STATE_NOTATTACHED);
+
+       /* lock the bus list on behalf of HCDs unregistering their root hubs */
+       if (!udev->parent)
+               down(&usb_bus_list_lock);
+       down(&udev->serialize);
+
+       dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum);
+
+       /* Free up all the children before we remove this device */
+       for (i = 0; i < USB_MAXCHILDREN; i++) {
+               if (udev->children[i])
+                       usb_disconnect(&udev->children[i]);
+       }
+
+       /* deallocate hcd/hardware state ... nuking all pending urbs and
+        * cleaning up all state associated with the current configuration
+        */
+       usb_disable_device(udev, 0);
+
+       /* Free the device number, remove the /proc/bus/usb entry and
+        * the sysfs attributes, and delete the parent's children[]
+        * (or root_hub) pointer.
+        */
+       dev_dbg (&udev->dev, "unregistering device\n");
+       release_address(udev);
+       usbfs_remove_device(udev);
+       usb_remove_sysfs_dev_files(udev);
+
+       /* Avoid races with recursively_mark_NOTATTACHED() */
+       spin_lock_irq(&device_state_lock);
+       *pdev = NULL;
+       spin_unlock_irq(&device_state_lock);
+
+       up(&udev->serialize);
+       if (!udev->parent)
+               up(&usb_bus_list_lock);
+
+       device_unregister(&udev->dev);
+}
+
+static int choose_configuration(struct usb_device *udev)
+{
+       int c, i;
+
+       /* NOTE: this should interact with hub power budgeting */
+
+       c = udev->config[0].desc.bConfigurationValue;
+       if (udev->descriptor.bNumConfigurations != 1) {
+               for (i = 0; i < udev->descriptor.bNumConfigurations; i++) {
+                       struct usb_interface_descriptor *desc;
+
+                       /* heuristic:  Linux is more likely to have class
+                        * drivers, so avoid vendor-specific interfaces.
+                        */
+                       desc = &udev->config[i].intf_cache[0]
+                                       ->altsetting->desc;
+                       if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
+                               continue;
+                       /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS */
+                       if (desc->bInterfaceClass == USB_CLASS_COMM
+                                       && desc->bInterfaceSubClass == 2
+                                       && desc->bInterfaceProtocol == 0xff)
+                               continue;
+                       c = udev->config[i].desc.bConfigurationValue;
+                       break;
+               }
+               dev_info(&udev->dev,
+                       "configuration #%d chosen from %d choices\n",
+                       c, udev->descriptor.bNumConfigurations);
+       }
+       return c;
+}
+
+#ifdef DEBUG
+static void show_string(struct usb_device *udev, char *id, int index)
+{
+       char *buf;
+
+       if (!index)
+               return;
+       if (!(buf = kmalloc(256, GFP_KERNEL)))
+               return;
+       if (usb_string(udev, index, buf, 256) > 0)
+               dev_printk(KERN_INFO, &udev->dev, "%s: %s\n", id, buf);
+       kfree(buf);
+}
+
+#else
+static inline void show_string(struct usb_device *udev, char *id, int index)
+{}
+#endif
+
+/*
+ * usb_new_device - perform initial device setup (usbcore-internal)
+ * @udev: newly addressed device (in ADDRESS state)
+ *
+ * This is called with devices which have been enumerated, but not yet
+ * configured.  The device descriptor is available, but not descriptors
+ * for any device configuration.  The caller must have locked udev and
+ * either the parent hub (if udev is a normal device) or else the
+ * usb_bus_list_lock (if udev is a root hub).  The parent's pointer to
+ * udev has already been installed, but udev is not yet visible through
+ * sysfs or other filesystem code.
+ *
+ * Returns 0 for success (device is configured and listed, with its
+ * interfaces, in sysfs); else a negative errno value.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Only the hub driver should ever call this; root hub registration
+ * uses it indirectly.
+ */
+int usb_new_device(struct usb_device *udev)
+{
+       int err;
+       int c;
+
+       err = usb_get_configuration(udev);
+       if (err < 0) {
+               dev_err(&udev->dev, "can't read configurations, error %d\n",
+                       err);
+               goto fail;
+       }
+
+       /* Tell the world! */
+       dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, "
+                       "SerialNumber=%d\n",
+                       udev->descriptor.iManufacturer,
+                       udev->descriptor.iProduct,
+                       udev->descriptor.iSerialNumber);
+
+       if (udev->descriptor.iProduct)
+               show_string(udev, "Product",
+                               udev->descriptor.iProduct);
+       if (udev->descriptor.iManufacturer)
+               show_string(udev, "Manufacturer",
+                               udev->descriptor.iManufacturer);
+       if (udev->descriptor.iSerialNumber)
+               show_string(udev, "SerialNumber",
+                               udev->descriptor.iSerialNumber);
+
+       /* put device-specific files into sysfs */
+       err = device_add (&udev->dev);
+       if (err) {
+               dev_err(&udev->dev, "can't device_add, error %d\n", err);
+               goto fail;
+       }
+       usb_create_sysfs_dev_files (udev);
+
+       /* choose and set the configuration. that registers the interfaces
+        * with the driver core, and lets usb device drivers bind to them.
+        */
+       c = choose_configuration(udev);
+       if (c < 0)
+               dev_warn(&udev->dev,
+                               "can't choose an initial configuration\n");
+       else {
+               err = usb_set_configuration(udev, c);
+               if (err) {
+                       dev_err(&udev->dev, "can't set config #%d, error %d\n",
+                                       c, err);
+                       usb_remove_sysfs_dev_files(udev);
+                       device_del(&udev->dev);
+                       goto fail;
+               }
+       }
+
+       /* USB device state == configured ... usable */
+
+       /* add a /proc/bus/usb entry */
+       usbfs_add_device(udev);
+       return 0;
+
+fail:
+       usb_set_device_state(udev, USB_STATE_NOTATTACHED);
+       return err;
+}
+
+
 static int hub_port_status(struct usb_device *hdev, int port,
                               u16 *status, u16 *change)
 {
@@ -934,16 +1210,20 @@ static int hub_port_reset(struct usb_device *hdev, int port,
 
        /* Reset the port */
        for (i = 0; i < PORT_RESET_TRIES; i++) {
-               set_port_feature(hdev, port + 1, USB_PORT_FEAT_RESET);
+               status = set_port_feature(hdev, port + 1, USB_PORT_FEAT_RESET);
+               if (status)
+                       dev_err(hub_dev, "cannot reset port %d (err = %d)\n",
+                                       port + 1, status);
+               else
+                       status = hub_port_wait_reset(hdev, port, udev, delay);
 
                /* return on disconnect or reset */
-               status = hub_port_wait_reset(hdev, port, udev, delay);
                if (status == -ENOTCONN || status == 0) {
                        clear_port_feature(hdev,
                                port + 1, USB_PORT_FEAT_C_RESET);
-                       udev->state = status
+                       usb_set_device_state(udev, status
                                        ? USB_STATE_NOTATTACHED
-                                       : USB_STATE_DEFAULT;
+                                       : USB_STATE_DEFAULT);
                        return status;
                }
 
@@ -964,6 +1244,9 @@ static int hub_port_disable(struct usb_device *hdev, int port)
 {
        int ret;
 
+       if (hdev->children[port])
+               usb_set_device_state(hdev->children[port],
+                               USB_STATE_NOTATTACHED);
        ret = clear_port_feature(hdev, port + 1, USB_PORT_FEAT_ENABLE);
        if (ret)
                dev_err(hubdev(hdev), "cannot disable port %d (err = %d)\n",
@@ -975,57 +1258,62 @@ static int hub_port_disable(struct usb_device *hdev, int port)
 /* USB 2.0 spec, 7.1.7.3 / fig 7-29:
  *
  * Between connect detection and reset signaling there must be a delay
- * of 100ms at least for debounce and power-settling. The corresponding
+ * of 100ms at least for debounce and power-settling.  The corresponding
  * timer shall restart whenever the downstream port detects a disconnect.
  * 
- * Apparently there are some bluetooth and irda-dongles and a number
- * of low-speed devices which require longer delays of about 200-400ms.
+ * Apparently there are some bluetooth and irda-dongles and a number of
+ * low-speed devices for which this debounce period may last over a second.
  * Not covered by the spec - but easy to deal with.
  *
- * This implementation uses 400ms minimum debounce timeout and checks
- * every 25ms for transient disconnects to restart the delay.
+ * This implementation uses a 1500ms total debounce timeout; if the
+ * connection isn't stable by then it returns -ETIMEDOUT.  It checks
+ * every 25ms for transient disconnects.  When the port status has been
+ * unchanged for 100ms it returns the port status.
  */
 
-#define HUB_DEBOUNCE_TIMEOUT   400
-#define HUB_DEBOUNCE_STEP       25
-#define HUB_DEBOUNCE_STABLE      4
+#define HUB_DEBOUNCE_TIMEOUT   1500
+#define HUB_DEBOUNCE_STEP        25
+#define HUB_DEBOUNCE_STABLE     100
 
 static int hub_port_debounce(struct usb_device *hdev, int port)
 {
        int ret;
-       int delay_time, stable_count;
+       int total_time, stable_time = 0;
        u16 portchange, portstatus;
-       unsigned connection;
-
-       connection = 0;
-       stable_count = 0;
-       for (delay_time = 0; delay_time < HUB_DEBOUNCE_TIMEOUT; delay_time += HUB_DEBOUNCE_STEP) {
-               msleep(HUB_DEBOUNCE_STEP);
+       unsigned connection = 0xffff;
 
+       for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) {
                ret = hub_port_status(hdev, port, &portstatus, &portchange);
                if (ret < 0)
                        return ret;
 
-               if ((portstatus & USB_PORT_STAT_CONNECTION) == connection) {
-                       if (connection) {
-                               if (++stable_count == HUB_DEBOUNCE_STABLE)
-                                       break;
-                       }
+               if (!(portchange & USB_PORT_STAT_C_CONNECTION) &&
+                    (portstatus & USB_PORT_STAT_CONNECTION) == connection) {
+                       stable_time += HUB_DEBOUNCE_STEP;
+                       if (stable_time >= HUB_DEBOUNCE_STABLE)
+                               break;
                } else {
-                       stable_count = 0;
+                       stable_time = 0;
+                       connection = portstatus & USB_PORT_STAT_CONNECTION;
                }
-               connection = portstatus & USB_PORT_STAT_CONNECTION;
 
-               if ((portchange & USB_PORT_STAT_C_CONNECTION)) {
-                       clear_port_feature(hdev, port+1, USB_PORT_FEAT_C_CONNECTION);
+               if (portchange & USB_PORT_STAT_C_CONNECTION) {
+                       clear_port_feature(hdev, port+1,
+                                       USB_PORT_FEAT_C_CONNECTION);
                }
+
+               if (total_time >= HUB_DEBOUNCE_TIMEOUT)
+                       break;
+               msleep(HUB_DEBOUNCE_STEP);
        }
 
        dev_dbg (hubdev (hdev),
-               "debounce: port %d: delay %dms stable %d status 0x%x\n",
-               port + 1, delay_time, stable_count, portstatus);
+               "debounce: port %d: total %dms stable %dms status 0x%x\n",
+               port + 1, total_time, stable_time, portstatus);
 
-       return (portstatus & USB_PORT_STAT_CONNECTION) ? 0 : -ENOTCONN;
+       if (stable_time < HUB_DEBOUNCE_STABLE)
+               return -ETIMEDOUT;
+       return portstatus;
 }
 
 static int hub_set_address(struct usb_device *udev)
@@ -1037,11 +1325,11 @@ static int hub_set_address(struct usb_device *udev)
        if (udev->state != USB_STATE_DEFAULT &&
                        udev->state != USB_STATE_ADDRESS)
                return -EINVAL;
-       retval = usb_control_msg(udev, usb_snddefctrl(udev),
+       retval = usb_control_msg(udev, (PIPE_CONTROL << 30) /* Address 0 */,
                USB_REQ_SET_ADDRESS, 0, udev->devnum, 0,
                NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
        if (retval == 0)
-               udev->state = USB_STATE_ADDRESS;
+               usb_set_device_state(udev, USB_STATE_ADDRESS);
        return retval;
 }
 
@@ -1109,33 +1397,9 @@ hub_port_init (struct usb_device *hdev, struct usb_device *udev, int port)
        udev->epmaxpacketin [0] = i;
        udev->epmaxpacketout[0] = i;
  
-       /* set the address */
-       if (udev->devnum <= 0) {
-               usb_choose_address(udev);
-               if (udev->devnum <= 0)
-                       goto fail;
-
-               /* Set up TT records, if needed  */
-               if (hdev->tt) {
-                       udev->tt = hdev->tt;
-                       udev->ttport = hdev->ttport;
-               } else if (udev->speed != USB_SPEED_HIGH
-                               && hdev->speed == USB_SPEED_HIGH) {
-                       struct usb_hub  *hub;
-                       hub = usb_get_intfdata (hdev->actconfig
-                                                       ->interface[0]);
-                       udev->tt = &hub->tt;
-                       udev->ttport = port + 1;
-               }
-
-               /* force the right log message (below) at low speed */
-               oldspeed = USB_SPEED_UNKNOWN;
-       }
        dev_info (&udev->dev,
                        "%s %s speed USB device using address %d\n",
-                       (oldspeed == USB_SPEED_UNKNOWN) ? "new" : "reset",
+                       (udev->config) ? "reset" : "new",
                        ({ char *speed; switch (udev->speed) {
                        case USB_SPEED_LOW:     speed = "low";  break;
                        case USB_SPEED_FULL:    speed = "full"; break;
@@ -1143,6 +1407,19 @@ hub_port_init (struct usb_device *hdev, struct usb_device *udev, int port)
                        default:                speed = "?";    break;
                        }; speed;}),
                        udev->devnum);
+
+       /* Set up TT records, if needed  */
+       if (hdev->tt) {
+               udev->tt = hdev->tt;
+               udev->ttport = hdev->ttport;
+       } else if (udev->speed != USB_SPEED_HIGH
+                       && hdev->speed == USB_SPEED_HIGH) {
+               struct usb_hub *hub;
+
+               hub = usb_get_intfdata(hdev->actconfig->interface[0]);
+               udev->tt = &hub->tt;
+               udev->ttport = port + 1;
+       }
  
        /* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
         * Because device hardware and firmware is sometimes buggy in
@@ -1164,12 +1441,7 @@ hub_port_init (struct usb_device *hdev, struct usb_device *udev, int port)
                        dev_err(&udev->dev,
                                "device not accepting address %d, error %d\n",
                                udev->devnum, retval);
- fail:
-                       hub_port_disable(hdev, port);
-                       usb_release_address(udev);
-                       usb_put_dev(udev);
-                       up(&usb_address0_sem);
-                       return retval;
+                       goto fail;
                }
  
                /* cope with hardware quirkiness:
@@ -1192,7 +1464,8 @@ hub_port_init (struct usb_device *hdev, struct usb_device *udev, int port)
        if (udev->speed == USB_SPEED_FULL
                        && (udev->epmaxpacketin [0]
                                != udev->descriptor.bMaxPacketSize0)) {
-               usb_disable_endpoint(udev, 0);
+               usb_disable_endpoint(udev, 0 + USB_DIR_IN);
+               usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
                usb_endpoint_running(udev, 0, 1);
                usb_endpoint_running(udev, 0, 0);
                udev->epmaxpacketin [0] = udev->descriptor.bMaxPacketSize0;
@@ -1208,11 +1481,11 @@ hub_port_init (struct usb_device *hdev, struct usb_device *udev, int port)
                goto fail;
        }
 
-       /* now dev is visible to other tasks */
-       hdev->children[port] = udev;
+       retval = 0;
 
+fail:
        up(&usb_address0_sem);
-       return 0;
+       return retval;
 }
 
 static void
@@ -1271,7 +1544,14 @@ hub_power_remaining (struct usb_hub *hub, struct usb_device *hdev)
        }
        return remaining;
 }
+
+/* Handle physical or logical connection change events.
+ * This routine is called when:
+ *     a port connection-change occurs;
+ *     a port enable-change occurs (often caused by EMI);
+ *     usb_reset_device() encounters changed descriptors (as from
+ *             a firmware download)
+ */
 static void hub_port_connect_change(struct usb_hub *hub, int port,
                                        u16 portstatus, u16 portchange)
 {
@@ -1282,9 +1562,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port,
        dev_dbg (hub_dev,
                "port %d, status %04x, change %04x, %s\n",
                port + 1, portstatus, portchange, portspeed (portstatus));
-       /* Clear the connection change status */
-       clear_port_feature(hdev, port + 1, USB_PORT_FEAT_C_CONNECTION);
 
        if (hub->has_indicators) {
                set_port_led(hdev, port + 1, HUB_LED_AUTO);
@@ -1295,6 +1572,17 @@ static void hub_port_connect_change(struct usb_hub *hub, int port,
        if (hdev->children[port])
                usb_disconnect(&hdev->children[port]);
 
+       if (portchange & USB_PORT_STAT_C_CONNECTION) {
+               status = hub_port_debounce(hdev, port);
+               if (status < 0) {
+                       dev_err (hub_dev,
+                               "connect-debounce failed, port %d disabled\n",
+                               port+1);
+                       goto done;
+               }
+               portstatus = status;
+       }
+
        /* Return now if nothing is connected */
        if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
 
@@ -1308,13 +1596,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port,
                        goto done;
                return;
        }
-  
-       if (hub_port_debounce(hdev, port)) {
-               dev_err (hub_dev,
-                       "connect-debounce failed, port %d disabled\n",
-                       port+1);
-               goto done;
-       }
 
        for (i = 0; i < SET_CONFIG_TRIES; i++) {
                struct usb_device *udev;
@@ -1328,21 +1609,26 @@ static void hub_port_connect_change(struct usb_hub *hub, int port,
                                "couldn't allocate port %d usb_device\n", port+1);
                        goto done;
                }
-               udev->state = USB_STATE_POWERED;
-         
+
+               usb_set_device_state(udev, USB_STATE_POWERED);
+
                /* hub can tell if it's lowspeed already:  D- pullup (not D+) */
                if (portstatus & USB_PORT_STAT_LOW_SPEED)
                        udev->speed = USB_SPEED_LOW;
                else
                        udev->speed = USB_SPEED_UNKNOWN;
+               /* set the address */
+               choose_address(udev);
+               if (udev->devnum <= 0) {
+                       status = -ENOTCONN;     /* Don't retry */
+                       goto loop;
+               }
 
-               /* reset, set address, get descriptor, add to hub's children */
-               down (&udev->serialize);
+               /* reset and get descriptor */
                status = hub_port_init(hdev, udev, port);
-               if (status == -ENOTCONN)
-                       break;
                if (status < 0)
-                       continue;
+                       goto loop;
 
                /* consecutive bus-powered hubs aren't reliable; they can
                 * violate the voltage drop budget.  if the new child has
@@ -1358,7 +1644,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port,
                                        &devstat);
                        if (status < 0) {
                                dev_dbg(&udev->dev, "get status %d ?\n", status);
-                               continue;
+                               goto loop;
                        }
                        cpu_to_le16s(&devstat);
                        if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
@@ -1370,10 +1656,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port,
                                                INDICATOR_AMBER_BLINK;
                                        schedule_work (&hub->leds);
                                }
-                               hdev->children[port] = NULL;
-                               usb_put_dev(udev);
-                               hub_port_disable(hdev, port);
-                               return;
+                               status = -ENOTCONN;     /* Don't retry */
+                               goto loop;
                        }
                }
  
@@ -1383,13 +1667,37 @@ static void hub_port_connect_change(struct usb_hub *hub, int port,
                                && highspeed_hubs != 0)
                        check_highspeed (hub, udev, port);
 
+               /* Store the parent's children[] pointer.  At this point
+                * udev becomes globally accessible, although presumably
+                * no one will look at it until hdev is unlocked.
+                */
+               down (&udev->serialize);
+               status = 0;
+
+               /* We mustn't add new devices if the parent hub has
+                * been disconnected; we would race with the
+                * recursively_mark_NOTATTACHED() routine.
+                */
+               spin_lock_irq(&device_state_lock);
+               if (hdev->state == USB_STATE_NOTATTACHED)
+                       status = -ENOTCONN;
+               else
+                       hdev->children[port] = udev;
+               spin_unlock_irq(&device_state_lock);
+
                /* Run it through the hoops (find a driver, etc) */
-               status = usb_new_device(udev);
-               if (status != 0) {
-                       hdev->children[port] = NULL;
-                       continue;
+               if (!status) {
+                       status = usb_new_device(udev);
+                       if (status) {
+                               spin_lock_irq(&device_state_lock);
+                               hdev->children[port] = NULL;
+                               spin_unlock_irq(&device_state_lock);
+                       }
                }
+
                up (&udev->serialize);
+               if (status)
+                       goto loop;
 
                status = hub_power_remaining(hub, hdev);
                if (status)
@@ -1398,6 +1706,15 @@ static void hub_port_connect_change(struct usb_hub *hub, int port,
                                2 * status);
 
                return;
+
+loop:
+               hub_port_disable(hdev, port);
+               usb_disable_endpoint(udev, 0 + USB_DIR_IN);
+               usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
+               release_address(udev);
+               usb_put_dev(udev);
+               if (status == -ENOTCONN)
+                       break;
        }
  
 done:
@@ -1406,7 +1723,6 @@ done:
 
 static void hub_events(void)
 {
-       unsigned long flags;
        struct list_head *tmp;
        struct usb_device *hdev;
        struct usb_hub *hub;
@@ -1416,6 +1732,7 @@ static void hub_events(void)
        u16 portstatus;
        u16 portchange;
        int i, ret;
+       int connect_change;
 
        /*
         *  We restart the list every time to avoid a deadlock with
@@ -1424,24 +1741,32 @@ static void hub_events(void)
         * Not the most efficient, but avoids deadlocks.
         */
        while (1) {
-               spin_lock_irqsave(&hub_event_lock, flags);
 
-               if (list_empty(&hub_event_list))
+               /* Grab the first entry at the beginning of the list */
+               spin_lock_irq(&hub_event_lock);
+               if (list_empty(&hub_event_list)) {
+                       spin_unlock_irq(&hub_event_lock);
                        break;
+               }
 
-               /* Grab the next entry from the beginning of the list */
                tmp = hub_event_list.next;
+               list_del_init(tmp);
 
                hub = list_entry(tmp, struct usb_hub, event_list);
                hdev = interface_to_usbdev(hub->intf);
                hub_dev = &hub->intf->dev;
 
-               list_del_init(tmp);
-
-               if (unlikely(down_trylock(&hub->khubd_sem)))
-                       BUG();  /* never blocks, we were on list */
+               usb_get_dev(hdev);
+               spin_unlock_irq(&hub_event_lock);
 
-               spin_unlock_irqrestore(&hub_event_lock, flags);
+               /* Lock the device, then check to see if we were
+                * disconnected while waiting for the lock to succeed. */
+               down(&hdev->serialize);
+               if (hdev->state != USB_STATE_CONFIGURED ||
+                               !hdev->actconfig ||
+                               hub != usb_get_intfdata(
+                                       hdev->actconfig->interface[0]))
+                       goto loop;
 
                if (hub->error) {
                        dev_dbg (hub_dev, "resetting for error %d\n",
@@ -1450,27 +1775,35 @@ static void hub_events(void)
                        if (hub_reset(hub)) {
                                dev_dbg (hub_dev,
                                        "can't reset; disconnecting\n");
-                               up(&hub->khubd_sem);
                                hub_start_disconnect(hdev);
-                               continue;
+                               goto loop;
                        }
 
                        hub->nerrors = 0;
                        hub->error = 0;
                }
 
+               /* deal with port status changes */
                for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
+                       if (!test_and_clear_bit(i+1, hub->event_bits))
+                               continue;
                        ret = hub_port_status(hdev, i, &portstatus, &portchange);
-                       if (ret < 0) {
+                       if (ret < 0)
                                continue;
-                       }
+                       connect_change = 0;
 
                        if (portchange & USB_PORT_STAT_C_CONNECTION) {
-                               hub_port_connect_change(hub, i, portstatus, portchange);
-                       } else if (portchange & USB_PORT_STAT_C_ENABLE) {
-                               dev_dbg (hub_dev,
-                                       "port %d enable change, status %08x\n",
-                                       i + 1, portstatus);
+                               clear_port_feature(hdev,
+                                       i + 1, USB_PORT_FEAT_C_CONNECTION);
+                               connect_change = 1;
+                       }
+
+                       if (portchange & USB_PORT_STAT_C_ENABLE) {
+                               if (!connect_change)
+                                       dev_dbg (hub_dev,
+                                               "port %d enable change, "
+                                               "status %08x\n",
+                                               i + 1, portstatus);
                                clear_port_feature(hdev,
                                        i + 1, USB_PORT_FEAT_C_ENABLE);
 
@@ -1481,15 +1814,14 @@ static void hub_events(void)
                                 * Works at least with mouse driver. 
                                 */
                                if (!(portstatus & USB_PORT_STAT_ENABLE)
-                                   && (portstatus & USB_PORT_STAT_CONNECTION)
-                                   && (hdev->children[i])) {
+                                   && !connect_change
+                                   && hdev->children[i]) {
                                        dev_err (hub_dev,
                                            "port %i "
                                            "disabled by hub (EMI?), "
                                            "re-enabling...",
                                                i + 1);
-                                       hub_port_connect_change(hub,
-                                               i, portstatus, portchange);
+                                       connect_change = 1;
                                }
                        }
 
@@ -1517,10 +1849,16 @@ static void hub_events(void)
                                clear_port_feature(hdev,
                                        i + 1, USB_PORT_FEAT_C_RESET);
                        }
+
+                       if (connect_change)
+                               hub_port_connect_change(hub, i,
+                                               portstatus, portchange);
                } /* end for i */
 
                /* deal with hub status changes */
-               if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
+               if (test_and_clear_bit(0, hub->event_bits) == 0)
+                       ;       /* do nothing */
+               else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
                        dev_err (hub_dev, "get_hub_status failed\n");
                else {
                        if (hubchange & HUB_CHANGE_LOCAL_POWER) {
@@ -1534,10 +1872,12 @@ static void hub_events(void)
                                hub_power_on(hub);
                        }
                }
-               up(&hub->khubd_sem);
-        } /* end while (1) */
 
-       spin_unlock_irqrestore(&hub_event_lock, flags);
+loop:
+               up(&hdev->serialize);
+               usb_put_dev(hdev);
+
+        } /* end while (1) */
 }
 
 static int hub_thread(void *__unused)
@@ -1581,9 +1921,6 @@ static struct usb_driver hub_driver = {
        .id_table =     hub_id_table,
 };
 
-/*
- * This should be a separate module.
- */
 int usb_hub_init(void)
 {
        pid_t pid;
@@ -1726,7 +2063,7 @@ int __usb_reset_device(struct usb_device *udev)
                        udev->actconfig->desc.bConfigurationValue, ret);
                goto re_enumerate;
        }
-       udev->state = USB_STATE_CONFIGURED;
+       usb_set_device_state(udev, USB_STATE_CONFIGURED);
 
        for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
                struct usb_interface *intf = udev->actconfig->interface[i];
@@ -1752,7 +2089,7 @@ int __usb_reset_device(struct usb_device *udev)
  
 re_enumerate:
        /* FIXME make some task re-enumerate; don't just mark unusable */
-       udev->state = USB_STATE_NOTATTACHED;
+       hub_port_disable(parent, port);
        return -ENODEV;
 }
 EXPORT_SYMBOL(__usb_reset_device);
index a24b1af..2fada0e 100644 (file)
@@ -202,11 +202,13 @@ struct usb_hub {
        int                     error;          /* last reported error */
        int                     nerrors;        /* track consecutive errors */
 
-       struct list_head        hub_list;       /* all hubs */
        struct list_head        event_list;     /* hubs w/data or errs ready */
+       unsigned long           event_bits[1];  /* status change bitmask */
+#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */
+#error event_bits[] is too short!
+#endif
 
        struct usb_hub_descriptor *descriptor;  /* class descriptor */
-       struct semaphore        khubd_sem;
        struct usb_tt           tt;             /* Transaction Translator */
 
        u8                      power_budget;   /* in 2mA units; or zero */
@@ -216,4 +218,15 @@ struct usb_hub {
        struct work_struct      leds;
 };
 
+/* use this for low-powered root hubs */
+static inline void
+hub_set_power_budget (struct usb_device *hubdev, unsigned mA)
+{
+       struct usb_hub  *hub;
+
+       hub = (struct usb_hub *)
+               usb_get_intfdata (hubdev->actconfig->interface[0]);
+       hub->power_budget = min(mA,(unsigned)500)/2;
+}
+
 #endif /* __LINUX_HUB_H */
index 6304f27..18a5da4 100644 (file)
@@ -566,22 +566,19 @@ void usb_sg_cancel (struct usb_sg_request *io)
  */
 int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size)
 {
-       int i = 5;
+       int i;
        int result;
        
        memset(buf,0,size);     // Make sure we parse really received data
 
-       while (i--) {
+       for (i = 0; i < 3; ++i) {
                /* retry on length 0 or stall; some devices are flakey */
-               if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-                                   USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
-                                   (type << 8) + index, 0, buf, size,
-                                   HZ * USB_CTRL_GET_TIMEOUT)) > 0
-                               || result != -EPIPE)
+               result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+                               USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+                               (type << 8) + index, 0, buf, size,
+                               HZ * USB_CTRL_GET_TIMEOUT);
+               if (!(result == 0 || result == -EPIPE))
                        break;
-
-               dev_dbg (&dev->dev, "RETRY descriptor, result %d\n", result);
-               result = -ENOMSG;
        }
        return result;
 }
@@ -830,6 +827,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
                        interface = dev->actconfig->interface[i];
                        dev_dbg (&dev->dev, "unregistering interface %s\n",
                                interface->dev.bus_id);
+                       usb_remove_sysfs_intf_files(interface);
                        device_del (&interface->dev);
                }
 
@@ -842,7 +840,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
                }
                dev->actconfig = 0;
                if (dev->state == USB_STATE_CONFIGURED)
-                       dev->state = USB_STATE_ADDRESS;
+                       usb_set_device_state(dev, USB_STATE_ADDRESS);
        }
 }
 
@@ -1047,7 +1045,7 @@ int usb_reset_configuration(struct usb_device *dev)
                        config->desc.bConfigurationValue, 0,
                        NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
        if (retval < 0) {
-               dev->state = USB_STATE_ADDRESS;
+               usb_set_device_state(dev, USB_STATE_ADDRESS);
                return retval;
        }
 
@@ -1185,9 +1183,9 @@ free_interfaces:
 
        dev->actconfig = cp;
        if (!cp)
-               dev->state = USB_STATE_ADDRESS;
+               usb_set_device_state(dev, USB_STATE_ADDRESS);
        else {
-               dev->state = USB_STATE_CONFIGURED;
+               usb_set_device_state(dev, USB_STATE_CONFIGURED);
 
                /* Initialize the new interface structures and the
                 * hc/hcd/usbcore interface/endpoint state.
@@ -1322,7 +1320,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
         */
 
        err = usb_get_string(dev, dev->string_langid, index, tbuf, 2);
-       if (err == -EPIPE) {
+       if (err == -EPIPE || err == 0) {
                dev_dbg(&dev->dev, "RETRY string %d read/%d\n", index, 2);
                err = usb_get_string(dev, dev->string_langid, index, tbuf, 2);
        }
@@ -1331,7 +1329,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
        len=tbuf[0];    
        
        err = usb_get_string(dev, dev->string_langid, index, tbuf, len);
-       if (err == -EPIPE) {
+       if (err == -EPIPE || err == 0) {
                dev_dbg(&dev->dev, "RETRY string %d read/%d\n", index, len);
                err = usb_get_string(dev, dev->string_langid, index, tbuf, len);
        }
index 38c64f6..78c5ca2 100644 (file)
@@ -2,8 +2,8 @@
  * drivers/usb/core/sysfs.c
  *
  * (C) Copyright 2002 David Brownell
- * (C) Copyright 2002 Greg Kroah-Hartman
- * (C) Copyright 2002 IBM Corp.
+ * (C) Copyright 2002,2004 Greg Kroah-Hartman
+ * (C) Copyright 2002,2004 IBM Corp.
  *
  * All of the sysfs file attributes for usb devices and interfaces.
  *
@@ -162,29 +162,35 @@ usb_descriptor_attr (bDeviceSubClass, "%02x\n")
 usb_descriptor_attr (bDeviceProtocol, "%02x\n")
 usb_descriptor_attr (bNumConfigurations, "%d\n")
 
+static struct attribute *dev_attrs[] = {
+       /* current configuration's attributes */
+       &dev_attr_bNumInterfaces.attr,
+       &dev_attr_bConfigurationValue.attr,
+       &dev_attr_bmAttributes.attr,
+       &dev_attr_bMaxPower.attr,
+       /* device attributes */
+       &dev_attr_idVendor.attr,
+       &dev_attr_idProduct.attr,
+       &dev_attr_bcdDevice.attr,
+       &dev_attr_bDeviceClass.attr,
+       &dev_attr_bDeviceSubClass.attr,
+       &dev_attr_bDeviceProtocol.attr,
+       &dev_attr_bNumConfigurations.attr,
+       &dev_attr_speed.attr,
+       &dev_attr_devnum.attr,
+       &dev_attr_version.attr,
+       &dev_attr_maxchild.attr,
+       NULL,
+};
+static struct attribute_group dev_attr_grp = {
+       .attrs = dev_attrs,
+};
 
 void usb_create_sysfs_dev_files (struct usb_device *udev)
 {
        struct device *dev = &udev->dev;
 
-       /* current configuration's attributes */
-       device_create_file (dev, &dev_attr_bNumInterfaces);
-       device_create_file (dev, &dev_attr_bConfigurationValue);
-       device_create_file (dev, &dev_attr_bmAttributes);
-       device_create_file (dev, &dev_attr_bMaxPower);
-
-       /* device attributes */
-       device_create_file (dev, &dev_attr_idVendor);
-       device_create_file (dev, &dev_attr_idProduct);
-       device_create_file (dev, &dev_attr_bcdDevice);
-       device_create_file (dev, &dev_attr_bDeviceClass);
-       device_create_file (dev, &dev_attr_bDeviceSubClass);
-       device_create_file (dev, &dev_attr_bDeviceProtocol);
-       device_create_file (dev, &dev_attr_bNumConfigurations);
-
-       /* speed varies depending on how you connect the device */
-       device_create_file (dev, &dev_attr_speed);
-       // FIXME iff there are other speed configs, show how many
+       sysfs_create_group(&dev->kobj, &dev_attr_grp);
 
        if (udev->descriptor.iManufacturer)
                device_create_file (dev, &dev_attr_manufacturer);
@@ -192,10 +198,20 @@ void usb_create_sysfs_dev_files (struct usb_device *udev)
                device_create_file (dev, &dev_attr_product);
        if (udev->descriptor.iSerialNumber)
                device_create_file (dev, &dev_attr_serial);
+}
+
+void usb_remove_sysfs_dev_files (struct usb_device *udev)
+{
+       struct device *dev = &udev->dev;
 
-       device_create_file (dev, &dev_attr_devnum);
-       device_create_file (dev, &dev_attr_version);
-       device_create_file (dev, &dev_attr_maxchild);
+       sysfs_remove_group(&dev->kobj, &dev_attr_grp);
+
+       if (udev->descriptor.iManufacturer)
+               device_remove_file(dev, &dev_attr_manufacturer);
+       if (udev->descriptor.iProduct)
+               device_remove_file(dev, &dev_attr_product);
+       if (udev->descriptor.iSerialNumber)
+               device_remove_file(dev, &dev_attr_serial);
 }
 
 /* Interface fields */
@@ -217,13 +233,26 @@ usb_intf_attr (bInterfaceSubClass, "%02x\n")
 usb_intf_attr (bInterfaceProtocol, "%02x\n")
 usb_intf_attr (iInterface, "%02x\n")
 
+static struct attribute *intf_attrs[] = {
+       &dev_attr_bInterfaceNumber.attr,
+       &dev_attr_bAlternateSetting.attr,
+       &dev_attr_bNumEndpoints.attr,
+       &dev_attr_bInterfaceClass.attr,
+       &dev_attr_bInterfaceSubClass.attr,
+       &dev_attr_bInterfaceProtocol.attr,
+       &dev_attr_iInterface.attr,
+       NULL,
+};
+static struct attribute_group intf_attr_grp = {
+       .attrs = intf_attrs,
+};
+
 void usb_create_sysfs_intf_files (struct usb_interface *intf)
 {
-       device_create_file (&intf->dev, &dev_attr_bInterfaceNumber);
-       device_create_file (&intf->dev, &dev_attr_bAlternateSetting);
-       device_create_file (&intf->dev, &dev_attr_bNumEndpoints);
-       device_create_file (&intf->dev, &dev_attr_bInterfaceClass);
-       device_create_file (&intf->dev, &dev_attr_bInterfaceSubClass);
-       device_create_file (&intf->dev, &dev_attr_bInterfaceProtocol);
-       device_create_file (&intf->dev, &dev_attr_iInterface);
+       sysfs_create_group(&intf->dev.kobj, &intf_attr_grp);
+}
+
+void usb_remove_sysfs_intf_files (struct usb_interface *intf)
+{
+       sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp);
 }
index 3c2ddb5..3a16e07 100644 (file)
@@ -883,6 +883,8 @@ struct usb_device *usb_find_device(u16 vendor_id, u16 product_id)
             buslist != &usb_bus_list; 
             buslist = buslist->next) {
                bus = container_of(buslist, struct usb_bus, bus_list);
+               if (!bus->root_hub)
+                       continue;
                dev = match_device(bus->root_hub, vendor_id, product_id);
                if (dev)
                        goto exit;
@@ -944,235 +946,6 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
        return -1;
 }
 
-/**
- * usb_disconnect - disconnect a device (usbcore-internal)
- * @pdev: pointer to device being disconnected
- * Context: !in_interrupt ()
- *
- * Something got disconnected. Get rid of it, and all of its children.
- *
- * Only hub drivers (including virtual root hub drivers for host
- * controllers) should ever call this.
- *
- * This call is synchronous, and may not be used in an interrupt context.
- */
-void usb_disconnect(struct usb_device **pdev)
-{
-       struct usb_device       *dev = *pdev;
-       struct usb_bus          *bus;
-       struct usb_operations   *ops;
-       int                     i;
-
-       might_sleep ();
-
-       if (!dev) {
-               pr_debug ("%s nodev\n", __FUNCTION__);
-               return;
-       }
-       bus = dev->bus;
-       if (!bus) {
-               pr_debug ("%s nobus\n", __FUNCTION__);
-               return;
-       }
-       ops = bus->op;
-
-       *pdev = NULL;
-
-       /* mark the device as inactive, so any further urb submissions for
-        * this device will fail.
-        */
-       dev->state = USB_STATE_NOTATTACHED;
-       down(&dev->serialize);
-
-       dev_info (&dev->dev, "USB disconnect, address %d\n", dev->devnum);
-
-       /* Free up all the children before we remove this device */
-       for (i = 0; i < USB_MAXCHILDREN; i++) {
-               struct usb_device **child = dev->children + i;
-               if (*child)
-                       usb_disconnect(child);
-       }
-
-       /* deallocate hcd/hardware state ... nuking all pending urbs and
-        * cleaning up all state associated with the current configuration
-        */
-       usb_disable_device(dev, 0);
-
-       /* Free the device number and remove the /proc/bus/usb entry */
-       dev_dbg (&dev->dev, "unregistering device\n");
-       usb_release_address(dev);
-       usbfs_remove_device(dev);
-       up(&dev->serialize);
-       device_unregister(&dev->dev);
-}
-
-/**
- * usb_choose_address - pick device address (usbcore-internal)
- * @dev: newly detected device (in DEFAULT state)
- *
- * Picks a device address.  It's up to the hub (or root hub) driver
- * to handle and manage enumeration, starting from the DEFAULT state.
- * Only hub drivers (but not virtual root hub drivers for host
- * controllers) should ever call this.
- */
-void usb_choose_address(struct usb_device *dev)
-{
-       int devnum;
-       // FIXME needs locking for SMP!!
-       /* why? this is called only from the hub thread, 
-        * which hopefully doesn't run on multiple CPU's simultaneously 8-)
-        */
-
-       /* Try to allocate the next devnum beginning at bus->devnum_next. */
-       devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, dev->bus->devnum_next);
-       if (devnum >= 128)
-               devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1);
-
-       dev->bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);
-
-       if (devnum < 128) {
-               set_bit(devnum, dev->bus->devmap.devicemap);
-               dev->devnum = devnum;
-       }
-}
-
-/**
- * usb_release_address - deallocate device address (usbcore-internal)
- * @dev: newly removed device
- *
- * Removes and deallocates the address assigned to a device.
- * Only hub drivers (but not virtual root hub drivers for host
- * controllers) should ever call this.
- */
-void usb_release_address(struct usb_device *dev)
-{
-       if (dev->devnum > 0) {
-               clear_bit(dev->devnum, dev->bus->devmap.devicemap);
-               dev->devnum = -1;
-       }
-}
-
-
-static inline void usb_show_string(struct usb_device *dev, char *id, int index)
-{
-       char *buf;
-
-       if (!index)
-               return;
-       if (!(buf = kmalloc(256, GFP_KERNEL)))
-               return;
-       if (usb_string(dev, index, buf, 256) > 0)
-               dev_printk(KERN_INFO, &dev->dev, "%s: %s\n", id, buf);
-       kfree(buf);
-}
-
-static int usb_choose_configuration(struct usb_device *dev)
-{
-       int c, i;
-
-       c = dev->config[0].desc.bConfigurationValue;
-       if (dev->descriptor.bNumConfigurations != 1) {
-               for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
-                       struct usb_interface_descriptor *desc;
-
-                       /* heuristic:  Linux is more likely to have class
-                        * drivers, so avoid vendor-specific interfaces.
-                        */
-                       desc = &dev->config[i].intf_cache[0]
-                                       ->altsetting->desc;
-                       if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
-                               continue;
-                       /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS */
-                       if (desc->bInterfaceClass == USB_CLASS_COMM
-                                       && desc->bInterfaceSubClass == 2
-                                       && desc->bInterfaceProtocol == 0xff)
-                               continue;
-                       c = dev->config[i].desc.bConfigurationValue;
-                       break;
-               }
-               dev_info(&dev->dev,
-                       "configuration #%d chosen from %d choices\n",
-                       c, dev->descriptor.bNumConfigurations);
-       }
-       return c;
-}
-
-/*
- * usb_new_device - perform initial device setup (usbcore-internal)
- * @dev: newly addressed device (in ADDRESS state)
- *
- * This is called with devices which have been enumerated, but not yet
- * configured.  The device descriptor is available, but not descriptors
- * for any device configuration.  The caller owns dev->serialize, and
- * the device is not visible through sysfs or other filesystem code.
- *
- * Returns 0 for success (device is configured and listed, with its
- * interfaces, in sysfs); else a negative errno value.  On error, one
- * reference count to the device has been dropped.
- *
- * This call is synchronous, and may not be used in an interrupt context.
- *
- * Only the hub driver should ever call this; root hub registration
- * uses it only indirectly.
- */
-int usb_new_device(struct usb_device *dev)
-{
-       int err;
-       int c;
-
-       err = usb_get_configuration(dev);
-       if (err < 0) {
-               dev_err(&dev->dev, "can't read configurations, error %d\n",
-                       err);
-               goto fail;
-       }
-
-       /* Tell the world! */
-       dev_dbg(&dev->dev, "new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
-               dev->descriptor.iManufacturer, dev->descriptor.iProduct, dev->descriptor.iSerialNumber);
-
-#ifdef DEBUG
-       if (dev->descriptor.iProduct)
-               usb_show_string(dev, "Product", dev->descriptor.iProduct);
-       if (dev->descriptor.iManufacturer)
-               usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer);
-       if (dev->descriptor.iSerialNumber)
-               usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
-#endif
-
-       /* put device-specific files into sysfs */
-       err = device_add (&dev->dev);
-       if (err) {
-               dev_err(&dev->dev, "can't device_add, error %d\n", err);
-               goto fail;
-       }
-       usb_create_sysfs_dev_files (dev);
-
-       /* choose and set the configuration. that registers the interfaces
-        * with the driver core, and lets usb device drivers bind to them.
-        * NOTE:  should interact with hub power budgeting.
-        */
-       c = usb_choose_configuration(dev);
-       err = usb_set_configuration(dev, c);
-       if (err) {
-               dev_err(&dev->dev, "can't set config #%d, error %d\n", c, err);
-               device_del(&dev->dev);
-               goto fail;
-       }
-
-       /* USB device state == configured ... usable */
-
-       /* add a /proc/bus/usb entry */
-       usbfs_add_device(dev);
-
-       return 0;
-fail:
-       dev->state = USB_STATE_NOTATTACHED;
-       usb_release_address(dev);
-       usb_put_dev(dev);
-       return err;
-}
-
 /**
  * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
  * @dev: device the buffer will be used with
index 886b79d..7d978af 100644 (file)
@@ -1,7 +1,9 @@
 /* Functions local to drivers/usb/core/ */
 
 extern void usb_create_sysfs_dev_files (struct usb_device *dev);
+extern void usb_remove_sysfs_dev_files (struct usb_device *dev);
 extern void usb_create_sysfs_intf_files (struct usb_interface *intf);
+extern void usb_remove_sysfs_intf_files (struct usb_interface *intf);
 extern int usb_probe_interface (struct device *dev);
 extern int usb_unbind_interface (struct device *dev);
 
@@ -19,5 +21,8 @@ extern int usb_get_device_descriptor(struct usb_device *dev,
                unsigned int size);
 extern int usb_set_configuration(struct usb_device *dev, int configuration);
 
+extern void usb_set_device_state(struct usb_device *udev,
+               enum usb_device_state new_state);
+
 /* for labeling diagnostics */
 extern const char *usbcore_name;
index 5fd8ea6..0c99e07 100644 (file)
@@ -825,8 +825,7 @@ static int dummy_urb_enqueue (
        dum = container_of (hcd, struct dummy, hcd);
        spin_lock_irqsave (&dum->lock, flags);
 
-       if (!dum->hdev)
-               dum->hdev = urb->dev->hcpriv;
+       dum->hdev = urb->dev->hcpriv;
        urb->hcpriv = dum;
        if (usb_pipetype (urb->pipe) == PIPE_CONTROL)
                urb->error_count = 1;           /* mark as a new urb */
@@ -994,10 +993,17 @@ static int periodic_bytes (struct dummy *dum, struct dummy_ep *ep)
        return limit;
 }
 
+#define is_active(dum) ((dum->port_status & \
+               (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE | \
+                       USB_PORT_STAT_SUSPEND)) \
+               == (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE))
+
 static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address)
 {
        int             i;
 
+       if (!is_active (dum))
+               return NULL;
        if ((address & ~USB_DIR_IN) == 0)
                return &dum->ep [0];
        for (i = 1; i < DUMMY_ENDPOINTS; i++) {
@@ -1011,6 +1017,8 @@ static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address)
        return NULL;
 }
 
+#undef is_active
+
 #define Dev_Request    (USB_TYPE_STANDARD | USB_RECIP_DEVICE)
 #define Dev_InRequest  (Dev_Request | USB_DIR_IN)
 #define Intf_Request   (USB_TYPE_STANDARD | USB_RECIP_INTERFACE)
@@ -1152,11 +1160,6 @@ restart:
                        case USB_REQ_SET_ADDRESS:
                                if (setup.bRequestType != Dev_Request)
                                        break;
-                               if (dum->address != 0) {
-                                       maybe_set_status (urb, -ETIMEDOUT);
-                                       urb->actual_length = 0;
-                                       goto return_urb;
-                               }
                                dum->address = setup.wValue;
                                maybe_set_status (urb, 0);
                                dev_dbg (hardware, "set_address = %d\n",
@@ -1404,9 +1407,8 @@ static int dummy_hub_control (
                        break;
                case USB_PORT_FEAT_POWER:
                        dum->port_status = 0;
-                       dum->address = 0;
-                       dum->hdev = 0;
                        dum->resuming = 0;
+                       stop_activity(dum, dum->driver);
                        break;
                default:
                        dum->port_status &= ~(1 << wValue);
@@ -1657,7 +1659,7 @@ clean0:
        INIT_LIST_HEAD (&hcd->dev_list);
        usb_register_bus (bus);
 
-       bus->root_hub = root = usb_alloc_dev (0, bus, 0);
+       root = usb_alloc_dev (0, bus, 0);
        if (!root) {
                retval = -ENOMEM;
 clean1:
@@ -1671,14 +1673,16 @@ clean1:
        root->speed = USB_SPEED_HIGH;
 
        /* ...then configured, so khubd sees us. */
-       if ((retval = hcd_register_root (&dum->hcd)) != 0) {
-               bus->root_hub = 0;
+       if ((retval = hcd_register_root (root, &dum->hcd)) != 0) {
                usb_put_dev (root);
 clean2:
                dum->hcd.state = USB_STATE_QUIESCING;
                goto clean1;
        }
 
+       /* only show a low-power port: just 8mA */
+       hub_set_power_budget (root, 8);
+
        dum->started = 1;
 
        if ((retval = dummy_register_udc (dum)) != 0) {
index 7726275..a4bf49e 100644 (file)
@@ -118,6 +118,7 @@ struct eth_dev {
        unsigned                zlp:1;
        unsigned                cdc:1;
        unsigned                rndis:1;
+       unsigned                suspended:1;
        u16                     cdc_filter;
        unsigned long           todo;
 #define        WORK_RX_MEMORY          0
@@ -1345,24 +1346,23 @@ static void eth_setup_complete (struct usb_ep *ep, struct usb_request *req)
 
 static void rndis_response_complete (struct usb_ep *ep, struct usb_request *req)
 {
-       struct eth_dev          *dev = ep->driver_data;
-       
        if (req->status || req->actual != req->length)
                DEBUG (dev, "rndis response complete --> %d, %d/%d\n",
                       req->status, req->actual, req->length);
 
        /* done sending after CDC_GET_ENCAPSULATED_RESPONSE */
-       rndis_free_response (dev->rndis_config, req->buf);
 }
 
 static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
 {
        struct eth_dev          *dev = ep->driver_data;
+       int                     status;
        
        /* received RNDIS command from CDC_SEND_ENCAPSULATED_COMMAND */
        spin_lock(&dev->lock);
-       if (rndis_msg_parser (dev->rndis_config, (u8 *) req->buf))
-               ERROR(dev, "%s: rndis parse error\n", __FUNCTION__ );
+       status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf);
+       if (status < 0)
+               ERROR(dev, "%s: rndis parse error %d\n", __FUNCTION__, status);
        spin_unlock(&dev->lock);
 }
 
@@ -1580,6 +1580,7 @@ done_set_intf:
                        if (buf) {
                                memcpy (req->buf, buf, value);
                                req->complete = rndis_response_complete;
+                               rndis_free_response(dev->rndis_config, buf);
                        }
                        /* else stalls ... spec says to avoid that */
                }
@@ -1651,12 +1652,12 @@ static struct net_device_stats *eth_get_stats (struct net_device *net)
        return &((struct eth_dev *) net->priv)->stats;
 }
 
-static int eth_ethtool_ioctl (struct net_device *net, void *useraddr)
+static int eth_ethtool_ioctl (struct net_device *net, void __user *useraddr)
 {
        struct eth_dev  *dev = (struct eth_dev *) net->priv;
        u32             cmd;
 
-       if (get_user (cmd, (u32 *)useraddr))
+       if (get_user (cmd, (u32 __user *)useraddr))
                return -EFAULT;
        switch (cmd) {
 
@@ -1694,7 +1695,7 @@ static int eth_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
 {
        switch (cmd) {
        case SIOCETHTOOL:
-               return eth_ethtool_ioctl (net, (void *)rq->ifr_data);
+               return eth_ethtool_ioctl(net, rq->ifr_data);
        default:
                return -EOPNOTSUPP;
        }
@@ -2064,6 +2065,16 @@ static void rndis_send_media_state (struct eth_dev *dev, int connect)
        }
 }
 
+static void rndis_control_ack_complete (struct usb_ep *ep, struct usb_request *req)
+{
+       if (req->status || req->actual != req->length)
+               DEBUG (dev, "rndis control ack complete --> %d, %d/%d\n",
+                      req->status, req->actual, req->length);
+
+       usb_ep_free_buffer(ep, req->buf, req->dma, 8);
+       usb_ep_free_request(ep, req);
+}
+
 static int rndis_control_ack (struct net_device *net)
 {
        struct eth_dev          *dev = (struct eth_dev *) net->priv;
@@ -2095,7 +2106,7 @@ static int rndis_control_ack (struct net_device *net)
         * CDC_NOTIFY_RESPONSE_AVAILABLE should work too
         */
        resp->length = 8;
-       resp->complete = rndis_response_complete;
+       resp->complete = rndis_control_ack_complete;
        
        *((u32 *) resp->buf) = __constant_cpu_to_le32 (1);
        *((u32 *) resp->buf + 1) = __constant_cpu_to_le32 (0);
@@ -2103,7 +2114,7 @@ static int rndis_control_ack (struct net_device *net)
        length = usb_ep_queue (dev->status_ep, resp, GFP_ATOMIC);
        if (length < 0) {
                resp->status = 0;
-               rndis_response_complete (dev->status_ep, resp);
+               rndis_control_ack_complete (dev->status_ep, resp);
        }
        
        return 0;
@@ -2302,17 +2313,6 @@ eth_bind (struct usb_gadget *gadget)
                UTS_SYSNAME " " UTS_RELEASE "/%s",
                gadget->name);
 
-       /* CDC subset ... recognized by Linux since 2.4.10, but Windows
-        * drivers aren't widely available.
-        */
-       if (!cdc) {
-               device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
-               device_desc.idVendor =
-                       __constant_cpu_to_le16(SIMPLE_VENDOR_NUM);
-               device_desc.idProduct =
-                       __constant_cpu_to_le16(SIMPLE_PRODUCT_NUM);
-       }
-
        /* If there's an RNDIS configuration, that's what Windows wants to
         * be using ... so use these product IDs here and in the "linux.inf"
         * needed to install MSFT drivers.  Current Linux kernels will use
@@ -2326,6 +2326,16 @@ eth_bind (struct usb_gadget *gadget)
                        __constant_cpu_to_le16(RNDIS_PRODUCT_NUM);
                snprintf (product_desc, sizeof product_desc,
                        "RNDIS/%s", driver_desc);
+
+       /* CDC subset ... recognized by Linux since 2.4.10, but Windows
+        * drivers aren't widely available.
+        */
+       } else if (!cdc) {
+               device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+               device_desc.idVendor =
+                       __constant_cpu_to_le16(SIMPLE_VENDOR_NUM);
+               device_desc.idProduct =
+                       __constant_cpu_to_le16(SIMPLE_PRODUCT_NUM);
        }
 
        /* support optional vendor/distro customization */
@@ -2554,6 +2564,26 @@ fail:
 
 /*-------------------------------------------------------------------------*/
 
+static void
+eth_suspend (struct usb_gadget *gadget)
+{
+       struct eth_dev          *dev = get_gadget_data (gadget);
+
+       DEBUG (dev, "suspend\n");
+       dev->suspended = 1;
+}
+
+static void
+eth_resume (struct usb_gadget *gadget)
+{
+       struct eth_dev          *dev = get_gadget_data (gadget);
+
+       DEBUG (dev, "resume\n");
+       dev->suspended = 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
 static struct usb_gadget_driver eth_driver = {
 #ifdef CONFIG_USB_GADGET_DUALSPEED
        .speed          = USB_SPEED_HIGH,
@@ -2567,6 +2597,9 @@ static struct usb_gadget_driver eth_driver = {
        .setup          = eth_setup,
        .disconnect     = eth_disconnect,
 
+       .suspend        = eth_suspend,
+       .resume         = eth_resume,
+
        .driver         = {
                .name           = (char *) shortname,
                // .shutdown = ...
index 55f4246..df7eb89 100644 (file)
@@ -2501,7 +2501,7 @@ static int send_status(struct fsg_dev *fsg)
                /* Store and send the Bulk-only CSW */
                csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG);
                csw->Tag = fsg->tag;
-               csw->Residue = fsg->residue;
+               csw->Residue = cpu_to_le32(fsg->residue);
                csw->Status = status;
 
                bh->inreq->length = USB_BULK_CS_WRAP_LEN;
@@ -2947,7 +2947,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
                fsg->data_dir = DATA_DIR_TO_HOST;
        else
                fsg->data_dir = DATA_DIR_FROM_HOST;
-       fsg->data_size = cbw->DataTransferLength;
+       fsg->data_size = le32_to_cpu(cbw->DataTransferLength);
        if (fsg->data_size == 0)
                fsg->data_dir = DATA_DIR_NONE;
        fsg->lun = cbw->Lun;
@@ -3834,6 +3834,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        }
 
        /* Find all the endpoints we will use */
+       usb_ep_autoconfig_reset(gadget);
        ep = usb_ep_autoconfig(gadget, &fs_bulk_in_desc);
        if (!ep)
                goto autoconf_fail;
index 611eac8..c553bbf 100644 (file)
 #define NDIS_STATUS_MULTICAST_EXISTS      0xC001000A
 #define NDIS_STATUS_MULTICAST_NOT_FOUND   0xC001000B
 
+enum NDIS_DEVICE_POWER_STATE {
+       NdisDeviceStateUnspecified = 0,
+       NdisDeviceStateD0,
+       NdisDeviceStateD1,
+       NdisDeviceStateD2,
+       NdisDeviceStateD3,
+       NdisDeviceStateMaximum
+};
+
+struct NDIS_PM_WAKE_UP_CAPABILITIES {
+       enum NDIS_DEVICE_POWER_STATE  MinMagicPacketWakeUp;
+       enum NDIS_DEVICE_POWER_STATE  MinPatternWakeUp;
+       enum NDIS_DEVICE_POWER_STATE  MinLinkChangeWakeUp;
+};
+
 /* NDIS_PNP_CAPABILITIES.Flags constants */
 #define NDIS_DEVICE_WAKE_UP_ENABLE                0x00000001
 #define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE  0x00000002
 #define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE   0x00000004
 
+struct NDIS_PNP_CAPABILITIES {
+       u32                                     Flags;
+       struct NDIS_PM_WAKE_UP_CAPABILITIES     WakeUpCapabilities;
+};
+
+struct NDIS_PM_PACKET_PATTERN {
+       u32     Priority;
+       u32     Reserved;
+       u32     MaskSize;
+       u32     PatternOffset;
+       u32     PatternSize;
+       u32     PatternFlags;
+};
+
+
 /* Required Object IDs (OIDs) */
 #define OID_GEN_SUPPORTED_LIST            0x00010101
 #define OID_GEN_HARDWARE_STATUS           0x00010102
index 2ae8309..bc00e07 100644 (file)
@@ -1902,6 +1902,8 @@ static void ep0_start (struct net2280 *dev)
                , &dev->usb->stdrsp);
        writel (  (1 << USB_ROOT_PORT_WAKEUP_ENABLE)
                | (1 << SELF_POWERED_USB_DEVICE)
+               /* erratum 0102 workaround */
+               | ((dev->chiprev == 0100) ? 0 : 1) << SUSPEND_IMMEDIATELY
                | (1 << REMOTE_WAKEUP_SUPPORT)
                | (1 << USB_DETECT_ENABLE)
                | (1 << SELF_POWERED_STATUS)
@@ -1917,6 +1919,7 @@ static void ep0_start (struct net2280 *dev)
                | (1 << PCI_RETRY_ABORT_INTERRUPT_ENABLE)
                | (1 << VBUS_INTERRUPT_ENABLE)
                | (1 << ROOT_PORT_RESET_INTERRUPT_ENABLE)
+               | (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE)
                , &dev->regs->pciirqenb1);
 
        /* don't leave any writes posted */
@@ -2513,19 +2516,24 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
                        return;
        }
 
-       /* NOTE: we don't actually suspend the hardware; that starts to
-        * interact with PCI power management, and needs something like a
-        * controller->suspend() call to clear SUSPEND_REQUEST_INTERRUPT.
-        * we shouldn't see resume interrupts.
-        * for rev 0100, this also avoids erratum 0102.
+       /* NOTE: chip stays in PCI D0 state for now, but it could
+        * enter D1 to save more power
         */
        tmp = (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT);
        if (stat & tmp) {
-               if (dev->driver->suspend)
-                       dev->driver->suspend (&dev->gadget);
+               writel (tmp, &dev->regs->irqstat1);
+               if (stat & (1 << SUSPEND_REQUEST_INTERRUPT)) {
+                       if (dev->driver->suspend)
+                               dev->driver->suspend (&dev->gadget);
+                       /* we use SUSPEND_IMMEDIATELY */
+                       stat &= ~(1 << SUSPEND_REQUEST_INTERRUPT);
+               } else {
+                       if (dev->driver->resume)
+                               dev->driver->resume (&dev->gadget);
+                       /* at high speed, note erratum 0133 */
+               }
                stat &= ~tmp;
        }
-       stat &= ~(1 << SUSPEND_REQUEST_INTERRUPT);
 
        /* clear any other status/irqs */
        if (stat)
@@ -2533,6 +2541,7 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
 
        /* some status we can just ignore */
        stat &= ~((1 << CONTROL_STATUS_INTERRUPT)
+                       | (1 << SUSPEND_REQUEST_INTERRUPT)
                        | (1 << RESUME_INTERRUPT)
                        | (1 << SOF_INTERRUPT));
        if (!stat)
index fd4e800..05fc22d 100644 (file)
@@ -18,6 +18,9 @@
  * 
  * 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
  *             Fixed rndis_rm_hdr length bug.
+ *
+ * Copyright (C) 2004 by David Brownell
+ *             updates to merge with Linux 2.6, better match RNDIS spec
  */
 
 #include <linux/config.h>
 #include <asm/byteorder.h>
 #include <asm/system.h>
 
+
+#undef RNDIS_PM
+#undef VERBOSE
+
 #include "rndis.h"
 
 
 /* The driver for your USB chip needs to support ep0 OUT to work with
- * RNDIS, plus the same three descriptors as CDC Ethernet.
+ * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional).
  *
  * Windows hosts need an INF file like Documentation/usb/linux.inf
+ * and will be happier if you provide the host_addr module parameter.
  */
 
-#ifndef        __LITTLE_ENDIAN
-#warning this code is missing all cpu_to_leXX() calls ...
-#endif
-
 #if 0
-#define DEBUG if (rndis_debug) printk 
+#define DEBUG(str,args...) do { \
+       if (rndis_debug) \
+               printk(KERN_DEBUG str , ## args ); \
+       } while (0)
 static int rndis_debug = 0;
 
 module_param (rndis_debug, bool, 0);
 MODULE_PARM_DESC (rndis_debug, "enable debugging");
 
 #else
-#define DEBUG(str,args...) do{}while(0)
+
+#define rndis_debug            0
+#define DEBUG(str,args...)     do{}while(0)
 #endif
 
 #define RNDIS_MAX_CONFIGS      1
@@ -79,16 +88,14 @@ static int rndis_keepalive_response (int configNr,
 
 static rndis_resp_t *rndis_add_response (int configNr, u32 length);
 
-/* FIXME OMITTED OIDs, that RNDIS-on-USB "must" support, include
- *  - power management (OID_PNP_CAPABILITIES, ...)
- *  - network wakeup (OID_PNP_ENABLE_WAKE_UP, ...)
- */
 
 /* NDIS Functions */
 static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
 {
        int                     retval = -ENOTSUPP;
        u32                     length = 0;
+       u32                     *tmp;
+       int                     i, count;
        rndis_query_cmplt_type  *resp;
 
        if (!r) return -ENOMEM;
@@ -97,11 +104,17 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        if (!resp) return -ENOMEM;
        
        switch (OID) {
+
+       /* general oids (table 4-1) */
+
        /* mandatory */
        case OID_GEN_SUPPORTED_LIST:
                DEBUG ("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__);
                length = sizeof (oid_supported_list);
-               memcpy ((u8 *) resp + 24, oid_supported_list, length); 
+               count  = length / sizeof (u32);
+               tmp = (u32 *) ((u8 *)resp + 24);
+               for (i = 0; i < count; i++)
+                       tmp[i] = cpu_to_le32 (oid_supported_list[i]);
                retval = 0;
                break;
                
@@ -115,7 +128,7 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
                 * reddite ergo quae sunt Caesaris Caesari
                 * et quae sunt Dei Deo!
                 */
-               *((u32 *) resp + 6) = 0;
+               *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
                
@@ -123,7 +136,8 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_GEN_MEDIA_SUPPORTED:
                DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__);
                length = 4;
-               *((u32 *) resp + 6) = rndis_per_dev_params [configNr].medium;
+               *((u32 *) resp + 6) = cpu_to_le32 (
+                                       rndis_per_dev_params [configNr].medium);
                retval = 0;
                break;
                
@@ -132,24 +146,21 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
                DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__);
                length = 4;
                /* one medium, one transport... (maybe you do it better) */
-               *((u32 *) resp + 6) = rndis_per_dev_params [configNr].medium;
+               *((u32 *) resp + 6) = cpu_to_le32 (
+                                       rndis_per_dev_params [configNr].medium);
                retval = 0;
                break;
                
-       case OID_GEN_MAXIMUM_LOOKAHEAD:
-               DEBUG("%s: OID_GEN_MAXIMUM_LOOKAHEAD\n", __FUNCTION__);
-               break;
-               
        /* mandatory */
        case OID_GEN_MAXIMUM_FRAME_SIZE:
                DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].dev) {
                        length = 4;
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
-                                               .dev->mtu;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr].dev->mtu);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -160,30 +171,20 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
                length = 4;
                if (rndis_per_dev_params [configNr].media_state
                        == NDIS_MEDIA_STATE_DISCONNECTED)
-                   *((u32 *) resp + 6) = 0;
+                   *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                else
-                   *((u32 *) resp + 6) = rndis_per_dev_params [configNr].speed;
+                   *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr].speed);
                retval = 0;
                break;
-               
-       case OID_GEN_TRANSMIT_BUFFER_SPACE:
-               DEBUG("%s: OID_GEN_TRANSMIT_BUFFER_SPACE\n", __FUNCTION__);
-               length = 4;
-               *((u32 *) resp + 6) = 0;
-               retval = 0;
-               break;
-               
-       case OID_GEN_RECEIVE_BUFFER_SPACE:
-               DEBUG("%s: OID_GEN_RECEIVE_BUFFER_SPACE\n", __FUNCTION__);
-               break;
-               
+
        /* mandatory */
        case OID_GEN_TRANSMIT_BLOCK_SIZE:
                DEBUG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].dev) {
                        length = 4;
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
-                                               .dev->mtu;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr].dev->mtu);
                        retval = 0;
                }
                break;
@@ -193,8 +194,8 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
                DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].dev) {
                        length = 4;
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
-                                               .dev->mtu;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr].dev->mtu);
                        retval = 0;
                }
                break;
@@ -203,7 +204,8 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_GEN_VENDOR_ID:
                DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__);
                length = 4;
-               *((u32 *) resp + 6) = rndis_per_dev_params [configNr].vendorID;
+               *((u32 *) resp + 6) = cpu_to_le32 (
+                       rndis_per_dev_params [configNr].vendorID);
                retval = 0;
                break;
                
@@ -216,129 +218,92 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
                retval = 0;
                break;
 
+       case OID_GEN_VENDOR_DRIVER_VERSION:
+               DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__);
+               length = 4;
+               /* Created as LE */
+               *((u32 *) resp + 6) = rndis_driver_version;
+               retval = 0;
+               break;
+
        /* mandatory */
        case OID_GEN_CURRENT_PACKET_FILTER:
                DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
                length = 4;
-               *((u32 *) resp + 6) = rndis_per_dev_params[configNr].filter;
+               *((u32 *) resp + 6) = cpu_to_le32 (
+                                       rndis_per_dev_params[configNr].filter);
                retval = 0;
                break;
-               
-       case OID_GEN_CURRENT_LOOKAHEAD:
-               DEBUG("%s: OID_GEN_CURRENT_LOOKAHEAD\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_DRIVER_VERSION:
-               DEBUG("%s: OID_GEN_DRIVER_VERSION\n", __FUNCTION__);
-               break;
-               
+
        /* mandatory */
        case OID_GEN_MAXIMUM_TOTAL_SIZE:
                DEBUG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__);
                length = 4;
-               *((u32 *) resp + 6) = RNDIS_MAX_TOTAL_SIZE;
-               retval = 0;
-               break;
-               
-       case OID_GEN_PROTOCOL_OPTIONS:
-               DEBUG("%s: OID_GEN_PROTOCOL_OPTIONS\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_MAC_OPTIONS:
-               DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__);
-               length = 4;
-               *((u32 *) resp + 6) = NDIS_MAC_OPTION_RECEIVE_SERIALIZED | 
-                   NDIS_MAC_OPTION_FULL_DUPLEX;
+               *((u32 *) resp + 6) = __constant_cpu_to_le32(
+                                       RNDIS_MAX_TOTAL_SIZE);
                retval = 0;
                break;
-               
+
        /* mandatory */
        case OID_GEN_MEDIA_CONNECT_STATUS:
                DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__);
                length = 4;
-               *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
-                                               .media_state;
+               *((u32 *) resp + 6) = cpu_to_le32 (
+                                       rndis_per_dev_params [configNr]
+                                               .media_state);
                retval = 0;
                break;
-               
-       case OID_GEN_MAXIMUM_SEND_PACKETS:
-               DEBUG("%s: OID_GEN_MAXIMUM_SEND_PACKETS\n", __FUNCTION__);
-               break;
-               
-       /* mandatory */
-       case OID_GEN_VENDOR_DRIVER_VERSION:
-               DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__);
-               length = 4;
-               *((u32 *) resp + 6) = rndis_driver_version;
-               retval = 0;
-               break;
-               
-       case OID_GEN_SUPPORTED_GUIDS:
-               DEBUG("%s: OID_GEN_SUPPORTED_GUIDS\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_NETWORK_LAYER_ADDRESSES:
-               DEBUG("%s: OID_GEN_NETWORK_LAYER_ADDRESSES\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_TRANSPORT_HEADER_OFFSET:
-               DEBUG("%s: OID_GEN_TRANSPORT_HEADER_OFFSET\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_MACHINE_NAME:
-               DEBUG("%s: OID_GEN_MACHINE_NAME\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_RNDIS_CONFIG_PARAMETER:
-               DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER\n", __FUNCTION__);
+
+       case OID_GEN_PHYSICAL_MEDIUM:
+               DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__);
                length = 4;
-               *((u32 *) resp + 6) = 0;
+               *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
-               
-       case OID_GEN_VLAN_ID:
-               DEBUG("%s: OID_GEN_VLAN_ID\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_MEDIA_CAPABILITIES:
-               DEBUG("%s: OID_GEN_MEDIA_CAPABILITIES\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_PHYSICAL_MEDIUM:
-               DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__);
+
+       /* The RNDIS specification is incomplete/wrong.   Some versions
+        * of MS-Windows expect OIDs that aren't specified there.  Other
+        * versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
+        */
+       case OID_GEN_MAC_OPTIONS:               /* from WinME */
+               DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__);
                length = 4;
-               *((u32 *) resp + 6) = 0;
+               *((u32 *) resp + 6) = __constant_cpu_to_le32(
+                         NDIS_MAC_OPTION_RECEIVE_SERIALIZED
+                       | NDIS_MAC_OPTION_FULL_DUPLEX);
                retval = 0;
                break;
-               
+
+       /* statistics OIDs (table 4-2) */
+
        /* mandatory */
        case OID_GEN_XMIT_OK:
                DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        length = 4;
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
-                                       .stats->tx_packets - 
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                           rndis_per_dev_params [configNr].stats->tx_packets - 
                            rndis_per_dev_params [configNr].stats->tx_errors -
-                           rndis_per_dev_params [configNr].stats->tx_dropped;
+                           rndis_per_dev_params [configNr].stats->tx_dropped);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
-               
+
        /* mandatory */
        case OID_GEN_RCV_OK:
                DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        length = 4;
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
-                                       stats->rx_packets - 
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                           rndis_per_dev_params [configNr].stats->rx_packets - 
                            rndis_per_dev_params [configNr].stats->rx_errors -
-                           rndis_per_dev_params [configNr].stats->rx_dropped;
+                           rndis_per_dev_params [configNr].stats->rx_dropped);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -348,11 +313,12 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
                DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        length = 4;
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
-                                       stats->tx_errors;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr]
+                                       .stats->tx_errors);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -361,11 +327,12 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_GEN_RCV_ERROR:
                DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
-                                       stats->rx_errors;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr]
+                                       .stats->rx_errors);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -374,15 +341,17 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_GEN_RCV_NO_BUFFER:
                DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
-                                       stats->rx_dropped;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr]
+                                       .stats->rx_dropped);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
-               
+
+#ifdef RNDIS_OPTIONAL_STATS
        case OID_GEN_DIRECTED_BYTES_XMIT:
                DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__);
                /* 
@@ -392,14 +361,17 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
                 */
                if (rndis_per_dev_params [configNr].stats) {
                        length = 4;
-                       *((u32 *) resp + 6) = (rndis_per_dev_params [configNr].
-                                       stats->tx_packets - 
-                           rndis_per_dev_params [configNr].stats->tx_errors -
-                           rndis_per_dev_params [configNr].stats->tx_dropped)
-                                       *123;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               (rndis_per_dev_params [configNr]
+                                       .stats->tx_packets - 
+                                rndis_per_dev_params [configNr]
+                                        .stats->tx_errors -
+                                rndis_per_dev_params [configNr]
+                                        .stats->tx_dropped)
+                               * 123);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -409,14 +381,17 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
                /* dito */
                if (rndis_per_dev_params [configNr].stats) {
                        length = 4;
-                       *((u32 *) resp + 6) = (rndis_per_dev_params [configNr].
-                                       stats->tx_packets - 
-                           rndis_per_dev_params [configNr].stats->tx_errors -
-                           rndis_per_dev_params [configNr].stats->tx_dropped)
-                                       /123;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               (rndis_per_dev_params [configNr]
+                                       .stats->tx_packets - 
+                                rndis_per_dev_params [configNr]
+                                        .stats->tx_errors -
+                                rndis_per_dev_params [configNr]
+                                        .stats->tx_dropped)
+                               / 123);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -424,11 +399,12 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_GEN_MULTICAST_BYTES_XMIT:
                DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
-                                       stats->multicast*1234;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr]
+                                       .stats->multicast*1234);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -436,11 +412,12 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_GEN_MULTICAST_FRAMES_XMIT:
                DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
-                                       stats->multicast;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr]
+                                       .stats->multicast);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -448,11 +425,12 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_GEN_BROADCAST_BYTES_XMIT:
                DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
-                                       stats->tx_packets/42*255;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr]
+                                       .stats->tx_packets/42*255);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -460,35 +438,37 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_GEN_BROADCAST_FRAMES_XMIT:
                DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
-                                       stats->tx_packets/42;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr]
+                                       .stats->tx_packets/42);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
                
        case OID_GEN_DIRECTED_BYTES_RCV:
                DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__);
-               *((u32 *) resp + 6) = 0;
+               *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
                
        case OID_GEN_DIRECTED_FRAMES_RCV:
                DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__);
-               *((u32 *) resp + 6) = 0;
+               *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
                
        case OID_GEN_MULTICAST_BYTES_RCV:
                DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
-                                       stats->multicast*1111;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr]
+                                       .stats->multicast * 1111);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -496,11 +476,12 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_GEN_MULTICAST_FRAMES_RCV:
                DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
-                                       stats->multicast;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr]
+                                       .stats->multicast);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -508,11 +489,12 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_GEN_BROADCAST_BYTES_RCV:
                DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
-                                       stats->rx_packets/42*255;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr]
+                                       .stats->rx_packets/42*255);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -520,11 +502,12 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_GEN_BROADCAST_FRAMES_RCV:
                DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
-                                       stats->rx_packets/42;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr]
+                                       .stats->rx_packets/42);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -532,61 +515,25 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_GEN_RCV_CRC_ERROR:
                DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
-                                       stats->rx_crc_errors;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr]
+                                       .stats->rx_crc_errors);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
                
        case OID_GEN_TRANSMIT_QUEUE_LENGTH:
                DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__);
-               *((u32 *) resp + 6) = 0;
+               *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
-               
-       case OID_GEN_GET_TIME_CAPS:
-               DEBUG("%s: OID_GEN_GET_TIME_CAPS\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_GET_NETCARD_TIME:
-               DEBUG("%s: OID_GEN_GET_NETCARD_TIME\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_NETCARD_LOAD:
-               DEBUG("%s: OID_GEN_NETCARD_LOAD\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_DEVICE_PROFILE:
-               DEBUG("%s: OID_GEN_DEVICE_PROFILE\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_INIT_TIME_MS:
-               DEBUG("%s: OID_GEN_INIT_TIME_MS\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_RESET_COUNTS:
-               DEBUG("%s: OID_GEN_RESET_COUNTS\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_MEDIA_SENSE_COUNTS:
-               DEBUG("%s: OID_GEN_MEDIA_SENSE_COUNTS\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_FRIENDLY_NAME:
-               DEBUG("%s: OID_GEN_FRIENDLY_NAME\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_MINIPORT_INFO:
-               DEBUG("%s: OID_GEN_MINIPORT_INFO\n", __FUNCTION__);
-               break;
-               
-       case OID_GEN_RESET_VERIFY_PARAMETERS:
-               DEBUG("%s: OID_GEN_RESET_VERIFY_PARAMETERS\n", __FUNCTION__);
-               break;
-               
+#endif /* RNDIS_OPTIONAL_STATS */
+
+       /* ieee802.3 OIDs (table 4-3) */
+
        /* mandatory */
        case OID_802_3_PERMANENT_ADDRESS:
                DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__);
@@ -597,7 +544,7 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
                                length);
                        retval = 0;
                } else {
-                       *((u32 *) resp + 6) = 0;
+                       *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                        retval = 0;
                }
                break;
@@ -619,7 +566,7 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
                DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
                length = 4;
                /* Multicast base address only */
-               *((u32 *) resp + 6) = 0xE0000000;
+               *((u32 *) resp + 6) = __constant_cpu_to_le32 (0xE0000000);
                retval = 0;
                break;
                
@@ -628,22 +575,25 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
                DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__);
                 length = 4;
                /* Multicast base address only */
-               *((u32 *) resp + 6) = 1;
+               *((u32 *) resp + 6) = __constant_cpu_to_le32 (1);
                retval = 0;
                break;
                
        case OID_802_3_MAC_OPTIONS:
                DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__);
                break;
-               
+
+       /* ieee802.3 statistics OIDs (table 4-4) */
+
        /* mandatory */
        case OID_802_3_RCV_ERROR_ALIGNMENT:
                DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats)
                {
                        length = 4;
-                       *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
-                                       .stats->rx_frame_errors;
+                       *((u32 *) resp + 6) = cpu_to_le32 (
+                               rndis_per_dev_params [configNr]
+                                       .stats->rx_frame_errors);
                        retval = 0;
                }
                break;
@@ -652,7 +602,7 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_802_3_XMIT_ONE_COLLISION:
                DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__);
                length = 4;
-               *((u32 *) resp + 6) = 0;
+               *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
                
@@ -660,10 +610,11 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
        case OID_802_3_XMIT_MORE_COLLISIONS:
                DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__);
                length = 4;
-               *((u32 *) resp + 6) = 0;
+               *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
                
+#ifdef RNDIS_OPTIONAL_STATS
        case OID_802_3_XMIT_DEFERRED:
                DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__);
                /* TODO */
@@ -698,14 +649,46 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
                DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__);
                /* TODO */
                break;          
-               
-       default: printk (KERN_ERR "%s: unknown OID 0x%08X\n", 
+#endif /* RNDIS_OPTIONAL_STATS */
+
+#ifdef RNDIS_PM
+       /* power management OIDs (table 4-5) */
+       case OID_PNP_CAPABILITIES:
+               DEBUG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__);
+
+               /* just PM, and remote wakeup on link status change
+                * (not magic packet or pattern match)
+                */
+               length = sizeof (struct NDIS_PNP_CAPABILITIES);
+               memset (resp, 0, length);
+               {
+                       struct NDIS_PNP_CAPABILITIES *caps = (void *) resp;
+
+                       caps->Flags = NDIS_DEVICE_WAKE_UP_ENABLE;
+                       caps->WakeUpCapabilities.MinLinkChangeWakeUp 
+                                = NdisDeviceStateD3;
+
+                       /* FIXME then use usb_gadget_wakeup(), and
+                        * set USB_CONFIG_ATT_WAKEUP in config desc
+                        */
+               }
+               retval = 0;
+               break;
+       case OID_PNP_QUERY_POWER:
+               DEBUG("%s: OID_PNP_QUERY_POWER\n", __FUNCTION__);
+               /* sure, handle any power state that maps to USB suspend */
+               retval = 0;
+               break;
+#endif
+
+       default:
+               printk (KERN_WARNING "%s: query unknown OID 0x%08X\n", 
                         __FUNCTION__, OID);
        }
        
-       resp->InformationBufferOffset = 16;
-       resp->InformationBufferLength = length;
-       resp->MessageLength = 24 + length;
+       resp->InformationBufferOffset = __constant_cpu_to_le32 (16);
+       resp->InformationBufferLength = cpu_to_le32 (length);
+       resp->MessageLength = cpu_to_le32 (24 + length);
        r->length = 24 + length;
        return retval;
 }
@@ -715,9 +698,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
 {
        rndis_set_cmplt_type            *resp;
        int                             i, retval = -ENOTSUPP;
-       struct rndis_config_parameter   *param;
        struct rndis_params             *params;
-       u8 *cp;
 
        if (!r)
                return -ENOMEM;
@@ -725,20 +706,37 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
        if (!resp)
                return -ENOMEM;
 
-       cp = (u8 *)resp;
+       DEBUG("set OID %08x value, len %d:\n", OID, buf_len);
+       for (i = 0; i < buf_len; i += 16) {
+               DEBUG ("%03d: "
+                       " %02x %02x %02x %02x"
+                       " %02x %02x %02x %02x"
+                       " %02x %02x %02x %02x"
+                       " %02x %02x %02x %02x"
+                       "\n",
+                       i,
+                       buf[i], buf [i+1],
+                               buf[i+2], buf[i+3],
+                       buf[i+4], buf [i+5],
+                               buf[i+6], buf[i+7],
+                       buf[i+8], buf [i+9],
+                               buf[i+10], buf[i+11],
+                       buf[i+12], buf [i+13],
+                               buf[i+14], buf[i+15]);
+       }
 
        switch (OID) {
        case OID_GEN_CURRENT_PACKET_FILTER:
                params = &rndis_per_dev_params [configNr];
                retval = 0;
 
-               /* FIXME use this NDIS_PACKET_TYPE_* bitflags to
+               /* FIXME use these NDIS_PACKET_TYPE_* bitflags to
                 * filter packets in hard_start_xmit()
                 * NDIS_PACKET_TYPE_x == CDC_PACKET_TYPE_x for x in:
                 *      PROMISCUOUS, DIRECTED,
                 *      MULTICAST, ALL_MULTICAST, BROADCAST
                 */
-               params->filter = *(u32 *)buf;
+               params->filter = cpu_to_le32p((u32 *)buf);
                DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
                        __FUNCTION__, params->filter);
 
@@ -763,23 +761,40 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
                DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
                retval = 0;
                break;
-               
+#if 0
        case OID_GEN_RNDIS_CONFIG_PARAMETER:
-               DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER\n", __FUNCTION__);
+               {
+               struct rndis_config_parameter   *param;
                param = (struct rndis_config_parameter *) buf;
-               if (param) {
-                       for (i = 0; i < param->ParameterNameLength; i++) {
-                               DEBUG ("%c", 
-                                      *(buf + param->ParameterNameOffset + i));
-                       }
-                       DEBUG ("\n");
+               DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
+                       __FUNCTION__,
+                       min(cpu_to_le32(param->ParameterNameLength),80),
+                       buf + param->ParameterNameOffset);
+               retval = 0;
                }
-               
+               break;
+#endif
+
+#ifdef RNDIS_PM
+       case OID_PNP_SET_POWER:
+               DEBUG ("OID_PNP_SET_POWER\n");
+               /* sure, handle any power state that maps to USB suspend */
                retval = 0;
                break;
-               
-       default: printk (KERN_ERR "%s: unknown OID 0x%08X\n", 
-                        __FUNCTION__, OID);
+
+       case OID_PNP_ENABLE_WAKE_UP:
+               /* always-connected ... */
+               DEBUG ("OID_PNP_ENABLE_WAKE_UP\n");
+               retval = 0;
+               break;
+
+       // no PM resume patterns supported (specified where?)
+       // so OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN always fails
+#endif
+
+       default:
+               printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n", 
+                        __FUNCTION__, OID, buf_len);
        }
        
        return retval;
@@ -804,22 +819,24 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
        
        if (!resp) return -ENOMEM;
        
-       resp->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
-       resp->MessageLength = 52;
-       resp->RequestID = buf->RequestID;
-       resp->Status = RNDIS_STATUS_SUCCESS;
-       resp->MajorVersion = RNDIS_MAJOR_VERSION;
-       resp->MinorVersion = RNDIS_MINOR_VERSION;
-       resp->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
-       resp->Medium = RNDIS_MEDIUM_802_3;
-       resp->MaxPacketsPerTransfer = 1;
-       resp->MaxTransferSize = rndis_per_dev_params [configNr].dev->mtu
+       resp->MessageType = __constant_cpu_to_le32 (
+                       REMOTE_NDIS_INITIALIZE_CMPLT);
+       resp->MessageLength = __constant_cpu_to_le32 (52);
+       resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
+       resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
+       resp->MajorVersion = __constant_cpu_to_le32 (RNDIS_MAJOR_VERSION);
+       resp->MinorVersion = __constant_cpu_to_le32 (RNDIS_MINOR_VERSION);
+       resp->DeviceFlags = __constant_cpu_to_le32 (RNDIS_DF_CONNECTIONLESS);
+       resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3);
+       resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1);
+       resp->MaxTransferSize = cpu_to_le32 (
+                 rndis_per_dev_params [configNr].dev->mtu
                + sizeof (struct ethhdr)
                + sizeof (struct rndis_packet_msg_type)
-               + 22;
-       resp->PacketAlignmentFactor = 0;
-       resp->AFListOffset = 0;
-       resp->AFListSize = 0;
+               + 22);
+       resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0);
+       resp->AFListOffset = __constant_cpu_to_le32 (0);
+       resp->AFListSize = __constant_cpu_to_le32 (0);
        
        if (rndis_per_dev_params [configNr].ack)
            rndis_per_dev_params [configNr].ack (
@@ -833,7 +850,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
        rndis_query_cmplt_type *resp;
        rndis_resp_t            *r;
        
-       DEBUG("%s: OID = %08X\n", __FUNCTION__, buf->OID);
+       // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID));
        if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
        
        /* 
@@ -847,17 +864,18 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
        
        if (!resp) return -ENOMEM;
        
-       resp->MessageType = REMOTE_NDIS_QUERY_CMPLT;
-       resp->MessageLength = 24;
-       resp->RequestID = buf->RequestID;
+       resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT);
+       resp->MessageLength = __constant_cpu_to_le32 (24);
+       resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
        
-       if (gen_ndis_query_resp (configNr, buf->OID, r)) {
+       if (gen_ndis_query_resp (configNr, cpu_to_le32 (buf->OID), r)) {
                /* OID not supported */
-               resp->Status = RNDIS_STATUS_NOT_SUPPORTED;
-               resp->InformationBufferLength = 0;
-               resp->InformationBufferOffset = 0;
+               resp->Status = __constant_cpu_to_le32 (
+                               RNDIS_STATUS_NOT_SUPPORTED);
+               resp->InformationBufferLength = __constant_cpu_to_le32 (0);
+               resp->InformationBufferOffset = __constant_cpu_to_le32 (0);
        } else
-               resp->Status = RNDIS_STATUS_SUCCESS;
+               resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
        
        if (rndis_per_dev_params [configNr].ack)
            rndis_per_dev_params [configNr].ack (
@@ -867,38 +885,42 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
 
 static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
 {
+       u32                     BufLength, BufOffset;
        rndis_set_cmplt_type    *resp;
        rndis_resp_t            *r;
-       int                     i;
        
        r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
        
        if (!r) return -ENOMEM;
        resp = (rndis_set_cmplt_type *) r->buf;
        if (!resp) return -ENOMEM;
-       
-       DEBUG("%s: Length: %d\n", __FUNCTION__, buf->InformationBufferLength);
-       DEBUG("%s: Offset: %d\n", __FUNCTION__, buf->InformationBufferOffset);
+
+       BufLength = cpu_to_le32 (buf->InformationBufferLength);
+       BufOffset = cpu_to_le32 (buf->InformationBufferOffset);
+
+#ifdef VERBOSE
+       DEBUG("%s: Length: %d\n", __FUNCTION__, BufLength);
+       DEBUG("%s: Offset: %d\n", __FUNCTION__, BufOffset);
        DEBUG("%s: InfoBuffer: ", __FUNCTION__);
        
-       for (i = 0; i < buf->InformationBufferLength; i++) {
-               DEBUG ("%02x ", *(((u8 *) buf) + i + 12 +
-                      buf->InformationBufferOffset));
+       for (i = 0; i < BufLength; i++) {
+               DEBUG ("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
        }
        
        DEBUG ("\n");
+#endif
        
-       resp->MessageType = REMOTE_NDIS_SET_CMPLT;
-       resp->MessageLength = 16;
-       resp->RequestID = buf->RequestID;
-       if (gen_ndis_set_resp (configNr, buf->OID, 
-                              ((u8 *) buf) + 28, 
-                              buf->InformationBufferLength, r))
-           resp->Status = RNDIS_STATUS_NOT_SUPPORTED;
-       else resp->Status = RNDIS_STATUS_SUCCESS;
+       resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
+       resp->MessageLength = __constant_cpu_to_le32 (16);
+       resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
+       if (gen_ndis_set_resp (configNr, cpu_to_le32 (buf->OID), 
+                              ((u8 *) buf) + 8 + BufOffset, BufLength, r))
+           resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED);
+       else resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
        
        if (rndis_per_dev_params [configNr].ack)
-           rndis_per_dev_params [configNr].ack (rndis_per_dev_params [configNr].dev);
+           rndis_per_dev_params [configNr].ack (
+                       rndis_per_dev_params [configNr].dev);
        
        return 0;
 }
@@ -914,10 +936,11 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
        resp = (rndis_reset_cmplt_type *) r->buf;
        if (!resp) return -ENOMEM;
        
-       resp->MessageType = REMOTE_NDIS_RESET_CMPLT;
-       resp->MessageLength = 16;
-       resp->Status = RNDIS_STATUS_SUCCESS;
-       resp->AddressingReset = 1; /* resent information */
+       resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);
+       resp->MessageLength = __constant_cpu_to_le32 (16);
+       resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
+       /* resent information */
+       resp->AddressingReset = __constant_cpu_to_le32 (1);
        
        if (rndis_per_dev_params [configNr].ack)
            rndis_per_dev_params [configNr].ack (
@@ -938,10 +961,11 @@ static int rndis_keepalive_response (int configNr,
        resp = (rndis_keepalive_cmplt_type *) r->buf;
        if (!resp) return -ENOMEM;
                
-       resp->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
-       resp->MessageLength = 16;
-       resp->RequestID = buf->RequestID;
-       resp->Status = RNDIS_STATUS_SUCCESS;
+       resp->MessageType = __constant_cpu_to_le32 (
+                       REMOTE_NDIS_KEEPALIVE_CMPLT);
+       resp->MessageLength = __constant_cpu_to_le32 (16);
+       resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
+       resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
        
        if (rndis_per_dev_params [configNr].ack)
            rndis_per_dev_params [configNr].ack (
@@ -969,11 +993,12 @@ static int rndis_indicate_status_msg (int configNr, u32 status)
        resp = (rndis_indicate_status_msg_type *) r->buf;
        if (!resp) return -ENOMEM;
        
-       resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
-       resp->MessageLength = 20;
-       resp->Status = status;
-       resp->StatusBufferLength = 0;
-       resp->StatusBufferOffset = 0;
+       resp->MessageType = __constant_cpu_to_le32 (
+                       REMOTE_NDIS_INDICATE_STATUS_MSG);
+       resp->MessageLength = __constant_cpu_to_le32 (20);
+       resp->Status = cpu_to_le32 (status);
+       resp->StatusBufferLength = __constant_cpu_to_le32 (0);
+       resp->StatusBufferOffset = __constant_cpu_to_le32 (0);
        
        if (rndis_per_dev_params [configNr].ack) 
            rndis_per_dev_params [configNr].ack (
@@ -1014,8 +1039,8 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
                return -ENOMEM;
        
        tmp = (u32 *) buf; 
-       MsgType = *tmp;
-       MsgLength = *(tmp + 1);
+       MsgType   = cpu_to_le32p(tmp++);
+       MsgLength = cpu_to_le32p(tmp++);
        
        if (configNr >= RNDIS_MAX_CONFIGS)
                return -ENOTSUPP;
@@ -1025,14 +1050,14 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
        switch (MsgType)
        {
        case REMOTE_NDIS_INITIALIZE_MSG:
-               DEBUG(KERN_INFO "%s: REMOTE_NDIS_INITIALIZE_MSG\n", 
+               DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", 
                        __FUNCTION__ );
                params->state = RNDIS_INITIALIZED;
                return  rndis_init_response (configNr,
                                             (rndis_init_msg_type *) buf);
                
        case REMOTE_NDIS_HALT_MSG:
-               DEBUG(KERN_INFO "%s: REMOTE_NDIS_HALT_MSG\n",
+               DEBUG("%s: REMOTE_NDIS_HALT_MSG\n",
                        __FUNCTION__ );
                params->state = RNDIS_UNINITIALIZED;
                if (params->dev) {
@@ -1042,34 +1067,57 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
                return 0;
                
        case REMOTE_NDIS_QUERY_MSG:
-               DEBUG(KERN_INFO "%s: REMOTE_NDIS_QUERY_MSG\n", 
-                       __FUNCTION__ );
                return rndis_query_response (configNr, 
                                             (rndis_query_msg_type *) buf);
                
        case REMOTE_NDIS_SET_MSG:
-               DEBUG(KERN_INFO "%s: REMOTE_NDIS_SET_MSG\n", 
-                       __FUNCTION__ );
                return rndis_set_response (configNr, 
                                           (rndis_set_msg_type *) buf);
                
        case REMOTE_NDIS_RESET_MSG:
-               DEBUG(KERN_INFO "%s: REMOTE_NDIS_RESET_MSG\n", 
+               DEBUG("%s: REMOTE_NDIS_RESET_MSG\n", 
                        __FUNCTION__ );
                return rndis_reset_response (configNr,
                                             (rndis_reset_msg_type *) buf);
 
        case REMOTE_NDIS_KEEPALIVE_MSG:
                /* For USB: host does this every 5 seconds */
-               DEBUG(KERN_INFO "%s: REMOTE_NDIS_KEEPALIVE_MSG\n", 
+#ifdef VERBOSE
+               DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", 
                        __FUNCTION__ );
+#endif
                return rndis_keepalive_response (configNr,
                                                 (rndis_keepalive_msg_type *) 
                                                 buf);
                
        default: 
-               printk (KERN_ERR "%s: unknown RNDIS Message Type 0x%08X\n", 
-                       __FUNCTION__ , MsgType);
+               /* At least Windows XP emits some undefined RNDIS messages.
+                * In one case those messages seemed to relate to the host
+                * suspending itself.
+                */
+               printk (KERN_WARNING
+                       "%s: unknown RNDIS message 0x%08X len %d\n", 
+                       __FUNCTION__ , MsgType, MsgLength);
+               {
+                       unsigned i;
+                       for (i = 0; i < MsgLength; i += 16) {
+                               DEBUG ("%03d: "
+                                       " %02x %02x %02x %02x"
+                                       " %02x %02x %02x %02x"
+                                       " %02x %02x %02x %02x"
+                                       " %02x %02x %02x %02x"
+                                       "\n",
+                                       i,
+                                       buf[i], buf [i+1],
+                                               buf[i+2], buf[i+3],
+                                       buf[i+4], buf [i+5],
+                                               buf[i+6], buf[i+7],
+                                       buf[i+8], buf [i+9],
+                                               buf[i+10], buf[i+11],
+                                       buf[i+12], buf [i+13],
+                                               buf[i+14], buf[i+15]);
+                       }
+               }
                break;
        }
        
@@ -1079,13 +1127,12 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
 int rndis_register (int (* rndis_control_ack) (struct net_device *))
 {
        u8 i;
-       DEBUG("%s: ", __FUNCTION__ );
        
        for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
                if (!rndis_per_dev_params [i].used) {
                        rndis_per_dev_params [i].used = 1;
                        rndis_per_dev_params [i].ack = rndis_control_ack;
-                       DEBUG("configNr = %d\n", i);
+                       DEBUG("%s: configNr = %d\n", __FUNCTION__, i);
                        return i;
                }
        }
@@ -1145,10 +1192,10 @@ void rndis_add_hdr (struct sk_buff *skb)
        if (!skb) return;
        skb_push (skb, sizeof (struct rndis_packet_msg_type));
        memset (skb->data, 0, sizeof (struct rndis_packet_msg_type));
-       *((u32 *) skb->data) = 1;
-       *((u32 *) skb->data + 1) = skb->len;
-       *((u32 *) skb->data + 2) = 36;
-       *((u32 *) skb->data + 3) = skb->len - 44;
+       *((u32 *) skb->data) = __constant_cpu_to_le32 (1);
+       *((u32 *) skb->data + 1) = cpu_to_le32(skb->len);
+       *((u32 *) skb->data + 2) = __constant_cpu_to_le32 (36);
+       *((u32 *) skb->data + 3) = cpu_to_le32(skb->len - 44);
        
        return;
 }
@@ -1208,14 +1255,16 @@ static rndis_resp_t *rndis_add_response (int configNr, u32 length)
 
 int rndis_rm_hdr (u8 *buf, u32 *length)
 {
-       u32 i, messageLen, dataOffset;
+       u32 i, messageLen, dataOffset, *tmp;
        
+       tmp = (u32 *) buf; 
+
        if (!buf || !length) return -1;
-       if (*((u32 *) buf) != 1) return -1;
+       if (cpu_to_le32p(tmp++) != 1) return -1;
        
-       messageLen = *((u32 *) buf + 1);
-       
-       dataOffset = *((u32 *) buf + 2) + 8;
+       messageLen = cpu_to_le32p(tmp++);
+       dataOffset = cpu_to_le32p(tmp++) + 8;
+
        if (messageLen < dataOffset || messageLen > *length) return -1;
        
        for (i = dataOffset; i < messageLen; i++)
index 150ec8e..fa7d908 100644 (file)
 
 #define RNDIS_MEDIUM_802_3             0x00000000U
 
+/* from drivers/net/sk98lin/h/skgepnmi.h */
+#define OID_PNP_CAPABILITIES                   0xFD010100
+#define OID_PNP_SET_POWER                      0xFD010101
+#define OID_PNP_QUERY_POWER                    0xFD010102
+#define OID_PNP_ADD_WAKE_UP_PATTERN            0xFD010103
+#define OID_PNP_REMOVE_WAKE_UP_PATTERN         0xFD010104
+#define OID_PNP_ENABLE_WAKE_UP                 0xFD010106
+
+
 /* supported OIDs */
 static const u32 oid_supported_list [] = 
 {
-       /* mandatory general */
        /* the general stuff */
        OID_GEN_SUPPORTED_LIST,
        OID_GEN_HARDWARE_STATUS,
@@ -70,7 +78,6 @@ static const u32 oid_supported_list [] =
        OID_GEN_MEDIA_IN_USE,
        OID_GEN_MAXIMUM_FRAME_SIZE,
        OID_GEN_LINK_SPEED,
-       OID_GEN_TRANSMIT_BUFFER_SPACE,
        OID_GEN_TRANSMIT_BLOCK_SIZE,
        OID_GEN_RECEIVE_BLOCK_SIZE,
        OID_GEN_VENDOR_ID,
@@ -78,10 +85,11 @@ static const u32 oid_supported_list [] =
        OID_GEN_VENDOR_DRIVER_VERSION,
        OID_GEN_CURRENT_PACKET_FILTER,
        OID_GEN_MAXIMUM_TOTAL_SIZE,
-       OID_GEN_MAC_OPTIONS,
        OID_GEN_MEDIA_CONNECT_STATUS,
        OID_GEN_PHYSICAL_MEDIUM,
+#if 0
        OID_GEN_RNDIS_CONFIG_PARAMETER,
+#endif
        
        /* the statistical stuff */
        OID_GEN_XMIT_OK,
@@ -89,6 +97,7 @@ static const u32 oid_supported_list [] =
        OID_GEN_XMIT_ERROR,
        OID_GEN_RCV_ERROR,
        OID_GEN_RCV_NO_BUFFER,
+#ifdef RNDIS_OPTIONAL_STATS
        OID_GEN_DIRECTED_BYTES_XMIT,
        OID_GEN_DIRECTED_FRAMES_XMIT,
        OID_GEN_MULTICAST_BYTES_XMIT,
@@ -103,6 +112,7 @@ static const u32 oid_supported_list [] =
        OID_GEN_BROADCAST_FRAMES_RCV,
        OID_GEN_RCV_CRC_ERROR,
        OID_GEN_TRANSMIT_QUEUE_LENGTH,
+#endif /* RNDIS_OPTIONAL_STATS */
 
        /* mandatory 802.3 */
        /* the general stuff */
@@ -115,7 +125,30 @@ static const u32 oid_supported_list [] =
        /* the statistical stuff */
        OID_802_3_RCV_ERROR_ALIGNMENT,
        OID_802_3_XMIT_ONE_COLLISION,
-       OID_802_3_XMIT_MORE_COLLISIONS
+       OID_802_3_XMIT_MORE_COLLISIONS,
+#ifdef RNDIS_OPTIONAL_STATS
+       OID_802_3_XMIT_DEFERRED,
+       OID_802_3_XMIT_MAX_COLLISIONS,
+       OID_802_3_RCV_OVERRUN,
+       OID_802_3_XMIT_UNDERRUN,
+       OID_802_3_XMIT_HEARTBEAT_FAILURE,
+       OID_802_3_XMIT_TIMES_CRS_LOST,
+       OID_802_3_XMIT_LATE_COLLISIONS,
+#endif /* RNDIS_OPTIONAL_STATS */
+
+#ifdef RNDIS_PM
+       /* PM and wakeup are mandatory for USB: */
+
+       /* power management */
+       OID_PNP_CAPABILITIES,
+       OID_PNP_QUERY_POWER,
+       OID_PNP_SET_POWER,
+
+       /* wake up host */
+       OID_PNP_ENABLE_WAKE_UP,
+       OID_PNP_ADD_WAKE_UP_PATTERN,
+       OID_PNP_REMOVE_WAKE_UP_PATTERN,
+#endif
 };
 
 
index 08fb764..aaf3334 100644 (file)
@@ -290,16 +290,17 @@ static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap)
 {
        if (cap & (1 << 16)) {
                int msec = 500;
+               struct pci_dev *pdev = to_pci_dev(ehci->hcd.self.controller);
 
                /* request handoff to OS */
-               cap &= 1 << 24;
-               pci_write_config_dword (to_pci_dev(ehci->hcd.self.controller), where, cap);
+               cap |= 1 << 24;
+               pci_write_config_dword(pdev, where, cap);
 
                /* and wait a while for it to happen */
                do {
                        msleep(10);
                        msec -= 10;
-                       pci_read_config_dword (to_pci_dev(ehci->hcd.self.controller), where, &cap);
+                       pci_read_config_dword(pdev, where, &cap);
                } while ((cap & (1 << 16)) && msec);
                if (cap & (1 << 16)) {
                        ehci_err (ehci, "BIOS handoff failed (%d, %04x)\n",
@@ -343,6 +344,7 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
        dbg_hcc_params (ehci, "reset");
 
 #ifdef CONFIG_PCI
+       writel(0, &ehci->regs->intr_enable);
        /* EHCI 0.96 and later may have "extended capabilities" */
        if (hcd->self.controller->bus == &pci_bus_type)
                temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
@@ -520,7 +522,7 @@ static int ehci_start (struct usb_hcd *hcd)
 
        /* wire up the root hub */
        bus = hcd_to_bus (hcd);
-       bus->root_hub = udev = usb_alloc_dev (NULL, bus, 0);
+       udev = usb_alloc_dev (NULL, bus, 0);
        if (!udev) {
 done2:
                ehci_mem_cleanup (ehci);
@@ -553,11 +555,10 @@ done2:
         * and device drivers may start it running.
         */
        udev->speed = USB_SPEED_HIGH;
-       if (hcd_register_root (hcd) != 0) {
+       if (hcd_register_root (udev, hcd) != 0) {
                if (hcd->state == USB_STATE_RUNNING)
                        ehci_ready (ehci);
                ehci_reset (ehci);
-               bus->root_hub = 0;
                usb_put_dev (udev); 
                retval = -ENODEV;
                goto done2;
index 3682fb9..d3bcf48 100644 (file)
@@ -483,7 +483,7 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
                qh->start = frame;
 
                /* reset S-frame and (maybe) C-frame masks */
-               qh->hw_info2 &= ~0xffff;
+               qh->hw_info2 &= ~__constant_cpu_to_le32(0xffff);
                qh->hw_info2 |= cpu_to_le32 (1 << uframe) | c_mask;
        } else
                dbg ("reused previous qh %p schedule", qh);
index a4dd462..aaaa705 100644 (file)
@@ -557,18 +557,24 @@ static int rh_unlink_urb (struct urb * urb)
 static int rh_connect_rh (hci_t * hci)
 {
        struct usb_device *usb_dev;
+       int retval;
 
        hci->rh.devnum = 0;
        usb_dev = usb_alloc_dev (NULL, hci->bus, 0);
        if (!usb_dev)
                return -ENOMEM;
 
-       hci->bus->root_hub = usb_dev;
        usb_dev->devnum = 1;
        usb_dev->bus->devnum_next = usb_dev->devnum + 1;
        set_bit (usb_dev->devnum, usb_dev->bus->devmap.devicemap);
 
-       if (usb_new_device (usb_dev) != 0) {
+       down (&usb_bus_list_lock);
+       hci->bus->root_hub = usb_dev;
+       retval = usb_new_device (usb_dev);
+       if (retval != 0)
+               hci->bus->root_hub = NULL;
+       up (&usb_bus_list_lock);
+       if (retval != 0) {
                usb_put_dev (usb_dev);
                return -ENODEV;
        }
index 3918eb3..582a55a 100644 (file)
@@ -134,13 +134,13 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
        struct ohci_regs        *regs = controller->regs;
        u32                     temp;
 
-       temp = readl (&regs->revision) & 0xff;
+       temp = ohci_readl (&regs->revision) & 0xff;
        ohci_dbg_sw (controller, next, size,
                "OHCI %d.%d, %s legacy support registers\n",
                0x03 & (temp >> 4), (temp & 0x0f),
                (temp & 0x10) ? "with" : "NO");
 
-       temp = readl (&regs->control);
+       temp = ohci_readl (&regs->control);
        ohci_dbg_sw (controller, next, size,
                "control 0x%03x%s%s%s HCFS=%s%s%s%s%s CBSR=%d\n",
                temp,
@@ -155,7 +155,7 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
                temp & OHCI_CTRL_CBSR
                );
 
-       temp = readl (&regs->cmdstatus);
+       temp = ohci_readl (&regs->cmdstatus);
        ohci_dbg_sw (controller, next, size,
                "cmdstatus 0x%05x SOC=%d%s%s%s%s\n", temp,
                (temp & OHCI_SOC) >> 16,
@@ -166,26 +166,26 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
                );
 
        ohci_dump_intr_mask (controller, "intrstatus",
-                       readl (&regs->intrstatus), next, size);
+                       ohci_readl (&regs->intrstatus), next, size);
        ohci_dump_intr_mask (controller, "intrenable",
-                       readl (&regs->intrenable), next, size);
+                       ohci_readl (&regs->intrenable), next, size);
        // intrdisable always same as intrenable
 
        maybe_print_eds (controller, "ed_periodcurrent",
-                       readl (&regs->ed_periodcurrent), next, size);
+                       ohci_readl (&regs->ed_periodcurrent), next, size);
 
        maybe_print_eds (controller, "ed_controlhead",
-                       readl (&regs->ed_controlhead), next, size);
+                       ohci_readl (&regs->ed_controlhead), next, size);
        maybe_print_eds (controller, "ed_controlcurrent",
-                       readl (&regs->ed_controlcurrent), next, size);
+                       ohci_readl (&regs->ed_controlcurrent), next, size);
 
        maybe_print_eds (controller, "ed_bulkhead",
-                       readl (&regs->ed_bulkhead), next, size);
+                       ohci_readl (&regs->ed_bulkhead), next, size);
        maybe_print_eds (controller, "ed_bulkcurrent",
-                       readl (&regs->ed_bulkcurrent), next, size);
+                       ohci_readl (&regs->ed_bulkcurrent), next, size);
 
        maybe_print_eds (controller, "donehead",
-                       readl (&regs->donehead), next, size);
+                       ohci_readl (&regs->donehead), next, size);
 }
 
 #define dbg_port_sw(hc,num,value,next,size) \
@@ -637,7 +637,7 @@ show_registers (struct class_device *class_dev, char *buf)
                        "hcca frame 0x%04x\n", OHCI_FRAME_NO(ohci->hcca));
 
        /* other registers mostly affect frame timings */
-       rdata = readl (&regs->fminterval);
+       rdata = ohci_readl (&regs->fminterval);
        temp = scnprintf (next, size,
                        "fmintvl 0x%08x %sFSMPS=0x%04x FI=0x%04x\n",
                        rdata, (rdata >> 31) ? " FIT" : "",
@@ -645,20 +645,20 @@ show_registers (struct class_device *class_dev, char *buf)
        size -= temp;
        next += temp;
 
-       rdata = readl (&regs->fmremaining);
+       rdata = ohci_readl (&regs->fmremaining);
        temp = scnprintf (next, size, "fmremaining 0x%08x %sFR=0x%04x\n",
                        rdata, (rdata >> 31) ? " FRT" : "",
                        rdata & 0x3fff);
        size -= temp;
        next += temp;
 
-       rdata = readl (&regs->periodicstart);
+       rdata = ohci_readl (&regs->periodicstart);
        temp = scnprintf (next, size, "periodicstart 0x%04x\n",
                        rdata & 0x3fff);
        size -= temp;
        next += temp;
 
-       rdata = readl (&regs->lsthresh);
+       rdata = ohci_readl (&regs->lsthresh);
        temp = scnprintf (next, size, "lsthresh 0x%04x\n",
                        rdata & 0x3fff);
        size -= temp;
index b5279a0..690e2be 100644 (file)
@@ -17,6 +17,7 @@
  *
  * History:
  * 
+ * 2004/03/24 LH7A404 support (Durgesh Pattamatta & Marc Singer)
  * 2004/02/04 use generic dma_* functions instead of pci_* (dsaxena@plexity.net)
  * 2003/02/24 show registers in sysfs (Kevin Brosius)
  *
@@ -393,7 +394,7 @@ static int hc_reset (struct ohci_hcd *ohci)
 
        /* boot firmware should have set this up (5.1.1.3.1) */
        if (!ohci->fminterval) {
-               temp = readl (&ohci->regs->fminterval);
+               temp = ohci_readl (&ohci->regs->fminterval);
                if (temp & 0x3fff0000)
                        ohci->fminterval = temp;
                else
@@ -405,7 +406,7 @@ static int hc_reset (struct ohci_hcd *ohci)
         * On PA-RISC, PDC can leave IR set incorrectly; ignore it there.
         */
 #ifndef __hppa__
-       if (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
+       if (ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) {
                ohci_dbg (ohci, "USB HC TakeOver from BIOS/SMM\n");
 
                /* this timeout is arbitrary.  we make it long, so systems
@@ -416,7 +417,7 @@ static int hc_reset (struct ohci_hcd *ohci)
 
                writel (OHCI_INTR_OC, &ohci->regs->intrenable);
                writel (OHCI_OCR, &ohci->regs->cmdstatus);
-               while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
+               while (ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) {
                        msleep (10);
                        if (--temp == 0) {
                                ohci_err (ohci, "USB HC TakeOver failed!\n");
@@ -430,13 +431,13 @@ static int hc_reset (struct ohci_hcd *ohci)
        writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
 
        ohci_dbg (ohci, "reset, control = 0x%x\n",
-               readl (&ohci->regs->control));
+                 ohci_readl (&ohci->regs->control));
 
        /* Reset USB (needed by some controllers); RemoteWakeupConnected
         * saved if boot firmware (BIOS/SMM/...) told us it's connected
         * (for OHCI integrated on mainboard, it normally is)
         */
-       ohci->hc_control = readl (&ohci->regs->control);
+       ohci->hc_control = ohci_readl (&ohci->regs->control);
        ohci->hc_control &= OHCI_CTRL_RWC;      /* hcfs 0 = RESET */
        if (ohci->hc_control)
                ohci->hcd.can_wakeup = 1;
@@ -450,13 +451,13 @@ static int hc_reset (struct ohci_hcd *ohci)
                                &ohci->regs->roothub.portstatus [temp]);
        }
        // flush those pci writes
-       (void) readl (&ohci->regs->control);
+       (void) ohci_readl (&ohci->regs->control);
        msleep (50);
 
        /* HC Reset requires max 10 us delay */
        writel (OHCI_HCR,  &ohci->regs->cmdstatus);
        temp = 30;      /* ... allow extra time */
-       while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
+       while ((ohci_readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
                if (--temp == 0) {
                        ohci_err (ohci, "USB HC reset timed out!\n");
                        return -1;
@@ -473,7 +474,7 @@ static int hc_reset (struct ohci_hcd *ohci)
         */
        writel (ohci->hc_control, &ohci->regs->control);
        // flush those pci writes
-       (void) readl (&ohci->regs->control);
+       (void) ohci_readl (&ohci->regs->control);
 
        return 0;
 }
@@ -505,8 +506,8 @@ static int hc_start (struct ohci_hcd *ohci)
        /* some OHCI implementations are finicky about how they init.
         * bogus values here mean not even enumeration could work.
         */
-       if ((readl (&ohci->regs->fminterval) & 0x3fff0000) == 0
-                       || !readl (&ohci->regs->periodicstart)) {
+       if ((ohci_readl (&ohci->regs->fminterval) & 0x3fff0000) == 0
+                       || !ohci_readl (&ohci->regs->periodicstart)) {
                ohci_err (ohci, "init err\n");
                return -EOVERFLOW;
        }
@@ -548,7 +549,7 @@ static int hc_start (struct ohci_hcd *ohci)
        writel (RH_HS_LPSC, &ohci->regs->roothub.status);
        writel (power_switching ? RH_B_PPCM : 0, &ohci->regs->roothub.b);
        // flush those pci writes
-       (void) readl (&ohci->regs->control);
+       (void) ohci_readl (&ohci->regs->control);
 
        // POTPGT delay is bits 24-31, in 2 ms units.
        mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
@@ -560,7 +561,7 @@ static int hc_start (struct ohci_hcd *ohci)
        }
  
        /* connect the virtual root hub */
-       bus->root_hub = udev = usb_alloc_dev (NULL, bus, 0);
+       udev = usb_alloc_dev (NULL, bus, 0);
        ohci->hcd.state = USB_STATE_RUNNING;
        if (!udev) {
                disable (ohci);
@@ -570,9 +571,8 @@ static int hc_start (struct ohci_hcd *ohci)
        }
 
        udev->speed = USB_SPEED_FULL;
-       if (hcd_register_root (&ohci->hcd) != 0) {
+       if (hcd_register_root (udev, &ohci->hcd) != 0) {
                usb_put_dev (udev);
-               bus->root_hub = NULL;
                disable (ohci);
                ohci->hc_control &= ~OHCI_CTRL_HCFS;
                writel (ohci->hc_control, &ohci->regs->control);
@@ -592,19 +592,20 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
        struct ohci_regs        *regs = ohci->regs;
        int                     ints; 
 
-       /* we can eliminate a (slow) readl() if _only_ WDH caused this irq */
+       /* we can eliminate a (slow) ohci_readl()
+          if _only_ WDH caused this irq */
        if ((ohci->hcca->done_head != 0)
                        && ! (le32_to_cpup (&ohci->hcca->done_head) & 0x01)) {
                ints =  OHCI_INTR_WDH;
 
        /* cardbus/... hardware gone before remove() */
-       } else if ((ints = readl (&regs->intrstatus)) == ~(u32)0) {
+       } else if ((ints = ohci_readl (&regs->intrstatus)) == ~(u32)0) {
                disable (ohci);
                ohci_dbg (ohci, "device removed!\n");
                return IRQ_HANDLED;
 
        /* interrupt for some other device? */
-       } else if ((ints &= readl (&regs->intrenable)) == 0) {
+       } else if ((ints &= ohci_readl (&regs->intrenable)) == 0) {
                return IRQ_NONE;
        } 
 
@@ -650,7 +651,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
                writel (ints, &regs->intrstatus);
                writel (OHCI_INTR_MIE, &regs->intrenable);      
                // flush those pci writes
-               (void) readl (&ohci->regs->control);
+               (void) ohci_readl (&ohci->regs->control);
        }
 
        return IRQ_HANDLED;
@@ -798,6 +799,14 @@ MODULE_LICENSE ("GPL");
 #include "ohci-omap.c"
 #endif
 
-#if !(defined(CONFIG_PCI) || defined(CONFIG_SA1111) || defined(CONFIG_ARCH_OMAP))
+#ifdef CONFIG_ARCH_LH7A404
+#include "ohci-lh7a404.c"
+#endif
+
+#if !(defined(CONFIG_PCI) \
+      || defined(CONFIG_SA1111) \
+      || defined(CONFIG_ARCH_OMAP) \
+      || defined (CONFIG_ARCH_LH7A404) \
+       )
 #error "missing bus glue for ohci-hcd"
 #endif
index 516d87d..bb6c3da 100644 (file)
  * till some bits (mostly reserved) are clear; ok for all revs.
  */
 #define read_roothub(hc, register, mask) ({ \
-       u32 temp = readl (&hc->regs->roothub.register); \
+       u32 temp = ohci_readl (&hc->regs->roothub.register); \
        if (temp == -1) \
                disable (hc); \
        else if (hc->flags & OHCI_QUIRK_AMD756) \
                while (temp & mask) \
-                       temp = readl (&hc->regs->roothub.register); \
+                       temp = ohci_readl (&hc->regs->roothub.register); \
        temp; })
 
 static u32 roothub_a (struct ohci_hcd *hc)
        { return read_roothub (hc, a, 0xfc0fe000); }
 static inline u32 roothub_b (struct ohci_hcd *hc)
-       { return readl (&hc->regs->roothub.b); }
+       { return ohci_readl (&hc->regs->roothub.b); }
 static inline u32 roothub_status (struct ohci_hcd *hc)
-       { return readl (&hc->regs->roothub.status); }
+       { return ohci_readl (&hc->regs->roothub.status); }
 static u32 roothub_portstatus (struct ohci_hcd *hc, int i)
        { return read_roothub (hc, portstatus [i], 0xffe0fce0); }
 
@@ -83,14 +83,14 @@ static int ohci_hub_suspend (struct usb_hcd *hcd)
 
        spin_lock_irq (&ohci->lock);
 
-       ohci->hc_control = readl (&ohci->regs->control);
+       ohci->hc_control = ohci_readl (&ohci->regs->control);
        switch (ohci->hc_control & OHCI_CTRL_HCFS) {
        case OHCI_USB_RESUME:
                ohci_dbg (ohci, "resume/suspend?\n");
                ohci->hc_control &= ~OHCI_CTRL_HCFS;
                ohci->hc_control |= OHCI_USB_RESET;
                writel (ohci->hc_control, &ohci->regs->control);
-               (void) readl (&ohci->regs->control);
+               (void) ohci_readl (&ohci->regs->control);
                /* FALL THROUGH */
        case OHCI_USB_RESET:
                status = -EBUSY;
@@ -109,7 +109,7 @@ static int ohci_hub_suspend (struct usb_hcd *hcd)
 
                ohci->hc_control &= ~OHCI_SCHED_ENABLES;
                writel (ohci->hc_control, &ohci->regs->control);
-               ohci->hc_control = readl (&ohci->regs->control);
+               ohci->hc_control = ohci_readl (&ohci->regs->control);
                writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
 
                /* sched disables take effect on the next frame,
@@ -120,7 +120,7 @@ static int ohci_hub_suspend (struct usb_hcd *hcd)
                while (limit > 0) {
                        udelay (250);
                        limit =- 250;
-                       if (readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
+                       if (ohci_readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
                                break;
                }
                dl_done_list (ohci, 0);
@@ -128,7 +128,7 @@ static int ohci_hub_suspend (struct usb_hcd *hcd)
        }
        dl_done_list (ohci, 0);
        finish_unlinks (ohci, OHCI_FRAME_NO(ohci->hcca), 0);
-       writel (readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus);
+       writel (ohci_readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus);
 
        /* maybe resume can wake root hub */
        if (ohci->hcd.remote_wakeup)
@@ -140,7 +140,7 @@ static int ohci_hub_suspend (struct usb_hcd *hcd)
        ohci->hc_control &= ~OHCI_CTRL_HCFS;
        ohci->hc_control |= OHCI_USB_SUSPEND;
        writel (ohci->hc_control, &ohci->regs->control);
-       (void) readl (&ohci->regs->control);
+       (void) ohci_readl (&ohci->regs->control);
 
        /* no resumes until devices finish suspending */
        ohci->next_statechange = jiffies + msecs_to_jiffies (5);
@@ -179,13 +179,13 @@ static int ohci_hub_resume (struct usb_hcd *hcd)
                return -EAGAIN;
 
        spin_lock_irq (&ohci->lock);
-       ohci->hc_control = readl (&ohci->regs->control);
+       ohci->hc_control = ohci_readl (&ohci->regs->control);
        switch (ohci->hc_control & OHCI_CTRL_HCFS) {
        case OHCI_USB_SUSPEND:
                ohci->hc_control &= ~(OHCI_CTRL_HCFS|OHCI_SCHED_ENABLES);
                ohci->hc_control |= OHCI_USB_RESUME;
                writel (ohci->hc_control, &ohci->regs->control);
-               (void) readl (&ohci->regs->control);
+               (void) ohci_readl (&ohci->regs->control);
                ohci_dbg (ohci, "resume root hub\n");
                break;
        case OHCI_USB_RESUME:
@@ -210,7 +210,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd)
        temp = roothub_a (ohci) & RH_A_NDP;
        enables = 0;
        while (temp--) {
-               u32 stat = readl (&ohci->regs->roothub.portstatus [temp]);
+               u32 stat = ohci_readl (&ohci->regs->roothub.portstatus [temp]);
 
                /* force global, not selective, resume */
                if (!(stat & RH_PS_PSS))
@@ -222,7 +222,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd)
        ohci->hcd.state = USB_STATE_RESUMING;
        mdelay (20 /* usb 11.5.1.10 */ + 15);
 
-       temp = readl (&ohci->regs->control);
+       temp = ohci_readl (&ohci->regs->control);
        temp &= OHCI_CTRL_HCFS;
        if (temp != OHCI_USB_RESUME) {
                ohci_err (ohci, "controller won't resume\n");
@@ -243,11 +243,11 @@ static int ohci_hub_resume (struct usb_hcd *hcd)
        writel (OHCI_INTR_INIT, &ohci->regs->intrenable);
        if (ohci->ed_rm_list)
                writel (OHCI_INTR_SF, &ohci->regs->intrenable);
-       writel (readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus);
+       writel (ohci_readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus);
 
        /* Then re-enable operations */
        writel (OHCI_USB_OPER, &ohci->regs->control);
-       (void) readl (&ohci->regs->control);
+       (void) ohci_readl (&ohci->regs->control);
        msleep (3);
 
        temp = OHCI_CONTROL_INIT | OHCI_USB_OPER;
@@ -255,7 +255,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd)
                temp |= OHCI_CTRL_RWC;
        ohci->hc_control = temp;
        writel (temp, &ohci->regs->control);
-       (void) readl (&ohci->regs->control);
+       (void) ohci_readl (&ohci->regs->control);
 
        /* TRSMRCY */
        msleep (10);
@@ -290,7 +290,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd)
                writel (ohci->hc_control, &ohci->regs->control);
                if (temp)
                        writel (status, &ohci->regs->cmdstatus);
-               (void) readl (&ohci->regs->control);
+               (void) ohci_readl (&ohci->regs->control);
        }
 
        ohci->hcd.state = USB_STATE_RUNNING;
@@ -332,7 +332,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
                if (!HCD_IS_RUNNING(ohci->hcd.state))
                        return -ESHUTDOWN;
                ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n",
-                       ports, readl (&ohci->regs->roothub.a) & RH_A_NDP);
+                       ports, ohci_readl (&ohci->regs->roothub.a) & RH_A_NDP);
                /* retry later; "should not happen" */
                return 0;
        }
@@ -496,7 +496,7 @@ static int ohci_hub_control (
                        goto error;
                }
                writel (temp, &ohci->regs->roothub.portstatus [wIndex]);
-               // readl (&ohci->regs->roothub.portstatus [wIndex]);
+               // ohci_readl (&ohci->regs->roothub.portstatus [wIndex]);
                break;
        case GetHubDescriptor:
                ohci_hub_descriptor (ohci, (struct usb_hub_descriptor *) buf);
@@ -541,7 +541,7 @@ static int ohci_hub_control (
                                &ohci->regs->roothub.portstatus [wIndex]);
                        break;
                case USB_PORT_FEAT_RESET:
-                       temp = readl (&ohci->regs->roothub.portstatus [wIndex]);
+                       temp = ohci_readl (&ohci->regs->roothub.portstatus [wIndex]);
                        if (temp & RH_PS_CCS)
                                writel (RH_PS_PRS,
                                    &ohci->regs->roothub.portstatus [wIndex]);
index eba974d..b82c939 100644 (file)
@@ -454,7 +454,6 @@ int usb_hcd_omap_probe (const struct hc_driver *driver,
  */
 void usb_hcd_omap_remove (struct usb_hcd *hcd, struct omap_dev *dev)
 {
-       struct usb_device       *hub;
        void *base;
 
        info ("remove: %s, state %x", hcd->self.bus_name, hcd->state);
@@ -462,11 +461,10 @@ void usb_hcd_omap_remove (struct usb_hcd *hcd, struct omap_dev *dev)
        if (in_interrupt ())
                BUG ();
 
-       hub = hcd->self.root_hub;
        hcd->state = USB_STATE_QUIESCING;
 
        dbg ("%s: roothub graceful disconnect", hcd->self.bus_name);
-       usb_disconnect (&hub);
+       usb_disconnect (&hcd->self.root_hub);
 
        hcd->driver->stop (hcd);
        hcd_buffer_destroy (hcd);
index f103b15..7674141 100644 (file)
@@ -321,7 +321,7 @@ static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed)
                        if (!ed->hwNextED) {
                                ohci->hc_control &= ~OHCI_CTRL_CLE;
                                writel (ohci->hc_control, &ohci->regs->control);
-                               // a readl() later syncs CLE with the HC
+                               // a ohci_readl() later syncs CLE with the HC
                        } else
                                writel (le32_to_cpup (&ed->hwNextED),
                                        &ohci->regs->ed_controlhead);
@@ -345,7 +345,7 @@ static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed)
                        if (!ed->hwNextED) {
                                ohci->hc_control &= ~OHCI_CTRL_BLE;
                                writel (ohci->hc_control, &ohci->regs->control);
-                               // a readl() later syncs BLE with the HC
+                               // a ohci_readl() later syncs BLE with the HC
                        } else
                                writel (le32_to_cpup (&ed->hwNextED),
                                        &ohci->regs->ed_bulkhead);
@@ -481,7 +481,7 @@ static void start_ed_unlink (struct ohci_hcd *ohci, struct ed *ed)
        writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
        writel (OHCI_INTR_SF, &ohci->regs->intrenable);
        // flush those writes, and get latest HCCA contents
-       (void) readl (&ohci->regs->control);
+       (void) ohci_readl (&ohci->regs->control);
 
        /* SF interrupt might get delayed; record the frame counter value that
         * indicates when the HC isn't looking at it, so concurrent unlinks
index 5b599cb..34cce49 100644 (file)
@@ -237,7 +237,6 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver,
  */
 void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev)
 {
-       struct usb_device       *hub;
        void *base;
 
        info ("remove: %s, state %x", hcd->self.bus_name, hcd->state);
@@ -245,11 +244,10 @@ void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev)
        if (in_interrupt ())
                BUG ();
 
-       hub = hcd->self.root_hub;
        hcd->state = USB_STATE_QUIESCING;
 
        dbg ("%s: roothub graceful disconnect", hcd->self.bus_name);
-       usb_disconnect (&hub);
+       usb_disconnect (&hcd->self.root_hub);
 
        hcd->driver->stop (hcd);
        hcd->state = USB_STATE_HALT;
index 70f32ef..5f03844 100644 (file)
@@ -429,3 +429,22 @@ static inline void periodic_reinit (struct ohci_hcd *ohci)
 #      define ohci_vdbg(ohci, fmt, args...) do { } while (0)
 #endif
 
+#ifdef CONFIG_ARCH_LH7A404
+       /* Marc Singer: at the time this code was written, the LH7A404
+        * had a problem reading the USB host registers.  This
+        * implementation of the ohci_readl function performs the read
+        * twice as a work-around.
+        */
+static inline unsigned int ohci_readl (void* regs)
+{
+       *(volatile unsigned int*) regs;
+       return *(volatile unsigned int*) regs;
+}
+#else
+       /* Standard version of ohci_readl uses standard, platform
+        * specific implementation. */
+static inline unsigned int ohci_readl (void* regs)
+{
+       return readl (regs);
+}
+#endif
index afe0320..92d1c28 100644 (file)
@@ -103,8 +103,8 @@ static void uhci_free_pending_tds(struct uhci_hcd *uhci);
 static void hc_state_transitions(struct uhci_hcd *uhci);
 
 /* If a transfer is still active after this much time, turn off FSBR */
-#define IDLE_TIMEOUT   (HZ / 20)       /* 50 ms */
-#define FSBR_DELAY     (HZ / 20)       /* 50 ms */
+#define IDLE_TIMEOUT   msecs_to_jiffies(50)
+#define FSBR_DELAY     msecs_to_jiffies(50)
 
 /* When we timeout an idle transfer for FSBR, we'll switch it over to */
 /* depth first traversal. We'll do it in groups of this number of TD's */
@@ -1611,6 +1611,7 @@ static void stall_callback(unsigned long ptr)
        struct uhci_hcd *uhci = hcd_to_uhci(hcd);
        struct list_head list, *tmp, *head;
        unsigned long flags;
+       int called_uhci_finish_completion = 0;
 
        INIT_LIST_HEAD(&list);
 
@@ -1619,6 +1620,7 @@ static void stall_callback(unsigned long ptr)
            uhci_get_current_frame_number(uhci) != uhci->urb_remove_age) {
                uhci_remove_pending_urbps(uhci);
                uhci_finish_completion(hcd, NULL);
+               called_uhci_finish_completion = 1;
        }
 
        head = &uhci->urb_list;
@@ -1646,6 +1648,10 @@ static void stall_callback(unsigned long ptr)
        }
        spin_unlock_irqrestore(&uhci->schedule_lock, flags);
 
+       /* Wake up anyone waiting for an URB to complete */
+       if (called_uhci_finish_completion)
+               wake_up_all(&uhci->waitqh);
+
        head = &list;
        tmp = head->next;
        while (tmp != head) {
@@ -1676,7 +1682,7 @@ static int init_stall_timer(struct usb_hcd *hcd)
        init_timer(&uhci->stall_timer);
        uhci->stall_timer.function = stall_callback;
        uhci->stall_timer.data = (unsigned long)hcd;
-       uhci->stall_timer.expires = jiffies + (HZ / 10);
+       uhci->stall_timer.expires = jiffies + msecs_to_jiffies(100);
        add_timer(&uhci->stall_timer);
 
        return 0;
@@ -1831,16 +1837,20 @@ static void reset_hc(struct uhci_hcd *uhci)
 {
        unsigned int io_addr = uhci->io_addr;
 
+       /* Turn off PIRQ, SMI, and all interrupts.  This also turns off
+        * the BIOS's USB Legacy Support.
+        */
+       pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
+       outw(0, uhci->io_addr + USBINTR);
+
        /* Global reset for 50ms */
        uhci->state = UHCI_RESET;
        outw(USBCMD_GRESET, io_addr + USBCMD);
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout((HZ*50+999) / 1000);
+       msleep(50);
        outw(0, io_addr + USBCMD);
 
        /* Another 10ms delay */
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout((HZ*10+999) / 1000);
+       msleep(10);
        uhci->resume_detect = 0;
 }
 
@@ -1865,7 +1875,7 @@ static void wakeup_hc(struct uhci_hcd *uhci)
                        /* Global resume for >= 20ms */
                        outw(USBCMD_FGR | USBCMD_EGSM, io_addr + USBCMD);
                        uhci->state = UHCI_RESUMING_1;
-                       uhci->state_end = jiffies + (20*HZ+999) / 1000;
+                       uhci->state_end = jiffies + msecs_to_jiffies(20);
                        break;
 
                case UHCI_RESUMING_1:           /* End global resume */
@@ -1990,7 +2000,9 @@ static void start_hc(struct uhci_hcd *uhci)
                }
        }
 
-       /* Turn on all interrupts */
+       /* Turn on PIRQ and all interrupts */
+       pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
+                       USBLEGSUP_DEFAULT);
        outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
                io_addr + USBINTR);
 
@@ -2054,15 +2066,10 @@ static int uhci_reset(struct usb_hcd *hcd)
 
        uhci->io_addr = (unsigned long) hcd->regs;
 
-       /* Turn off all interrupts */
-       outw(0, uhci->io_addr + USBINTR);
-
-       /* Maybe kick BIOS off this hardware.  Then reset, so we won't get
+       /* Kick BIOS off this hardware and reset, so we won't get
         * interrupts from any previous setup.
         */
        reset_hc(uhci);
-       pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
-                       USBLEGSUP_DEFAULT);
        return 0;
 }
 
@@ -2178,7 +2185,7 @@ static int uhci_start(struct usb_hcd *hcd)
 
        uhci->rh_numports = port;
 
-       hcd->self.root_hub = udev = usb_alloc_dev(NULL, &hcd->self, 0);
+       udev = usb_alloc_dev(NULL, &hcd->self, 0);
        if (!udev) {
                dev_err(uhci_dev(uhci), "unable to allocate root hub\n");
                goto err_alloc_root_hub;
@@ -2260,7 +2267,7 @@ static int uhci_start(struct usb_hcd *hcd)
 
        udev->speed = USB_SPEED_FULL;
 
-       if (usb_register_root_hub(udev, uhci_dev(uhci)) != 0) {
+       if (hcd_register_root(udev, &uhci->hcd) != 0) {
                dev_err(uhci_dev(uhci), "unable to start root hub\n");
                retval = -ENOMEM;
                goto err_start_root_hub;
@@ -2288,7 +2295,6 @@ err_alloc_skelqh:
 
 err_alloc_term_td:
        usb_put_dev(udev);
-       hcd->self.root_hub = NULL;
 
 err_alloc_root_hub:
        dma_pool_destroy(uhci->qh_pool);
@@ -2369,14 +2375,18 @@ static int uhci_resume(struct usb_hcd *hcd)
                /*
                 * Some systems don't maintain the UHCI register values
                 * during a PM suspend/resume cycle, so reinitialize
-                * the Frame Number, the Framelist Base Address, and the
-                * Interrupt Enable registers.
+                * the Frame Number, Framelist Base Address, Interrupt
+                * Enable, and Legacy Support registers.
                 */
+               pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
+                               0);
                outw(uhci->saved_framenumber, uhci->io_addr + USBFRNUM);
                outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD);
                outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC |
                                USBINTR_SP, uhci->io_addr + USBINTR);
                uhci->resume_detect = 1;
+               pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
+                               USBLEGSUP_DEFAULT);
        } else {
                reset_hc(uhci);
                start_hc(uhci);
index bd69f10..dabc366 100644 (file)
@@ -11,7 +11,7 @@
 #include <asm/atomic.h>
 #include <linux/blkdev.h>
 #include "../../scsi/scsi.h"
-#include "../../scsi/hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "hpusbscsi.h"
 
index b05c168..d9461e3 100644 (file)
@@ -667,10 +667,10 @@ static int mdc800_device_release (struct inode* inode, struct file *file)
 /*
  * The Device read callback Function
  */
-static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, loff_t *pos)
+static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t len, loff_t *pos)
 {
        size_t left=len, sts=len; /* single transfer size */
-       char* ptr=buf;
+       char __user *ptr = buf;
        long timeout;
        DECLARE_WAITQUEUE(wait, current);
 
@@ -767,7 +767,7 @@ static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, lof
  * After this the driver initiates the request for the answer or
  * just waits until the camera becomes ready.
  */
-static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t len, loff_t *pos)
+static ssize_t mdc800_device_write (struct file *file, const char __user *buf, size_t len, loff_t *pos)
 {
        size_t i=0;
        DECLARE_WAITQUEUE(wait, current);
index 19acf62..94f6f27 100644 (file)
 #include <asm/atomic.h>
 #include <linux/blkdev.h>
 #include "../../scsi/scsi.h"
-#include "../../scsi/hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "microtek.h"
 
index 0f02822..dc2f8f0 100644 (file)
@@ -219,14 +219,16 @@ config USB_XPAD
          module will be called xpad.
          
 config USB_ATI_REMOTE
-       tristate "ATI USB RF remote control"
+       tristate "ATI / X10 USB RF remote control"
        depends on USB && INPUT
        ---help---
-         Say Y here if you want to use one of ATI's USB remote controls.
-         These are RF remotes with USB receivers. They come with many of ATI's 
-         All-In-Wonder video cards.  This driver provides mouse pointer, left
-          and right mouse buttons, and maps all the other remote buttons to
-         keypress events.
+         Say Y here if you want to use an ATI or X10 "Lola" USB remote control.
+         These are RF remotes with USB receivers. 
+         The ATI remote comes with many of ATI's All-In-Wonder video cards.
+         The X10 "Lola" remote is available at:
+            http://www.x10.com/products/lola_sg1.htm
+         This driver provides mouse pointer, left and right mouse buttons, 
+         and maps all the other remote buttons to keypress events.
          
          To compile this driver as a module, choose M here: the module will be
          called ati_remote.
index 0ac83aa..c1f1c1d 100644 (file)
  *
  *  Feb 2004: Torrey Hoffman <thoffman@arnor.net>
  *            Version 2.2.0
+ *  Jun 2004: Torrey Hoffman <thoffman@arnor.net>
+ *            Version 2.2.1
+ *            Added key repeat support contributed by:
+ *                Vincent Vanackere <vanackere@lif.univ-mrs.fr>
+ *            Added support for the "Lola" remote contributed by:
+ *                Seth Cohn <sethcohn@yahoo.com>
  *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
  *
  * "All-In-Wonder" video card packages.  The receiver self-identifies as a 
  * "USB Receiver" with manufacturer "X10 Wireless Technology Inc".
  *
+ * The "Lola" remote is available from X10.  See: 
+ *    http://www.x10.com/products/lola_sg1.htm
+ * The Lola is similar to the ATI remote but has no mouse support, and slightly
+ * different keys.
+ *
  * It is possible to use multiple receivers and remotes on multiple computers 
  * simultaneously by configuring them to use specific channels.
  * 
  
 #define ATI_REMOTE_VENDOR_ID   0x0bc7
 #define ATI_REMOTE_PRODUCT_ID  0x004
+#define LOLA_REMOTE_PRODUCT_ID         0x002
 
-#define DRIVER_VERSION                 "2.2.0"
+#define DRIVER_VERSION                 "2.2.1"
 #define DRIVER_AUTHOR           "Torrey Hoffman <thoffman@arnor.net>"
 #define DRIVER_DESC             "ATI/X10 RF USB Remote Control"
 
@@ -113,6 +125,7 @@ MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
  
 static struct usb_device_id ati_remote_table[] = {
        { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
+       { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) },
        {}      /* Terminating entry */
 };
 
@@ -134,10 +147,13 @@ static char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
 
 /* Duplicate event filtering time. 
  * Sequential, identical KIND_FILTERED inputs with less than
- * FILTER_TIME jiffies between them are dropped.  
- * (HZ >> 4) == 1/16th of a second and works well for me.
+ * FILTER_TIME jiffies between them are considered as repeat
+ * events. The hardware generates 5 events for the first keypress
+ * and we have to take this into account for an accurate repeat
+ * behaviour.
+ * (HZ / 20) == 50 ms and works well for me.
  */
-#define FILTER_TIME (HZ >> 4)
+#define FILTER_TIME (HZ / 20)
 
 static DECLARE_MUTEX(disconnect_sem);
 
@@ -161,6 +177,7 @@ struct ati_remote {
        unsigned char old_data[2];  /* Detect duplicate events */
        unsigned long old_jiffies;
        unsigned long acc_jiffies;  /* handle acceleration */
+       unsigned int repeat_count;
        
        char name[NAME_BUFSIZE];
        char phys[NAME_BUFSIZE];
@@ -256,6 +273,12 @@ static struct
        {KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_FORWARD, 1},    /* (>>) */
        {KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1},       /* ([]) */ 
        {KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_PAUSE, 1},      /* ('') */
+       {KIND_FILTERED, 0xf0, 0x2b, EV_KEY, KEY_PREVIOUS, 1},   /* (<-) */
+       {KIND_FILTERED, 0xef, 0x2a, EV_KEY, KEY_NEXT, 1},       /* (>+) */
+       {KIND_FILTERED, 0xf2, 0x2D, EV_KEY, KEY_INFO, 1},       /* PLAYING */
+       {KIND_FILTERED, 0xf3, 0x2E, EV_KEY, KEY_HOME, 1},       /* TOP */
+       {KIND_FILTERED, 0xf4, 0x2F, EV_KEY, KEY_END, 1},        /* END */
+       {KIND_FILTERED, 0xf5, 0x30, EV_KEY, KEY_SELECT, 1},     /* SELECT */    
        
        {KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0}
 };
@@ -483,9 +506,20 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
                if ((ati_remote->old_data[0] == data[1]) && 
                        (ati_remote->old_data[1] == data[2]) && 
                        ((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) {
-                       ati_remote->old_jiffies = jiffies;                      
+                       ati_remote->repeat_count++;
+               } 
+               else {
+                       ati_remote->repeat_count = 0;
+               }
+               
+               ati_remote->old_data[0] = data[1];
+               ati_remote->old_data[1] = data[2];
+               ati_remote->old_jiffies = jiffies;
+
+               if ((ati_remote->repeat_count > 0)
+                   && (ati_remote->repeat_count < 5))
                        return;
-               }               
+               
 
                input_regs(dev, regs);
                input_event(dev, ati_remote_tbl[index].type,
@@ -494,9 +528,6 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
                        ati_remote_tbl[index].code, 0);
                input_sync(dev);
 
-               ati_remote->old_data[0] = data[1];
-               ati_remote->old_data[1] = data[2];
-               ati_remote->old_jiffies = jiffies;
                return;
        }                       
        
@@ -697,9 +728,9 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
 
        /* See if the offered device matches what we can accept */
        if ((udev->descriptor.idVendor != ATI_REMOTE_VENDOR_ID) ||
-           (udev->descriptor.idProduct != ATI_REMOTE_PRODUCT_ID)) {
+               ( (udev->descriptor.idProduct != ATI_REMOTE_PRODUCT_ID) &&
+                 (udev->descriptor.idProduct != LOLA_REMOTE_PRODUCT_ID) ))
                return -ENODEV;
-       }
 
        /* Allocate and clear an ati_remote struct */
        if (!(ati_remote = kmalloc(sizeof (struct ati_remote), GFP_KERNEL)))
@@ -856,4 +887,3 @@ module_exit(ati_remote_exit);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
-
index 663a6b7..ff0010d 100644 (file)
@@ -1324,12 +1324,14 @@ void hid_init_reports(struct hid_device *hid)
        }
 
        err = 0;
-       while ((ret = hid_wait_io(hid))) {
+       ret = hid_wait_io(hid);
+       while (ret) {
                err |= ret;
                if (test_bit(HID_CTRL_RUNNING, &hid->iofl))
                        usb_unlink_urb(hid->urbctrl);
                if (test_bit(HID_OUT_RUNNING, &hid->iofl))
                        usb_unlink_urb(hid->urbout);
+               ret = hid_wait_io(hid);
        }
 
        if (err)
index c995d93..159a0d2 100644 (file)
@@ -295,7 +295,7 @@ static int hiddev_open(struct inode * inode, struct file * file) {
 /*
  * "write" file op
  */
-static ssize_t hiddev_write(struct file * file, const char * buffer, size_t count, loff_t *ppos)
+static ssize_t hiddev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
 {
        return -EINVAL;
 }
@@ -303,7 +303,7 @@ static ssize_t hiddev_write(struct file * file, const char * buffer, size_t coun
 /*
  * "read" file op
  */
-static ssize_t hiddev_read(struct file * file, char * buffer, size_t count, loff_t *ppos)
+static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
 {
        DECLARE_WAITQUEUE(wait, current);
        struct hiddev_list *list = file->private_data;
@@ -406,6 +406,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
        struct hiddev_devinfo dinfo;
        struct hid_report *report;
        struct hid_field *field;
+       void __user *user_arg = (void __user *)arg;
        int i;
 
        if (!hiddev->exist)
@@ -414,7 +415,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
        switch (cmd) {
 
        case HIDIOCGVERSION:
-               return put_user(HID_VERSION, (int *) arg);
+               return put_user(HID_VERSION, (int __user *)arg);
 
        case HIDIOCAPPLICATION:
                if (arg < 0 || arg >= hid->maxapplication)
@@ -439,13 +440,13 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                dinfo.product = dev->descriptor.idProduct;
                dinfo.version = dev->descriptor.bcdDevice;
                dinfo.num_applications = hid->maxapplication;
-               if (copy_to_user((void *) arg, &dinfo, sizeof(dinfo)))
+               if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
                        return -EFAULT;
 
                return 0;
 
        case HIDIOCGFLAG:
-               if (put_user(list->flags, (int *) arg))
+               if (put_user(list->flags, (int __user *)arg))
                        return -EFAULT;
 
                return 0;
@@ -453,7 +454,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
        case HIDIOCSFLAG:
                {
                        int newflags;
-                       if (get_user(newflags, (int *) arg))
+                       if (get_user(newflags, (int __user *)arg))
                                return -EFAULT;
 
                        if ((newflags & ~HIDDEV_FLAGS) != 0 ||
@@ -471,7 +472,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        int idx, len;
                        char *buf;
 
-                       if (get_user(idx, (int *) arg))
+                       if (get_user(idx, (int __user *)arg))
                                return -EFAULT;
 
                        if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
@@ -482,7 +483,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                                return -EINVAL;
                        }
 
-                       if (copy_to_user((void *) (arg+sizeof(int)), buf, len+1)) {
+                       if (copy_to_user(user_arg+sizeof(int), buf, len+1)) {
                                kfree(buf);
                                return -EFAULT;
                        }
@@ -498,7 +499,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
        case HIDIOCGREPORT:
-               if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
+               if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
                        return -EFAULT;
 
                if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
@@ -513,7 +514,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
        case HIDIOCSREPORT:
-               if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
+               if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
                        return -EFAULT;
 
                if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
@@ -527,7 +528,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
        case HIDIOCGREPORTINFO:
-               if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
+               if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
                        return -EFAULT;
 
                if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
@@ -535,13 +536,13 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 
                rinfo.num_fields = report->maxfield;
 
-               if (copy_to_user((void *) arg, &rinfo, sizeof(rinfo)))
+               if (copy_to_user(user_arg, &rinfo, sizeof(rinfo)))
                        return -EFAULT;
 
                return 0;
 
        case HIDIOCGFIELDINFO:
-               if (copy_from_user(&finfo, (void *) arg, sizeof(finfo)))
+               if (copy_from_user(&finfo, user_arg, sizeof(finfo)))
                        return -EFAULT;
                rinfo.report_type = finfo.report_type;
                rinfo.report_id = finfo.report_id;
@@ -568,7 +569,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                finfo.unit_exponent = field->unit_exponent;
                finfo.unit = field->unit;
 
-               if (copy_to_user((void *) arg, &finfo, sizeof(finfo)))
+               if (copy_to_user(user_arg, &finfo, sizeof(finfo)))
                        return -EFAULT;
 
                return 0;
@@ -578,7 +579,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                if (!uref_multi)
                        return -ENOMEM;
                uref = &uref_multi->uref;
-               if (copy_from_user(uref, (void *) arg, sizeof(*uref))) 
+               if (copy_from_user(uref, user_arg, sizeof(*uref))) 
                        goto fault;
 
                rinfo.report_type = uref->report_type;
@@ -595,7 +596,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 
                uref->usage_code = field->usage[uref->usage_index].hid;
 
-               if (copy_to_user((void *) arg, uref, sizeof(*uref)))
+               if (copy_to_user(user_arg, uref, sizeof(*uref)))
                        goto fault;
 
                kfree(uref_multi);
@@ -611,11 +612,11 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        return -ENOMEM;
                uref = &uref_multi->uref;
                if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
-                       if (copy_from_user(uref_multi, (void *) arg, 
+                       if (copy_from_user(uref_multi, user_arg, 
                                           sizeof(*uref_multi)))
                                goto fault;
                } else {
-                       if (copy_from_user(uref, (void *) arg, sizeof(*uref)))
+                       if (copy_from_user(uref, user_arg, sizeof(*uref)))
                                goto fault;
                }
 
@@ -652,7 +653,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                switch (cmd) {
                        case HIDIOCGUSAGE:
                                uref->value = field->value[uref->usage_index];
-                               if (copy_to_user((void *) arg, uref, sizeof(*uref)))
+                               if (copy_to_user(user_arg, uref, sizeof(*uref)))
                                        goto fault;
                                goto goodreturn;
 
@@ -667,7 +668,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                                for (i = 0; i < uref_multi->num_values; i++)
                                        uref_multi->values[i] = 
                                            field->value[uref->usage_index + i];
-                               if (copy_to_user((void *) arg, uref_multi, 
+                               if (copy_to_user(user_arg, uref_multi, 
                                                 sizeof(*uref_multi)))
                                        goto fault;
                                goto goodreturn;
@@ -689,7 +690,7 @@ inval:
                return -EINVAL;
 
        case HIDIOCGCOLLECTIONINFO:
-               if (copy_from_user(&cinfo, (void *) arg, sizeof(cinfo)))
+               if (copy_from_user(&cinfo, user_arg, sizeof(cinfo)))
                        return -EFAULT;
 
                if (cinfo.index >= hid->maxcollection)
@@ -699,7 +700,7 @@ inval:
                cinfo.usage = hid->collection[cinfo.index].usage;
                cinfo.level = hid->collection[cinfo.index].level;
 
-               if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+               if (copy_to_user(user_arg, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -715,7 +716,7 @@ inval:
                        len = strlen(hid->name) + 1;
                        if (len > _IOC_SIZE(cmd))
                                 len = _IOC_SIZE(cmd);
-                       return copy_to_user((char *) arg, hid->name, len) ?
+                       return copy_to_user(user_arg, hid->name, len) ?
                                -EFAULT : len;
                }
 
@@ -726,7 +727,7 @@ inval:
                        len = strlen(hid->phys) + 1;
                        if (len > _IOC_SIZE(cmd))
                                len = _IOC_SIZE(cmd);
-                       return copy_to_user((char *) arg, hid->phys, len) ?
+                       return copy_to_user(user_arg, hid->phys, len) ?
                                -EFAULT : len;
                }
        }
index eba7ef3..03947be 100644 (file)
@@ -108,7 +108,7 @@ config USB_OV511
 
 config USB_PWC
        tristate "USB Philips Cameras"
-       depends on USB && VIDEO_DEV && BROKEN
+       depends on USB && VIDEO_DEV && CONFIG_BROKEN
        ---help---
          Say Y or M here if you want to use one of these Philips & OEM
           webcams:
index 4510ace..2c021bf 100644 (file)
@@ -476,7 +476,7 @@ static int dabusb_startrek (pdabusb_t s)
        return 0;
 }
 
-static ssize_t dabusb_read (struct file *file, char *buf, size_t count, loff_t * ppos)
+static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, loff_t * ppos)
 {
        pdabusb_t s = (pdabusb_t) file->private_data;
        unsigned long flags;
@@ -670,7 +670,7 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
                        break;
                }
 
-               if (copy_from_user (pbulk, (void *) arg, sizeof (bulk_transfer_t))) {
+               if (copy_from_user (pbulk, (void __user *) arg, sizeof (bulk_transfer_t))) {
                        ret = -EFAULT;
                        kfree (pbulk);
                        break;
@@ -678,18 +678,18 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
 
                ret=dabusb_bulk (s, pbulk);
                if(ret==0)
-                       if (copy_to_user((void *)arg, pbulk,
+                       if (copy_to_user((void __user *)arg, pbulk,
                                         sizeof(bulk_transfer_t)))
                                ret = -EFAULT;
                kfree (pbulk);
                break;
 
        case IOCTL_DAB_OVERRUNS:
-               ret = put_user (s->overruns, (unsigned int *) arg);
+               ret = put_user (s->overruns, (unsigned int __user *) arg);
                break;
 
        case IOCTL_DAB_VERSION:
-               ret = put_user (version, (unsigned int *) arg);
+               ret = put_user (version, (unsigned int __user *) arg);
                break;
 
        default:
index c9cef99..e1007b0 100644 (file)
@@ -4593,7 +4593,7 @@ ov51x_v4l1_ioctl(struct inode *inode, struct file *file,
 }
 
 static ssize_t
-ov51x_v4l1_read(struct file *file, char *buf, size_t cnt, loff_t *ppos)
+ov51x_v4l1_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos)
 {
        struct video_device *vdev = file->private_data;
        int noblock = file->f_flags&O_NONBLOCK;
index fafd7ec..086509a 100644 (file)
@@ -11,7 +11,7 @@
 #ifdef OV511_DEBUG
        #define PDEBUG(level, fmt, args...) \
                if (debug >= (level)) info("[%s:%d] " fmt, \
-               __PRETTY_FUNCTION__, __LINE__ , ## args)
+               __FUNCTION__, __LINE__ , ## args)
 #else
        #define PDEBUG(level, fmt, args...) do {} while(0)
 #endif
index 4d503a2..4807974 100644 (file)
@@ -129,8 +129,7 @@ static struct {
 
 static int pwc_video_open(struct inode *inode, struct file *file);
 static int pwc_video_close(struct inode *inode, struct file *file);
-static int pwc_video_release(struct video_device *);                     
-static ssize_t pwc_video_read(struct file *file, char *buf,
+static ssize_t pwc_video_read(struct file *file, char __user *buf,
                          size_t count, loff_t *ppos);
 static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
 static int  pwc_video_ioctl(struct inode *inode, struct file *file,
@@ -1121,12 +1120,6 @@ static int pwc_video_close(struct inode *inode, struct file *file)
        return 0;
 }
 
-static int pwc_video_release(struct video_device *vfd)
-{
-       Trace(TRACE_OPEN, "pwc_video_release() called. Now what?\n");
-}
-               
-
 /*
  *     FIXME: what about two parallel reads ????
  *      ANSWER: Not supported. You can't open the device more than once,
@@ -1139,7 +1132,7 @@ static int pwc_video_release(struct video_device *vfd)
                 device is tricky anyhow.
  */
 
-static ssize_t pwc_video_read(struct file *file, char *buf,
+static ssize_t pwc_video_read(struct file *file, char __user *buf,
                          size_t count, loff_t *ppos)
 {
        struct video_device *vdev = file->private_data;
@@ -1855,7 +1848,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
                }
        }
 
-       pdev->vdev.release = pwc_video_release;
+       pdev->vdev.release = video_device_release;
        i = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr);
        if (i < 0) {
                Err("Failed to register as video device (%d).\n", i);
index ac19cfb..cea90d9 100644 (file)
@@ -1121,7 +1121,7 @@ static int se401_ioctl(struct inode *inode, struct file *file,
        return video_usercopy(inode, file, cmd, arg, se401_do_ioctl);
 }
 
-static ssize_t se401_read(struct file *file, char *buf,
+static ssize_t se401_read(struct file *file, char __user *buf,
                     size_t count, loff_t *ppos)
 {
        int realcount=count, ret=0;
index 10feeb7..af46029 100644 (file)
@@ -1309,7 +1309,7 @@ static int stv680_mmap (struct file *file, struct vm_area_struct *vma)
        return 0;
 }
 
-static ssize_t stv680_read (struct file *file, char *buf,
+static ssize_t stv680_read (struct file *file, char __user *buf,
                        size_t count, loff_t *ppos)
 {
        struct video_device *dev = file->private_data;
index 178a7b8..d46b136 100644 (file)
@@ -46,7 +46,7 @@ static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file,
                              unsigned int cmd, unsigned long arg);
 static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma);
 static int usbvideo_v4l_open(struct inode *inode, struct file *file);
-static ssize_t usbvideo_v4l_read(struct file *file, char *buf,
+static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
                             size_t count, loff_t *ppos);
 static int usbvideo_v4l_close(struct inode *inode, struct file *file);
 
@@ -1587,7 +1587,7 @@ static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file,
  * 20-Oct-2000 Created.
  * 01-Nov-2000 Added mutex (uvd->lock).
  */
-static ssize_t usbvideo_v4l_read(struct file *file, char *buf,
+static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
                      size_t count, loff_t *ppos)
 {
        struct uvd *uvd = file->private_data;
index 79629c3..1e416c1 100644 (file)
@@ -523,9 +523,9 @@ set_camera_power(struct vicam_camera *cam, int state)
 }
 
 static int
-vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsigned long ul_arg)
+vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsigned long arg)
 {
-       void *arg = (void *)ul_arg;
+       void __user *user_arg = (void __user *)arg;
        struct vicam_camera *cam = file->private_data;
        int retval = 0;
 
@@ -549,7 +549,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign
                        b.minwidth = 320;       /* VIDEOSIZE_48_48 */
                        b.minheight = 240;
 
-                       if (copy_to_user(arg, &b, sizeof (b)))
+                       if (copy_to_user(user_arg, &b, sizeof(b)))
                                retval = -EFAULT;
 
                        break;
@@ -560,7 +560,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign
                        struct video_channel v;
 
                        DBG("VIDIOCGCHAN\n");
-                       if (copy_from_user(&v, arg, sizeof (v))) {
+                       if (copy_from_user(&v, user_arg, sizeof(v))) {
                                retval = -EFAULT;
                                break;
                        }
@@ -576,7 +576,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign
                        v.type = VIDEO_TYPE_CAMERA;
                        v.norm = 0;
 
-                       if (copy_to_user(arg, &v, sizeof (v)))
+                       if (copy_to_user(user_arg, &v, sizeof(v)))
                                retval = -EFAULT;
                        break;
                }
@@ -585,7 +585,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign
                {
                        int v;
 
-                       if (copy_from_user(&v, arg, sizeof (v)))
+                       if (copy_from_user(&v, user_arg, sizeof(v)))
                                retval = -EFAULT;
                        DBG("VIDIOCSCHAN %d\n", v);
 
@@ -604,8 +604,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign
                        vp.brightness = cam->gain << 8;
                        vp.depth = 24;
                        vp.palette = VIDEO_PALETTE_RGB24;
-                       if (copy_to_user
-                           (arg, &vp, sizeof (struct video_picture)))
+                       if (copy_to_user(user_arg, &vp, sizeof (struct video_picture)))
                                retval = -EFAULT;
                        break;
                }
@@ -614,7 +613,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign
                {
                        struct video_picture vp;
                        
-                       if (copy_from_user(&vp, arg, sizeof(vp))) {
+                       if (copy_from_user(&vp, user_arg, sizeof(vp))) {
                                retval = -EFAULT;
                                break;
                        }
@@ -646,8 +645,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign
 
                        DBG("VIDIOCGWIN\n");
 
-                       if (copy_to_user
-                           ((void *) arg, (void *) &vw, sizeof (vw)))
+                       if (copy_to_user(user_arg, (void *)&vw, sizeof(vw)))
                                retval = -EFAULT;
 
                        // I'm not sure what the deal with a capture window is, it is very poorly described
@@ -660,7 +658,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign
 
                        struct video_window vw;
 
-                       if (copy_from_user(&vw, arg, sizeof(vw))) {
+                       if (copy_from_user(&vw, user_arg, sizeof(vw))) {
                                retval = -EFAULT;
                                break;
                        }
@@ -687,8 +685,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign
                        for (i = 0; i < VICAM_FRAMES; i++)
                                vm.offsets[i] = VICAM_MAX_FRAME_SIZE * i;
 
-                       if (copy_to_user
-                           ((void *) arg, (void *) &vm, sizeof (vm)))
+                       if (copy_to_user(user_arg, (void *)&vm, sizeof(vm)))
                                retval = -EFAULT;
 
                        break;
@@ -699,8 +696,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign
                        struct video_mmap vm;
                        // int video_size;
 
-                       if (copy_from_user
-                           ((void *) &vm, (void *) arg, sizeof (vm))) {
+                       if (copy_from_user((void *)&vm, user_arg, sizeof(vm))) {
                                retval = -EFAULT;
                                break;
                        }
@@ -723,7 +719,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign
                {
                        int frame;
 
-                       if (copy_from_user((void *) &frame, arg, sizeof (int))) {
+                       if (copy_from_user((void *)&frame, user_arg, sizeof(int))) {
                                retval = -EFAULT;
                                break;
                        }
@@ -1003,7 +999,7 @@ read_frame(struct vicam_camera *cam, int framenum)
 }
 
 static ssize_t
-vicam_read( struct file *file, char *buf, size_t count, loff_t *ppos )
+vicam_read( struct file *file, char __user *buf, size_t count, loff_t *ppos )
 {
        struct vicam_camera *cam = file->private_data;
 
index eb257e5..fccd94e 100644 (file)
@@ -388,7 +388,7 @@ MODULE_PARM_DESC(specific_debug,
 static struct file_operations w9968cf_fops;
 static int w9968cf_open(struct inode*, struct file*);
 static int w9968cf_release(struct inode*, struct file*);
-static ssize_t w9968cf_read(struct file*, char*, size_t, loff_t*);
+static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*);
 static int w9968cf_mmap(struct file*, struct vm_area_struct*);
 static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long);
 static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int, void*);
@@ -444,8 +444,8 @@ static inline unsigned long w9968cf_get_max_bufsize(struct w9968cf_device*);
 /* High-level CMOS sensor control functions */
 static int w9968cf_sensor_set_control(struct w9968cf_device*,int cid,int val);
 static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val);
-static inline int w9968cf_sensor_cmd(struct w9968cf_device*, 
-                                     unsigned int cmd, void *arg);
+static int w9968cf_sensor_cmd(struct w9968cf_device*, 
+                              unsigned int cmd, void *arg);
 static int w9968cf_sensor_init(struct w9968cf_device*);
 static int w9968cf_sensor_update_settings(struct w9968cf_device*);
 static int w9968cf_sensor_get_picture(struct w9968cf_device*);
@@ -461,7 +461,7 @@ static int w9968cf_init_chip(struct w9968cf_device*);
 static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture);
 static int w9968cf_set_window(struct w9968cf_device*, struct video_window);
 static inline u16 w9968cf_valid_palette(u16 palette);
-static inline u16 w9968cf_valid_depth(u16 palette);
+static u16 w9968cf_valid_depth(u16 palette);
 static inline u8 w9968cf_need_decompression(u16 palette);
 static int w9968cf_postprocess_frame(struct w9968cf_device*, 
                                      struct w9968cf_frame_t*);
@@ -1959,7 +1959,7 @@ static inline u16 w9968cf_valid_palette(u16 palette)
   Return the depth corresponding to the given palette.
   Palette _must_ be supported !
   --------------------------------------------------------------------------*/
-static inline u16 w9968cf_valid_depth(u16 palette)
+static u16 w9968cf_valid_depth(u16 palette)
 {
        u8 i=0;
        while (w9968cf_formatlist[i].palette != palette)
@@ -2178,7 +2178,7 @@ w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val)
 }
 
 
-static inline int
+static int
 w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
 {
        struct i2c_client* c = cam->sensor_client;
@@ -2770,7 +2770,7 @@ static int w9968cf_release(struct inode* inode, struct file* filp)
 
 
 static ssize_t
-w9968cf_read(struct file* filp, char* buf, size_t count, loff_t* f_pos)
+w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
 {
        struct w9968cf_device* cam;
        struct w9968cf_frame_t* fr;
@@ -2915,7 +2915,8 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                   unsigned int cmd, void* arg)
 {
        struct w9968cf_device* cam;
-       static const char* v4l1_ioctls[] = {
+       void __user *user_arg = (void __user *)arg;
+       const char* v4l1_ioctls[] = {
                "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", 
                "GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF",
                "SFBUF", "KEY", "GFREQ", "SFREQ", "GAUDIO", "SAUDIO",
@@ -2923,8 +2924,6 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", "SMICROCODE", 
                "GVBIFMT", "SVBIFMT" 
        };
-       struct video_tuner tuner;
-       struct video_channel chan;
 
        #define V4L1_IOCTL(cmd) \
                ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \
@@ -2950,7 +2949,7 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                cap.maxheight = (cam->upscaling && w9968cf_vppmod_present)
                                ? W9968CF_MAX_HEIGHT : cam->maxheight;
 
-               if (copy_to_user(arg, &cap, sizeof(cap)))
+               if (copy_to_user(user_arg, &cap, sizeof(cap)))
                        return -EFAULT;
 
                DBG(5, "VIDIOCGCAP successfully called.")
@@ -2959,7 +2958,8 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
 
        case VIDIOCGCHAN: /* get video channel informations */
        {
-               if (copy_from_user(&chan, arg, sizeof(chan)))
+               struct video_channel chan;
+               if (copy_from_user(&chan, user_arg, sizeof(chan)))
                        return -EFAULT;
 
                if (chan.channel != 0)
@@ -2971,7 +2971,7 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                chan.type = VIDEO_TYPE_CAMERA;
                chan.norm = VIDEO_MODE_AUTO;
 
-               if (copy_to_user(arg, &chan, sizeof(chan)))
+               if (copy_to_user(user_arg, &chan, sizeof(chan)))
                        return -EFAULT;
 
                DBG(5, "VIDIOCGCHAN successfully called.")
@@ -2980,7 +2980,9 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
 
        case VIDIOCSCHAN: /* set active channel */
        {
-               if (copy_from_user(&chan, arg, sizeof(chan)))
+               struct video_channel chan;
+
+               if (copy_from_user(&chan, user_arg, sizeof(chan)))
                        return -EFAULT;
 
                if (chan.channel != 0)
@@ -2995,7 +2997,7 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                if (w9968cf_sensor_get_picture(cam))
                        return -EIO;
 
-               if (copy_to_user(arg, &cam->picture, sizeof(cam->picture)))
+               if (copy_to_user(user_arg, &cam->picture, sizeof(cam->picture)))
                        return -EFAULT;
 
                DBG(5, "VIDIOCGPICT successfully called.")
@@ -3007,7 +3009,7 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                struct video_picture pict;
                int err = 0;
 
-               if (copy_from_user(&pict, arg, sizeof(pict)))
+               if (copy_from_user(&pict, user_arg, sizeof(pict)))
                        return -EFAULT;
 
                if ( (cam->force_palette || !w9968cf_vppmod_present) 
@@ -3086,7 +3088,7 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                struct video_window win;
                int err = 0;
 
-               if (copy_from_user(&win, arg, sizeof(win)))
+               if (copy_from_user(&win, user_arg, sizeof(win)))
                        return -EFAULT;
 
                DBG(6, "VIDIOCSWIN called: clipcount=%d, flags=%d, "
@@ -3140,7 +3142,7 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
 
        case VIDIOCGWIN: /* get current window properties */
        {
-               if (copy_to_user(arg,&cam->window,sizeof(struct video_window)))
+               if (copy_to_user(user_arg, &cam->window, sizeof(struct video_window)))
                        return -EFAULT;
 
                DBG(5, "VIDIOCGWIN successfully called.")
@@ -3158,7 +3160,7 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                        mbuf.offsets[i] = (unsigned long)cam->frame[i].buffer -
                                          (unsigned long)cam->frame[0].buffer;
 
-               if (copy_to_user(arg, &mbuf, sizeof(mbuf)))
+               if (copy_to_user(user_arg, &mbuf, sizeof(mbuf)))
                        return -EFAULT;
 
                DBG(5, "VIDIOCGMBUF successfully called.")
@@ -3171,7 +3173,7 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                struct w9968cf_frame_t* fr;
                int err = 0;
 
-               if (copy_from_user(&mmap, arg, sizeof(mmap)))
+               if (copy_from_user(&mmap, user_arg, sizeof(mmap)))
                        return -EFAULT;
 
                DBG(6, "VIDIOCMCAPTURE called: frame #%d, format=%s, %dx%d",
@@ -3294,7 +3296,7 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                struct w9968cf_frame_t* fr;
                int err = 0;
 
-               if (copy_from_user(&f_num, arg, sizeof(f_num)))
+               if (copy_from_user(&f_num, user_arg, sizeof(f_num)))
                        return -EFAULT;
 
                if (f_num >= cam->nbuffers) {
@@ -3347,7 +3349,7 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                        .teletext = VIDEO_NO_UNIT,
                };
 
-               if (copy_to_user(arg, &unit, sizeof(unit)))
+               if (copy_to_user(user_arg, &unit, sizeof(unit)))
                        return -EFAULT;
 
                DBG(5, "VIDIOCGUNIT successfully called.")
@@ -3359,7 +3361,7 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
 
        case VIDIOCGFBUF:
        {
-               if (clear_user(arg, sizeof(struct video_buffer)))
+               if (clear_user(user_arg, sizeof(struct video_buffer)))
                        return -EFAULT;
 
                DBG(5, "VIDIOCGFBUF successfully called.")
@@ -3368,7 +3370,8 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
 
        case VIDIOCGTUNER:
        {
-               if (copy_from_user(&tuner, arg, sizeof(tuner)))
+               struct video_tuner tuner;
+               if (copy_from_user(&tuner, user_arg, sizeof(tuner)))
                        return -EFAULT;
 
                if (tuner.tuner != 0)
@@ -3381,7 +3384,7 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                tuner.mode = VIDEO_MODE_AUTO;
                tuner.signal = 0xffff;
 
-               if (copy_to_user(arg, &tuner, sizeof(tuner)))
+               if (copy_to_user(user_arg, &tuner, sizeof(tuner)))
                        return -EFAULT;
 
                DBG(5, "VIDIOCGTUNER successfully called.")
@@ -3390,7 +3393,8 @@ w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
 
        case VIDIOCSTUNER:
        {
-               if (copy_from_user(&tuner, arg, sizeof(tuner)))
+               struct video_tuner tuner;
+               if (copy_from_user(&tuner, user_arg, sizeof(tuner)))
                        return -EFAULT;
 
                if (tuner.tuner != 0)
index 3076d87..ca91401 100644 (file)
@@ -293,7 +293,7 @@ if ( ((specific_debug) && (debug == (level))) || \
                warn(fmt, ## args); \
        else if ((level) >= 5) \
                info("[%s:%d] " fmt, \
-                    __PRETTY_FUNCTION__, __LINE__ , ## args); \
+                    __FUNCTION__, __LINE__ , ## args); \
 } \
 }
 #else
index b137da9..e3c4226 100644 (file)
@@ -1452,6 +1452,8 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int
         audevinfo_t devinfo;
         pauerswald_t cp = NULL;
        unsigned int u;
+       unsigned int __user *user_arg = (unsigned int __user *)arg;
+
         dbg ("ioctl");
 
        /* get the mutexes */
@@ -1483,14 +1485,14 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int
                u   = ccp->auerdev
                   && (ccp->scontext.id != AUH_UNASSIGNED)
                   && !list_empty (&cp->bufctl.free_buff_list);
-               ret = put_user (u, (unsigned int *) arg);
+               ret = put_user (u, user_arg);
                break;
 
        /* return != 0 if connected to a service channel */
        case IOCTL_AU_CONNECT:
                dbg ("IOCTL_AU_CONNECT");
                u = (ccp->scontext.id != AUH_UNASSIGNED);
-               ret = put_user (u, (unsigned int *) arg);
+               ret = put_user (u, user_arg);
                break;
 
        /* return != 0 if Receive Data available */
@@ -1511,14 +1513,14 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int
                                u = 1;
                        }
                }
-               ret = put_user (u, (unsigned int *) arg);
+               ret = put_user (u, user_arg);
                break;
 
        /* return the max. buffer length for the device */
        case IOCTL_AU_BUFLEN:
                dbg ("IOCTL_AU_BUFLEN");
                u = cp->maxControlLength;
-               ret = put_user (u, (unsigned int *) arg);
+               ret = put_user (u, user_arg);
                break;
 
        /* requesting a service channel */
@@ -1527,7 +1529,7 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int
                 /* requesting a service means: release the previous one first */
                auerswald_removeservice (cp, &ccp->scontext);
                /* get the channel number */
-               ret = get_user (u, (unsigned int *) arg);
+               ret = get_user (u, user_arg);
                if (ret) {
                        break;
                }
@@ -1564,7 +1566,7 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int
         case IOCTL_AU_SLEN:
                dbg ("IOCTL_AU_SLEN");
                u = AUSI_DLEN;
-               ret = put_user (u, (unsigned int *) arg);
+               ret = put_user (u, user_arg);
                break;
 
        default:
index c44f65a..8e266eb 100644 (file)
@@ -236,8 +236,8 @@ struct lego_usb_tower {
 
 
 /* local function prototypes */
-static ssize_t tower_read      (struct file *file, char *buffer, size_t count, loff_t *ppos);
-static ssize_t tower_write     (struct file *file, const char *buffer, size_t count, loff_t *ppos);
+static ssize_t tower_read      (struct file *file, char __user *buffer, size_t count, loff_t *ppos);
+static ssize_t tower_write     (struct file *file, const char __user *buffer, size_t count, loff_t *ppos);
 static inline void tower_delete (struct lego_usb_tower *dev);
 static int tower_open          (struct inode *inode, struct file *file);
 static int tower_release       (struct inode *inode, struct file *file);
@@ -560,7 +560,7 @@ static loff_t tower_llseek (struct file *file, loff_t off, int whence)
 /**
  *     tower_read
  */
-static ssize_t tower_read (struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t tower_read (struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
        struct lego_usb_tower *dev;
        size_t bytes_to_read;
@@ -651,7 +651,7 @@ exit:
 /**
  *     tower_write
  */
-static ssize_t tower_write (struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t tower_write (struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
        struct lego_usb_tower *dev;
        size_t bytes_to_write;
index 9018774..b89b534 100644 (file)
  *
  * CAUTION: Generally you should use 0 < degrees < 180 as anything else
  * is probably beyond the range of your servo and may damage it.
+ *
+ * Jun 16, 2004: Sean Young <sean@mess.org>
+ *  - cleanups
+ *  - was using memory after kfree()
  */
 
 #include <linux/config.h>
 #define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
 #define DRIVER_DESC "USB PhidgetServo Driver"
 
-#define VENDOR_ID_GLAB                 0x06c2
-#define DEVICE_ID_4MOTOR_SERVO_30      0x0038
-#define DEVICE_ID_1MOTOR_SERVO_30      0x0039
+#define VENDOR_ID_GLAB                         0x06c2
+#define DEVICE_ID_GLAB_PHIDGETSERVO_QUAD       0x0038
+#define DEVICE_ID_GLAB_PHIDGETSERVO_UNI                0x0039
+
+#define VENDOR_ID_WISEGROUP                    0x0925
+#define VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD  0x8101
+#define VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI   0x8104
 
-#define VENDOR_ID_WISEGROUP            0x0925
-#define DEVICE_ID_1MOTOR_SERVO_20      0x8101
-#define DEVICE_ID_4MOTOR_SERVO_20      0x8104
+#define SERVO_VERSION_30                       0x01
+#define SERVO_COUNT_QUAD                       0x02
 
 static struct usb_device_id id_table[] = {
-       {USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_4MOTOR_SERVO_30)},
-       {USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_1MOTOR_SERVO_30)},
-       {USB_DEVICE(VENDOR_ID_WISEGROUP, DEVICE_ID_4MOTOR_SERVO_20)},
-       {USB_DEVICE(VENDOR_ID_WISEGROUP, DEVICE_ID_1MOTOR_SERVO_20)},
+       {
+               USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_QUAD), 
+               .driver_info = SERVO_VERSION_30 | SERVO_COUNT_QUAD 
+       },
+       {
+               USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_UNI),
+               .driver_info = SERVO_VERSION_30 
+       },
+       {
+               USB_DEVICE(VENDOR_ID_WISEGROUP, 
+                               VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD),
+               .driver_info = SERVO_COUNT_QUAD 
+       },
+       {
+               USB_DEVICE(VENDOR_ID_WISEGROUP, 
+                               VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI),
+               .driver_info = 0
+       },
        {}
 };
 
@@ -53,14 +74,13 @@ MODULE_DEVICE_TABLE(usb, id_table);
 
 struct phidget_servo {
        struct usb_device *udev;
-       int version;
-       int quad_servo;
+       ulong type;
        int pulse[4];
        int degrees[4];
        int minutes[4];
 };
 
-static void
+static int
 change_position_v30(struct phidget_servo *servo, int servo_no, int degrees, 
                                                                int minutes)
 {
@@ -71,7 +91,7 @@ change_position_v30(struct phidget_servo *servo, int servo_no, int degrees,
        if (!buffer) {
                dev_err(&servo->udev->dev, "%s - out of memory\n",
                        __FUNCTION__);
-               return;
+               return -ENOMEM;
        }
 
        /*
@@ -124,12 +144,13 @@ change_position_v30(struct phidget_servo *servo, int servo_no, int degrees,
        retval = usb_control_msg(servo->udev,
                                 usb_sndctrlpipe(servo->udev, 0),
                                 0x09, 0x21, 0x0200, 0x0000, buffer, 6, 2 * HZ);
-       if (retval != 6)
-               dev_err(&servo->udev->dev, "retval = %d\n", retval);
+
        kfree(buffer);
+
+       return retval;
 }
 
-static void
+static int
 change_position_v20(struct phidget_servo *servo, int servo_no, int degrees,
                                                                int minutes)
 {
@@ -140,7 +161,7 @@ change_position_v20(struct phidget_servo *servo, int servo_no, int degrees,
        if (!buffer) {
                dev_err(&servo->udev->dev, "%s - out of memory\n",
                        __FUNCTION__);
-               return;
+               return -ENOMEM;
        }
 
        /*
@@ -171,16 +192,17 @@ change_position_v20(struct phidget_servo *servo, int servo_no, int degrees,
        retval = usb_control_msg(servo->udev,
                                 usb_sndctrlpipe(servo->udev, 0),
                                 0x09, 0x21, 0x0200, 0x0000, buffer, 2, 2 * HZ);
-       if (retval != 2)
-               dev_err(&servo->udev->dev, "retval = %d\n", retval);
+
        kfree(buffer);
+
+       return retval;
 }
 
 #define show_set(value)        \
 static ssize_t set_servo##value (struct device *dev,                   \
                                        const char *buf, size_t count)  \
 {                                                                      \
-       int degrees, minutes;                                           \
+       int degrees, minutes, retval;                                   \
        struct usb_interface *intf = to_usb_interface (dev);            \
        struct phidget_servo *servo = usb_get_intfdata (intf);          \
                                                                        \
@@ -195,12 +217,14 @@ static ssize_t set_servo##value (struct device *dev,                      \
                return -EINVAL;                                         \
        }                                                               \
                                                                        \
-       if (servo->version >= 3)                                        \
-               change_position_v30 (servo, value, degrees, minutes);   \
+       if (servo->type & SERVO_VERSION_30)                             \
+               retval = change_position_v30 (servo, value, degrees,    \
+                                                       minutes);       \
        else                                                            \
-               change_position_v20 (servo, value, degrees, minutes);   \
+               retval = change_position_v20 (servo, value, degrees,    \
+                                                       minutes);       \
                                                                        \
-       return count;                                                   \
+       return retval < 0 ? retval : count;                             \
 }                                                                      \
                                                                        \
 static ssize_t show_servo##value (struct device *dev, char *buf)       \
@@ -223,7 +247,7 @@ static int
 servo_probe(struct usb_interface *interface, const struct usb_device_id *id)
 {
        struct usb_device *udev = interface_to_usbdev(interface);
-       struct phidget_servo *dev = NULL;
+       struct phidget_servo *dev;
 
        dev = kmalloc(sizeof (struct phidget_servo), GFP_KERNEL);
        if (dev == NULL) {
@@ -233,37 +257,21 @@ servo_probe(struct usb_interface *interface, const struct usb_device_id *id)
        memset(dev, 0x00, sizeof (*dev));
 
        dev->udev = usb_get_dev(udev);
-       switch (udev->descriptor.idVendor) {
-       case VENDOR_ID_WISEGROUP:
-               dev->version = 2;
-               break;
-       case VENDOR_ID_GLAB:
-               dev->version = 3;
-               break;
-       }
-       switch (udev->descriptor.idProduct) {
-       case DEVICE_ID_4MOTOR_SERVO_20:
-       case DEVICE_ID_4MOTOR_SERVO_30:
-               dev->quad_servo = 1;
-               break;
-       case DEVICE_ID_1MOTOR_SERVO_20:
-       case DEVICE_ID_1MOTOR_SERVO_30:
-               dev->quad_servo = 0;
-               break;
-       }
-
+       dev->type = id->driver_info;
        usb_set_intfdata(interface, dev);
 
        device_create_file(&interface->dev, &dev_attr_servo0);
-       if (dev->quad_servo) {
+       if (dev->type & SERVO_COUNT_QUAD) {
                device_create_file(&interface->dev, &dev_attr_servo1);
                device_create_file(&interface->dev, &dev_attr_servo2);
                device_create_file(&interface->dev, &dev_attr_servo3);
        }
 
        dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 attached\n",
-                dev->quad_servo ? 4 : 1, dev->version);
-       if (dev->version == 2) 
+               dev->type & SERVO_COUNT_QUAD ? 4 : 1,
+               dev->type & SERVO_VERSION_30 ? 3 : 2);
+
+       if(!(dev->type & SERVO_VERSION_30))
                dev_info(&interface->dev,
                         "WARNING: v2.0 not tested! Please report if it works.\n");
 
@@ -279,7 +287,7 @@ servo_disconnect(struct usb_interface *interface)
        usb_set_intfdata(interface, NULL);
 
        device_remove_file(&interface->dev, &dev_attr_servo0);
-       if (dev->quad_servo) {
+       if (dev->type & SERVO_COUNT_QUAD) {
                device_remove_file(&interface->dev, &dev_attr_servo1);
                device_remove_file(&interface->dev, &dev_attr_servo2);
                device_remove_file(&interface->dev, &dev_attr_servo3);
@@ -287,10 +295,11 @@ servo_disconnect(struct usb_interface *interface)
 
        usb_put_dev(dev->udev);
 
-       kfree(dev);
-
        dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 detached\n",
-                dev->quad_servo ? 4 : 1, dev->version);
+               dev->type & SERVO_COUNT_QUAD ? 4 : 1,
+               dev->type & SERVO_VERSION_30 ? 3 : 2);
+
+       kfree(dev);
 }
 
 static struct usb_driver servo_driver = {
@@ -304,7 +313,7 @@ static struct usb_driver servo_driver = {
 static int __init
 phidget_servo_init(void)
 {
-       int retval = 0;
+       int retval;
 
        retval = usb_register(&servo_driver);
        if (retval)
index f9609d0..d6e1958 100644 (file)
@@ -269,7 +269,7 @@ struct udsl_instance_data {
 static void udsl_atm_dev_close (struct atm_dev *dev);
 static int udsl_atm_open (struct atm_vcc *vcc);
 static void udsl_atm_close (struct atm_vcc *vcc);
-static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg);
+static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void __user *arg);
 static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb);
 static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page);
 
@@ -991,11 +991,11 @@ static void udsl_atm_close (struct atm_vcc *vcc)
        dbg ("udsl_atm_close successful");
 }
 
-static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg)
+static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void __user *arg)
 {
        switch (cmd) {
        case ATM_QUERYLOOP:
-               return put_user (ATM_LM_NONE, (int *) arg) ? -EFAULT : 0;
+               return put_user (ATM_LM_NONE, (int __user *)arg) ? -EFAULT : 0;
        default:
                return -ENOIOCTLCMD;
        }
index 2fb1fae..404f397 100644 (file)
@@ -459,8 +459,8 @@ static int perform_sglist (
  * or remote wakeup (which needs human interaction).
  */
 
-static int realworld = 1;
-MODULE_PARM (realworld, "i");
+static unsigned realworld = 1;
+module_param (realworld, uint, 0);
 MODULE_PARM_DESC (realworld, "clear to demand stricter ch9 compliance");
 
 static int get_altsetting (struct usbtest_dev *dev)
@@ -1808,17 +1808,17 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
 
 /*-------------------------------------------------------------------------*/
 
-static int force_interrupt = 0;
-MODULE_PARM (force_interrupt, "i");
+static unsigned force_interrupt = 0;
+module_param (force_interrupt, uint, 0);
 MODULE_PARM_DESC (force_interrupt, "0 = test default; else interrupt");
 
 #ifdef GENERIC
-static int vendor;
-MODULE_PARM (vendor, "h");
+static unsigned short vendor;
+module_param(vendor, ushort, 0);
 MODULE_PARM_DESC (vendor, "vendor code (from usb-if)");
 
-static int product;
-MODULE_PARM (product, "h");
+static unsigned short product;
+module_param(product, ushort, 0);
 MODULE_PARM_DESC (product, "product code (from vendor)");
 #endif
 
index d705e81..de9bf86 100644 (file)
@@ -672,7 +672,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
         struct catc *catc = dev->priv;
         u32 cmd;
         
-        if (get_user(cmd, (u32 *)useraddr))
+        if (get_user(cmd, (u32 __user *)useraddr))
                 return -EFAULT;
 
         switch (cmd) {
@@ -726,7 +726,7 @@ static int catc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
         switch(cmd) {
         case SIOCETHTOOL:
-                return netdev_ethtool_ioctl(dev, (void __user *)rq->ifr_data);
+                return netdev_ethtool_ioctl(dev, rq->ifr_data);
         default:
                 return -EOPNOTSUPP;
         }
index d61d7d7..42a248f 100644 (file)
@@ -737,7 +737,7 @@ static int kaweth_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
 {
        switch (cmd) {
        case SIOCETHTOOL:
-               return netdev_ethtool_ioctl(net, (void __user *)rq->ifr_data);
+               return netdev_ethtool_ioctl(net, rq->ifr_data);
        }
        return -EOPNOTSUPP;
 }
index 9174825..5142d8a 100644 (file)
@@ -1030,7 +1030,7 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void __user *uaddr)
        int cmd;
 
        pegasus = net->priv;
-       if (get_user(cmd, (int *) uaddr))
+       if (get_user(cmd, (int __user *) uaddr))
                return -EFAULT;
        switch (cmd) {
        case ETHTOOL_GDRVINFO:{
@@ -1107,13 +1107,13 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void __user *uaddr)
 #endif
 static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
 {
-       __u16 *data = (__u16 *) & rq->ifr_data;
+       __u16 *data = (__u16 *) & rq->ifr_ifru;
        pegasus_t *pegasus = net->priv;
        int res;
 
        switch (cmd) {
        case SIOCETHTOOL:
-               res = pegasus_ethtool_ioctl(net, (void __user *)rq->ifr_data);
+               res = pegasus_ethtool_ioctl(net, rq->ifr_data);
                break;
        case SIOCDEVPRIVATE:
                data[0] = pegasus->phy;
index 411758b..7bc24d9 100644 (file)
@@ -121,6 +121,7 @@ struct usb_eth_dev {
 #define        VENDOR_ADMTEK           0x07a6
 #define        VENDOR_AEILAB           0x3334
 #define        VENDOR_ALLIEDTEL        0x07c9
+#define        VENDOR_ATEN             0x0557
 #define        VENDOR_BELKIN           0x050d
 #define        VENDOR_BILLIONTON       0x08dd
 #define        VENDOR_COMPAQ           0x049f
@@ -150,6 +151,8 @@ struct usb_eth_dev {
 
 PEGASUS_DEV( "3Com USB Ethernet 3C460B", VENDOR_3COM, 0x4601,
                DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "ATEN USB Ethernet UC-110T", VENDOR_ATEN, 0x2007,
+               DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x110c,
                DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
 PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4104,
index 52592ef..d9d09e9 100644 (file)
@@ -398,6 +398,21 @@ static void unlink_all_urbs(rtl8150_t * dev)
        usb_unlink_urb(dev->ctrl_urb);
 }
 
+static inline struct sk_buff *pull_skb(rtl8150_t *dev)
+{
+       struct sk_buff *skb;
+       int i;
+
+       for (i = 0; i < RX_SKB_POOL_SIZE; i++) {
+               if (dev->rx_skb_pool[i]) {
+                       skb = dev->rx_skb_pool[i];
+                       dev->rx_skb_pool[i] = NULL;
+                       return skb;
+               }
+       }
+       return NULL;
+}
+
 static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
 {
        rtl8150_t *dev;
@@ -603,21 +618,6 @@ static void free_skb_pool(rtl8150_t *dev)
                        dev_kfree_skb(dev->rx_skb_pool[i]);
 }
 
-static inline struct sk_buff *pull_skb(rtl8150_t *dev)
-{
-       struct sk_buff *skb;
-       int i;
-
-       for (i = 0; i < RX_SKB_POOL_SIZE; i++) {
-               if (dev->rx_skb_pool[i]) {
-                       skb = dev->rx_skb_pool[i];
-                       dev->rx_skb_pool[i] = NULL;
-                       return skb;
-               }
-       }
-       return NULL;
-}
-
 static int enable_net_traffic(rtl8150_t * dev)
 {
        u8 cr, tcr, rcr, msr;
@@ -776,13 +776,13 @@ static int rtl8150_close(struct net_device *netdev)
        return res;
 }
 
-static int rtl8150_ethtool_ioctl(struct net_device *netdev, void *uaddr)
+static int rtl8150_ethtool_ioctl(struct net_device *netdev, void __user *uaddr)
 {
        rtl8150_t *dev;
        int cmd;
 
        dev = netdev->priv;
-       if (get_user(cmd, (int *) uaddr))
+       if (get_user(cmd, (int __user *) uaddr))
                return -EFAULT;
 
        switch (cmd) {
@@ -856,7 +856,7 @@ static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
        int res;
 
        dev = netdev->priv;
-       data = (u16 *) & rq->ifr_data;
+       data = (u16 *) & rq->ifr_ifru;
        res = 0;
 
        switch (cmd) {
index e2e328f..db96e3b 100644 (file)
  *             disconnect; other cleanups. (db)  Flush net1080 fifos
  *             after several sequential framing errors. (Johannes Erdfelt)
  * 22-aug-2003 AX8817X support (Dave Hollis).
+ * 14-jun-2004  Trivial patch for AX8817X based Buffalo LUA-U2-KTX in Japan
+ *             (Neil Bortnak)
  *
  *-------------------------------------------------------------------------*/
 
@@ -1157,6 +1159,7 @@ static int cdc_bind (struct usbnet *dev, struct usb_interface *intf)
 
        status = get_ethernet_addr (dev, info->ether);
        if (status < 0) {
+               usb_set_intfdata(info->data, NULL);
                usb_driver_release_interface (&usbnet_driver, info->data);
                return status;
        }
@@ -2668,9 +2671,7 @@ static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
        struct usbnet *dev = (struct usbnet *)net->priv;
 
        if (dev->mii.mdio_read != NULL && dev->mii.mdio_write != NULL)
-               return generic_mii_ioctl(&dev->mii,
-                               (struct mii_ioctl_data *) &rq->ifr_data,
-                               cmd, NULL);
+               return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
        }
 #endif
        return -EOPNOTSUPP;
@@ -3206,6 +3207,10 @@ static const struct usb_device_id        products [] = {
        // ATEN UC210T
        USB_DEVICE (0x0557, 0x2009),
        .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // Buffalo LUA-U2-KTX
+       USB_DEVICE (0x0411, 0x003d),
+       .driver_info =  (unsigned long) &ax8817x_info,
 },
 #endif
 
index 003e101..991d37d 100644 (file)
@@ -78,8 +78,8 @@ static int usb_serial_device_probe (struct device *dev)
        minor = port->number;
        tty_register_device (usb_serial_tty_driver, minor, dev);
        dev_info(&port->serial->dev->dev, 
-                "%s converter now attached to ttyUSB%d (or usb/tts/%d for devfs)\n",
-                driver->name, minor, minor);
+                "%s converter now attached to ttyUSB%d\n",
+                driver->name, minor);
 
 exit:
        return retval;
index 299daca..9ca40ac 100644 (file)
@@ -109,7 +109,7 @@ struct cyberjack_private {
        short           rdtodo;         /* Bytes still to read */
        unsigned char   wrbuf[5*64];    /* Buffer for collecting data to write */
        short           wrfilled;       /* Overall data size we already got */
-       short           wrsent;         /* Data akready sent */
+       short           wrsent;         /* Data already sent */
 };
 
 /* do some startup allocations not currently performed by usb_serial_probe() */
@@ -159,8 +159,6 @@ static int  cyberjack_open (struct usb_serial_port *port, struct file *filp)
 
        dbg("%s - usb_clear_halt", __FUNCTION__ );
        usb_clear_halt(port->serial->dev, port->write_urb->pipe);
-       usb_clear_halt(port->serial->dev, port->read_urb->pipe);
-       usb_clear_halt(port->serial->dev, port->interrupt_in_urb->pipe);
 
        /* force low_latency on so that our tty_push actually forces
         * the data through, otherwise it is scheduled, and with high
@@ -212,7 +210,6 @@ static int cyberjack_write (struct usb_serial_port *port, int from_user, const u
        unsigned long flags;
        int result;
        int wrexpected;
-       unsigned char localbuf[CYBERJACK_LOCAL_BUF_SIZE];       /* Buffer for collecting data to write */
 
        dbg("%s - port %d", __FUNCTION__, port->number);
        dbg("%s - from_user %d", __FUNCTION__, from_user);
@@ -229,29 +226,23 @@ static int cyberjack_write (struct usb_serial_port *port, int from_user, const u
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ||
-               (count>sizeof(localbuf)) ) {
-               /* To much data  for buffer. Reset buffer. */
+       if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ) {
+               /* To much data for buffer. Reset buffer. */
                priv->wrfilled=0;
                spin_unlock_irqrestore(&priv->lock, flags);
                return (0);
        }
 
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        /* Copy data */
        if (from_user) {
-               if (copy_from_user(localbuf, buf, count)) {
+               if (copy_from_user(priv->wrbuf+priv->wrfilled, buf, count)) {
+                       spin_unlock_irqrestore(&priv->lock, flags);
                        return -EFAULT;
                }
        } else {
-               memcpy (localbuf, buf, count);
+               memcpy (priv->wrbuf+priv->wrfilled, buf, count);
        }  
 
-       spin_lock_irqsave(&priv->lock, flags);
-
-       memcpy (priv->wrbuf+priv->wrfilled, localbuf, count);
-
        usb_serial_debug_data (__FILE__, __FUNCTION__, count,
                priv->wrbuf+priv->wrfilled);
        priv->wrfilled += count;
index c15f3e5..43bc3dc 100644 (file)
@@ -1022,7 +1022,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
 }
 
 
-static int get_serial_info(struct usb_serial_port * port, struct serial_struct * retinfo)
+static int get_serial_info(struct usb_serial_port * port, struct serial_struct __user * retinfo)
 {
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        struct serial_struct tmp;
@@ -1039,7 +1039,7 @@ static int get_serial_info(struct usb_serial_port * port, struct serial_struct *
 } /* get_serial_info */
 
 
-static int set_serial_info(struct usb_serial_port * port, struct serial_struct * newinfo)
+static int set_serial_info(struct usb_serial_port * port, struct serial_struct __user * newinfo)
 { /* set_serial_info */
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        struct serial_struct new_serial;
@@ -1504,6 +1504,7 @@ static int ftdi_write (struct usb_serial_port *port, int from_user,
        if (status) {
                err("%s - failed submitting write urb, error %d", __FUNCTION__, status);
                count = status;
+               kfree (buffer);
        }
 
        /* we are done with this urb, so let the host driver
@@ -2042,7 +2043,7 @@ static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigne
 
        case TIOCMBIS: /* turns on (Sets) the lines as specified by the mask */
                dbg("%s TIOCMBIS", __FUNCTION__);
-               if (get_user(mask, (unsigned long *) arg))
+               if (get_user(mask, (unsigned long __user *) arg))
                        return -EFAULT;
                if (mask & TIOCM_DTR){
                        if ((ret = set_dtr(port, HIGH)) < 0) {
@@ -2061,7 +2062,7 @@ static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigne
 
        case TIOCMBIC: /* turns off (Clears) the lines as specified by the mask */
                dbg("%s TIOCMBIC", __FUNCTION__);
-               if (get_user(mask, (unsigned long *) arg))
+               if (get_user(mask, (unsigned long __user *) arg))
                        return -EFAULT;
                if (mask & TIOCM_DTR){
                        if ((ret = set_dtr(port, LOW)) < 0){
@@ -2088,10 +2089,10 @@ static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigne
                 */
 
        case TIOCGSERIAL: /* gets serial port data */
-               return get_serial_info(port, (struct serial_struct *) arg);
+               return get_serial_info(port, (struct serial_struct __user *) arg);
 
        case TIOCSSERIAL: /* sets serial port data */
-               return set_serial_info(port, (struct serial_struct *) arg);
+               return set_serial_info(port, (struct serial_struct __user *) arg);
 
        /*
         * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
index 5b2249b..2baac79 100644 (file)
@@ -1705,7 +1705,7 @@ static void edge_set_termios (struct usb_serial_port *port, struct termios *old_
  *         transmit holding register is empty.  This functionality
  *         allows an RS485 driver to be written in user space. 
  *****************************************************************************/
-static int get_lsr_info(struct edgeport_port *edge_port, unsigned int *value)
+static int get_lsr_info(struct edgeport_port *edge_port, unsigned int __user *value)
 {
        unsigned int result = 0;
 
@@ -1720,7 +1720,7 @@ static int get_lsr_info(struct edgeport_port *edge_port, unsigned int *value)
        return 0;
 }
 
-static int get_number_bytes_avail(struct edgeport_port *edge_port, unsigned int *value)
+static int get_number_bytes_avail(struct edgeport_port *edge_port, unsigned int __user *value)
 {
        unsigned int result = 0;
        struct tty_struct *tty = edge_port->port->tty;
@@ -1790,7 +1790,7 @@ static int edge_tiocmget(struct usb_serial_port *port, struct file *file)
        return result;
 }
 
-static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct retinfo)
+static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct __user *retinfo)
 {
        struct serial_struct tmp;
 
@@ -1812,7 +1812,6 @@ static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct
 //     tmp.hub6                = state->hub6;
 //     tmp.io_type             = state->io_type;
 
-
        if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
                return -EFAULT;
        return 0;
@@ -1838,17 +1837,17 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned
                // return number of bytes available
                case TIOCINQ:
                        dbg("%s (%d) TIOCINQ", __FUNCTION__,  port->number);
-                       return get_number_bytes_avail(edge_port, (unsigned int *) arg);
+                       return get_number_bytes_avail(edge_port, (unsigned int __user *) arg);
                        break;
 
                case TIOCSERGETLSR:
                        dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__,  port->number);
-                       return get_lsr_info(edge_port, (unsigned int *) arg);
+                       return get_lsr_info(edge_port, (unsigned int __user *) arg);
                        return 0;
 
                case TIOCGSERIAL:
                        dbg("%s (%d) TIOCGSERIAL", __FUNCTION__,  port->number);
-                       return get_serial_info(edge_port, (struct serial_struct *) arg);
+                       return get_serial_info(edge_port, (struct serial_struct __user *) arg);
 
                case TIOCSSERIAL:
                        dbg("%s (%d) TIOCSSERIAL", __FUNCTION__,  port->number);
@@ -1893,7 +1892,7 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned
                        icount.buf_overrun = cnow.buf_overrun;
 
                        dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__,  port->number, icount.rx, icount.tx );
-                       if (copy_to_user((void *)arg, &icount, sizeof(icount)))
+                       if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
                                return -EFAULT;
                        return 0;
        }
index 853cf17..793d40d 100644 (file)
@@ -2428,7 +2428,7 @@ static int edge_tiocmget(struct usb_serial_port *port, struct file *file)
        return result;
 }
 
-static int get_serial_info (struct edgeport_port *edge_port, struct serial_struct retinfo)
+static int get_serial_info (struct edgeport_port *edge_port, struct serial_struct __user *retinfo)
 {
        struct serial_struct tmp;
 
@@ -2477,7 +2477,7 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned
 
                case TIOCGSERIAL:
                        dbg("%s - (%d) TIOCGSERIAL", __FUNCTION__, port->number);
-                       return get_serial_info(edge_port, (struct serial_struct *) arg);
+                       return get_serial_info(edge_port, (struct serial_struct __user *) arg);
                        break;
 
                case TIOCSSERIAL:
@@ -2510,7 +2510,7 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned
                case TIOCGICOUNT:
                        dbg ("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__,
                             port->number, edge_port->icount.rx, edge_port->icount.tx);
-                       if (copy_to_user((void *)arg, &edge_port->icount, sizeof(edge_port->icount)))
+                       if (copy_to_user((void __user *)arg, &edge_port->icount, sizeof(edge_port->icount)))
                                return -EFAULT;
                        return 0;
        }
index c9b5af2..99fb540 100644 (file)
@@ -926,6 +926,7 @@ static int klsi_105_ioctl (struct usb_serial_port *port, struct file * file,
                           unsigned int cmd, unsigned long arg)
 {
        struct klsi_105_private *priv = usb_get_serial_port_data(port);
+       void __user *user_arg = (void __user *)arg;
        
        dbg("%scmd=0x%x", __FUNCTION__, cmd);
 
@@ -948,13 +949,12 @@ static int klsi_105_ioctl (struct usb_serial_port *port, struct file * file,
 
             dbg("%s - TCGETS data faked/incomplete", __FUNCTION__);
 
-            retval = verify_area(VERIFY_WRITE, (void *)arg,
+            retval = verify_area(VERIFY_WRITE, user_arg,
                                  sizeof(struct termios));
-
             if (retval)
-                        return(retval);
+                        return retval;
 
-            if (kernel_termios_to_user_termios((struct termios *)arg,  
+            if (kernel_termios_to_user_termios((struct termios __user *)arg,
                                                &priv->termios))
                     return -EFAULT;
             return(0);
@@ -965,14 +965,13 @@ static int klsi_105_ioctl (struct usb_serial_port *port, struct file * file,
 
                dbg("%s - TCSETS not handled", __FUNCTION__);
 
-               retval = verify_area(VERIFY_READ, (void *)arg,
+               retval = verify_area(VERIFY_READ, user_arg,
                                     sizeof(struct termios));
-
                if (retval)
-                           return(retval);
+                           return retval;
 
                if (user_termios_to_kernel_termios(&priv->termios,
-                                                 (struct termios *)arg))
+                                                 (struct termios __user *)arg))
                        return -EFAULT;
                klsi_105_set_termios(port, &priv->termios);
                return(0);
index 79cb22e..13c9515 100644 (file)
@@ -643,6 +643,7 @@ static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,
        unsigned char *transfer_buffer;
        int transfer_buffer_length = 8;
        char *settings;
+       void __user *user_arg = (void __user *)arg;
 
        priv = usb_get_serial_port_data(port);
        if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
@@ -652,12 +653,12 @@ static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,
 
        switch (cmd) {
        case TCGETS:   // 0x5401
-               result = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct termios));
+               result = verify_area(VERIFY_WRITE, user_arg, sizeof(struct termios));
                if (result) {
                        dbg("%s - port %d Error in verify_area", __FUNCTION__, port->number);
                        return(result);
                }
-               if (kernel_termios_to_user_termios((struct termios *)arg,
+               if (kernel_termios_to_user_termios((struct termios __user *)arg,
                                                   &priv->internal_termios))
                        return -EFAULT;
                return 0;
@@ -667,13 +668,13 @@ static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,
                        dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number);
                        return -ENOTTY;
                }
-               result = verify_area(VERIFY_READ, (void *)arg, sizeof(struct termios));
+               result = verify_area(VERIFY_READ, user_arg, sizeof(struct termios));
                if (result) {
                        dbg("%s - port %d Error in verify_area", __FUNCTION__, port->number);
                        return result;
                }
                if (user_termios_to_kernel_termios(&priv->internal_termios,
-                                                  (struct termios *)arg))
+                                                  (struct termios __user *)arg))
                        return -EFAULT;
                
                settings = (unsigned char *) kmalloc(50, GFP_KERNEL);  
index 377a184..29b64a4 100644 (file)
@@ -247,6 +247,8 @@ static struct usb_device_id id_table [] = {
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
+       { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID),
+               .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { },                                    /* optional parameter entry */
        { }                                     /* Terminating entry */
 };
@@ -290,6 +292,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID) },
        { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) },
        { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) },
+       { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) },
        { },                                    /* optional parameter entry */
        { }                                     /* Terminating entry */
 };
@@ -515,6 +518,7 @@ static int visor_write (struct usb_serial_port *port, int from_user, const unsig
                dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n",
                        __FUNCTION__, status);
                count = status;
+               kfree (buffer);
        } else {
                bytes_out += count;
        }
@@ -795,7 +799,7 @@ static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_i
                dev_err(dev, "%s - error %d getting connection info\n",
                        __FUNCTION__, retval);
        else
-               usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer);
+               usb_serial_debug_data (__FILE__, __FUNCTION__, retval, transfer_buffer);
 
        kfree (transfer_buffer);
        return 0;
@@ -881,18 +885,19 @@ static int treo_attach (struct usb_serial *serial)
 
        /* Only do this endpoint hack for the Handspring devices with
         * interrupt in endpoints, which for now are the Treo devices. */
-       if ((serial->dev->descriptor.idVendor != HANDSPRING_VENDOR_ID) ||
+       if (!((serial->dev->descriptor.idVendor == HANDSPRING_VENDOR_ID) ||
+             (serial->dev->descriptor.idVendor == KYOCERA_VENDOR_ID)) ||
            (serial->num_interrupt_in == 0))
                return 0;
 
        dbg("%s", __FUNCTION__);
 
        /*
-       * It appears that Treos want to use the 1st interrupt endpoint to
-       * communicate with the 2nd bulk out endpoint, so let's swap the 1st
-       * and 2nd bulk in and interrupt endpoints.  Note that swapping the
-       * bulk out endpoints would break lots of apps that want to communicate
-       * on the second port.
+       * It appears that Treos and Kyoceras want to use the 
+       * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint, 
+       * so let's swap the 1st and 2nd bulk in and interrupt endpoints.  
+       * Note that swapping the bulk out endpoints would break lots of 
+       * apps that want to communicate on the second port.
        */
 #define COPY_PORT(dest, src)                                           \
        dest->read_urb = src->read_urb;                                 \
index 6062273..55185b3 100644 (file)
@@ -55,6 +55,9 @@
 #define ACEECA_VENDOR_ID               0x4766
 #define ACEECA_MEZ1000_ID              0x0001
 
+#define KYOCERA_VENDOR_ID              0x0C88
+#define KYOCERA_7135_ID                        0x0021 
+
 /****************************************************************************
  * Handspring Visor Vendor specific request codes (bRequest values)
  * A big thank you to Handspring for providing the following information.
index e79afad..231c7b9 100644 (file)
@@ -835,6 +835,7 @@ static int whiteheat_tiocmset (struct usb_serial_port *port, struct file *file,
 static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
 {
        struct serial_struct serstruct;
+       void __user *user_arg = (void __user *)arg;
 
        dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
 
@@ -851,13 +852,13 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un
                        serstruct.close_delay = CLOSING_DELAY;
                        serstruct.closing_wait = CLOSING_DELAY;
 
-                       if (copy_to_user((void *)arg, &serstruct, sizeof(serstruct)))
+                       if (copy_to_user(user_arg, &serstruct, sizeof(serstruct)))
                                return -EFAULT;
 
                        break;
 
                case TIOCSSERIAL:
-                       if (copy_from_user(&serstruct, (void *)arg, sizeof(serstruct)))
+                       if (copy_from_user(&serstruct, user_arg, sizeof(serstruct)))
                                return -EFAULT;
 
                        /*
index 9e49d54..7e8d121 100644 (file)
@@ -23,6 +23,28 @@ config USB_STORAGE_DEBUG
          Say Y here in order to have the USB Mass Storage code generate
          verbose debugging messages.
 
+config USB_STORAGE_RW_DETECT
+       bool "USB Mass Storage Write-Protected Media Detection (EXPERIMENTAL)"
+       depends on USB_STORAGE && EXPERIMENTAL
+       help
+         Say Y here in order to have the USB Mass Storage code indicate to
+         the SCSI layer that using MODE SENSE(6) and MODE SENSE(10) to
+         determine if the media is write-protected is a good thing to do.
+
+         Many devices have historically had trouble with these commands,
+         hence the default 2.6.x behavior has been to suppress their use.
+         2.4.x used these commands with (at best) mixed results, often
+         crashing the firmware of the device.  However, the SCSI layer now
+         issues these commands in a manner more consistent with other
+         "popular" OSes, in an attempt to improve compatibility.
+
+         Saying Y here allows these commands to be sent to a USB device.
+         If you find a device this doesn't work for, switch to N and let
+         us know at usb-storage@lists.one-eyed-alien.net
+
+         If you say N here, the kernel will assume that all disk-like USB
+         devices are write-enabled.
+
 config USB_STORAGE_DATAFAB
        bool "Datafab Compact Flash Reader support (EXPERIMENTAL)"
        depends on USB_STORAGE && EXPERIMENTAL
index 39b24e5..ac9c908 100644 (file)
@@ -471,7 +471,7 @@ int jumpshot_transport(Scsi_Cmnd * srb, struct us_data *us)
 
                // build the reply
                //
-               ((u32 *) ptr)[0] = cpu_to_be32(info->sectors);
+               ((u32 *) ptr)[0] = cpu_to_be32(info->sectors - 1);
                ((u32 *) ptr)[1] = cpu_to_be32(info->ssize);
                usb_stor_set_xfer_buf(ptr, 8, srb);
 
index f903d39..43cb90d 100644 (file)
 #include "usb.h"
 #include "debug.h"
 #include "transport.h"
+#include "protocol.h"
 
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <scsi/scsi_devinfo.h>
 #include <scsi/scsi_host.h>
 
-
 /***********************************************************************
  * Host functions 
  ***********************************************************************/
@@ -68,10 +68,13 @@ static int slave_alloc (struct scsi_device *sdev)
 {
        /*
         * Set default bflags. These can be overridden for individual
-        * models and vendors via the scsi devinfo mechanism.
+        * models and vendors via the scsi devinfo mechanism.  The only
+        * flag we need is to force 36-byte INQUIRYs; we don't use any
+        * of the extra data and many devices choke if asked for more or
+        * less than 36 bytes.
         */
-       sdev->sdev_bflags = (BLIST_MS_SKIP_PAGE_08 | BLIST_MS_SKIP_PAGE_3F |
-                            BLIST_USE_10_BYTE_MS);
+       sdev->sdev_bflags = BLIST_INQUIRY_36;
+
        return 0;
 }
 
@@ -95,11 +98,48 @@ static int slave_configure(struct scsi_device *sdev)
         * reduce the maximum transfer size to 64 KB = 128 sectors. */
 
 #define USB_VENDOR_ID_GENESYS  0x05e3          // Needs a standard location
+
        if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS &&
-                       us->pusb_dev->speed == USB_SPEED_HIGH)
+                       us->pusb_dev->speed == USB_SPEED_HIGH &&
+                       sdev->request_queue->max_sectors > 128)
                blk_queue_max_sectors(sdev->request_queue, 128);
 
-       /* this is to satisify the compiler, tho I don't think the 
+       /* We can't put these settings in slave_alloc() because that gets
+        * called before the device type is known.  Consequently these
+        * settings can't be overridden via the scsi devinfo mechanism. */
+       if (sdev->type == TYPE_DISK) {
+
+               /* Disk-type devices use MODE SENSE(6) if the protocol
+                * (SubClass) is Transparent SCSI, otherwise they use
+                * MODE SENSE(10). */
+               if (us->subclass != US_SC_SCSI)
+                       sdev->use_10_for_ms = 1;
+
+               /* Many disks only accept MODE SENSE transfer lengths of
+                * 192 bytes (that's what Windows uses). */
+               sdev->use_192_bytes_for_3f = 1;
+
+               /* A number of devices have problems with MODE SENSE for
+                * page x08, so we will skip it. */
+               sdev->skip_ms_page_8 = 1;
+
+#ifndef CONFIG_USB_STORAGE_RW_DETECT
+               /* Some devices may not like MODE SENSE with page=0x3f.
+                * Now that we're using 192-byte transfers this may no
+                * longer be a problem.  So this will be a configuration
+                * option. */
+               sdev->skip_ms_page_3f = 1;
+#endif
+
+       } else {
+
+               /* Non-disk-type devices don't need to blacklist any pages
+                * or to force 192-byte transfer lengths for MODE SENSE.
+                * But they do need to use MODE SENSE(10). */
+               sdev->use_10_for_ms = 1;
+       }
+
+       /* this is to satisfy the compiler, tho I don't think the 
         * return code is ever checked anywhere. */
        return 0;
 }
@@ -409,6 +449,9 @@ struct scsi_host_template usb_stor_host_template = {
        /* emulated HBA */
        .emulated =                     TRUE,
 
+       /* we do our own delay after a device or bus reset */
+       .skip_settle_delay =            1,
+
        /* sysfs device attributes */
        .sdev_attrs =                   sysfs_device_attr_list,
 
index e42c59a..b24c4c7 100644 (file)
@@ -908,26 +908,29 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
                                 USB_RECIP_INTERFACE,
                                 0, us->ifnum, us->iobuf, 1, HZ);
 
+       US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", 
+                 result, us->iobuf[0]);
+
+       /* if we have a successful request, return the result */
+       if (result == 1)
+               return us->iobuf[0];
+
        /* 
         * Some devices (i.e. Iomega Zip100) need this -- apparently
         * the bulk pipes get STALLed when the GetMaxLUN request is
         * processed.   This is, in theory, harmless to all other devices
         * (regardless of if they stall or not).
         */
-       if (result < 0) {
+       if (result == -EPIPE) {
                usb_stor_clear_halt(us, us->recv_bulk_pipe);
                usb_stor_clear_halt(us, us->send_bulk_pipe);
+               /* return the default -- no LUNs */
+               return 0;
        }
 
-       US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", 
-                 result, us->iobuf[0]);
-
-       /* if we have a successful request, return the result */
-       if (result == 1)
-               return us->iobuf[0];
-
-       /* return the default -- no LUNs */
-       return 0;
+       /* An answer or a STALL are the only valid responses.  If we get
+        * something else, return an indication of error */
+       return -1;
 }
 
 int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
@@ -1110,10 +1113,11 @@ static int usb_stor_reset_common(struct us_data *us,
                goto Done;
        }
 
-       /* long wait for reset, so unlock to allow disconnects */
-       up(&us->dev_semaphore);
-       msleep(6000);
-       down(&us->dev_semaphore);
+       /* Give the device some time to recover from the reset,
+        * but don't delay disconnect processing. */
+       wait_event_interruptible_timeout(us->dev_reset_wait,
+                       test_bit(US_FLIDX_DISCONNECTING, &us->flags),
+                       HZ*6);
        if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
                US_DEBUGP("Reset interrupted by disconnect\n");
                goto Done;
index 56de0bd..ef13259 100644 (file)
@@ -207,7 +207,7 @@ UNUSUAL_DEV(  0x04e6, 0x0005, 0x0100, 0x0208,
 UNUSUAL_DEV(  0x04e6, 0x0006, 0x0100, 0x0205, 
                "Shuttle",
                "eUSB MMC Adapter",
-               US_SC_SCSI, US_PR_CB, NULL, 
+               US_SC_SCSI, US_PR_DEVICE, NULL, 
                US_FL_SINGLE_LUN), 
 
 UNUSUAL_DEV(  0x04e6, 0x0007, 0x0100, 0x0200, 
@@ -359,13 +359,19 @@ UNUSUAL_DEV(  0x057b, 0x0000, 0x0300, 0x9999,
 UNUSUAL_DEV(  0x0595, 0x4343, 0x0000, 0x2210,
                "Fujifilm",
                "Digital Camera EX-20 DSC",
-               US_SC_8070, US_PR_CBI, NULL, 0 ),
+               US_SC_8070, US_PR_DEVICE, NULL, 0 ),
 
 UNUSUAL_DEV(  0x059f, 0xa601, 0x0200, 0x0200, 
                "LaCie",
                "USB Hard Disk",
                US_SC_RBC, US_PR_CB, NULL, 0 ), 
 
+/* Submitted by Jol Bourquard <numlock@freesurf.ch> */
+UNUSUAL_DEV(  0x05ab, 0x0060, 0x1104, 0x1110,
+               "In-System",
+               "PyroGate External CD-ROM Enclosure (FCD-523)",
+               US_SC_SCSI, US_PR_BULK, NULL, 0 ),
+
 #ifdef CONFIG_USB_STORAGE_ISD200
 UNUSUAL_DEV(  0x05ab, 0x0031, 0x0100, 0x0110,
                "In-System",
@@ -396,8 +402,8 @@ UNUSUAL_DEV(  0x05ab, 0x5701, 0x0100, 0x0110,
 UNUSUAL_DEV(  0x05dc, 0x0001, 0x0000, 0x0001,
                "Lexar",
                "Jumpshot USB CF Reader",
-               US_SC_DEVICE, US_PR_JUMPSHOT, NULL,
-               US_FL_MODE_XLATE ),
+               US_SC_SCSI, US_PR_JUMPSHOT, NULL,
+               US_FL_NEED_OVERRIDE | US_FL_MODE_XLATE ),
 #endif
 
 /* Reported by Blake Matheny <bmatheny@purdue.edu> */
@@ -628,20 +634,14 @@ UNUSUAL_DEV(  0x07c4, 0xa400, 0x0000, 0xffff,
  * - Some cameras with idProduct=0x1001 and bcdDevice=0x1000 have
  *   bInterfaceProtocol=0x00 (US_PR_CBI) while others have 0x01 (US_PR_CB).
  *   So don't remove the US_PR_CB override!
+ * - Cameras with bcdDevice=0x9009 require the US_SC_8070 override.
  */
-UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009,
+UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999,
                "Casio",
                "QV DigitalCamera",
-               US_SC_DEVICE, US_PR_CB, NULL,
+               US_SC_8070, US_PR_CB, NULL,
                US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ),
 
-/* Later Casio cameras apparently tell the truth */
-UNUSUAL_DEV( 0x07cf, 0x1001, 0x9010, 0x9999,
-               "Casio",
-               "QV DigitalCamera",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_INQUIRY ),
-
 /* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/
 UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001,
                "Samsung",
index 6342822..c2ccdab 100644 (file)
@@ -266,6 +266,7 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data,
 static int usb_stor_control_thread(void * __us)
 {
        struct us_data *us = (struct us_data *)__us;
+       struct Scsi_Host *host = us->host;
 
        lock_kernel();
 
@@ -283,19 +284,21 @@ static int usb_stor_control_thread(void * __us)
        complete(&(us->notify));
 
        for(;;) {
-               struct Scsi_Host *host;
                US_DEBUGP("*** thread sleeping.\n");
                if(down_interruptible(&us->sema))
                        break;
                        
                US_DEBUGP("*** thread awakened.\n");
 
+               /* lock the device pointers */
+               down(&(us->dev_semaphore));
+
                /* if us->srb is NULL, we are being asked to exit */
                if (us->srb == NULL) {
                        US_DEBUGP("-- exit command received\n");
+                       up(&(us->dev_semaphore));
                        break;
                }
-               host = us->srb->device->host;
 
                /* lock access to the state */
                scsi_lock(host);
@@ -306,23 +309,20 @@ static int usb_stor_control_thread(void * __us)
                        goto SkipForAbort;
                }
 
-               /* set the state and release the lock */
-               us->sm_state = US_STATE_RUNNING;
-               scsi_unlock(host);
-
-               /* lock the device pointers */
-               down(&(us->dev_semaphore));
-
                /* don't do anything if we are disconnecting */
                if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
                        US_DEBUGP("No command during disconnect\n");
-                       us->srb->result = DID_BAD_TARGET << 16;
+                       goto SkipForDisconnect;
                }
 
+               /* set the state and release the lock */
+               us->sm_state = US_STATE_RUNNING;
+               scsi_unlock(host);
+
                /* reject the command if the direction indicator 
                 * is UNKNOWN
                 */
-               else if (us->srb->sc_data_direction == SCSI_DATA_UNKNOWN) {
+               if (us->srb->sc_data_direction == SCSI_DATA_UNKNOWN) {
                        US_DEBUGP("UNKNOWN data direction\n");
                        us->srb->result = DID_ERROR << 16;
                }
@@ -362,9 +362,6 @@ static int usb_stor_control_thread(void * __us)
                        us->proto_handler(us->srb, us);
                }
 
-               /* unlock the device pointers */
-               up(&(us->dev_semaphore));
-
                /* lock access to the state */
                scsi_lock(host);
 
@@ -374,7 +371,7 @@ static int usb_stor_control_thread(void * __us)
                                   us->srb->result);
                        us->srb->scsi_done(us->srb);
                } else {
-                       SkipForAbort:
+SkipForAbort:
                        US_DEBUGP("scsi command aborted\n");
                }
 
@@ -387,9 +384,13 @@ static int usb_stor_control_thread(void * __us)
                        complete(&(us->notify));
 
                /* empty the queue, reset the state, and release the lock */
+SkipForDisconnect:
                us->srb = NULL;
                us->sm_state = US_STATE_IDLE;
                scsi_unlock(host);
+
+               /* unlock the device pointers */
+               up(&(us->dev_semaphore));
        } /* for (;;) */
 
        /* notify the exit routine that we're actually exiting now 
@@ -423,10 +424,8 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf)
        us->pusb_intf = intf;
        us->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
 
-       /* Store our private data in the interface and increment the
-        * device's reference count */
+       /* Store our private data in the interface */
        usb_set_intfdata(intf, us);
-       usb_get_dev(us->pusb_dev);
 
        /* Allocate the device-related DMA-mapped buffers */
        us->cr = usb_buffer_alloc(us->pusb_dev, sizeof(*us->cr),
@@ -754,8 +753,14 @@ static int usb_stor_acquire_resources(struct us_data *us)
        down(&us->dev_semaphore);
 
        /* For bulk-only devices, determine the max LUN value */
-       if (us->protocol == US_PR_BULK)
-               us->max_lun = usb_stor_Bulk_max_lun(us);
+       if (us->protocol == US_PR_BULK) {
+               p = usb_stor_Bulk_max_lun(us);
+               if (p < 0) {
+                       up(&us->dev_semaphore);
+                       return p;
+               }
+               us->max_lun = p;
+       }
 
        /* Just before we start our control thread, initialize
         * the device if it needs initialization */
@@ -764,19 +769,6 @@ static int usb_stor_acquire_resources(struct us_data *us)
 
        up(&us->dev_semaphore);
 
-       /* Start up our control thread */
-       us->sm_state = US_STATE_IDLE;
-       p = kernel_thread(usb_stor_control_thread, us, CLONE_VM);
-       if (p < 0) {
-               printk(KERN_WARNING USB_STORAGE 
-                      "Unable to start control thread\n");
-               return p;
-       }
-       us->pid = p;
-
-       /* Wait for the thread to start */
-       wait_for_completion(&(us->notify));
-
        /*
         * Since this is a new device, we need to register a SCSI
         * host definition with the higher SCSI layers.
@@ -784,69 +776,61 @@ static int usb_stor_acquire_resources(struct us_data *us)
        us->host = scsi_host_alloc(&usb_stor_host_template, sizeof(us));
        if (!us->host) {
                printk(KERN_WARNING USB_STORAGE
-                       "Unable to register the scsi host\n");
+                       "Unable to allocate the scsi host\n");
                return -EBUSY;
        }
 
        /* Set the hostdata to prepare for scanning */
        us->host->hostdata[0] = (unsigned long) us;
 
-       return 0;
-}
-
-/* Dissociate from the USB device */
-static void dissociate_dev(struct us_data *us)
-{
-       US_DEBUGP("-- %s\n", __FUNCTION__);
-       down(&us->dev_semaphore);
-
-       /* Free the device-related DMA-mapped buffers */
-       if (us->cr) {
-               usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr,
-                               us->cr_dma);
-               us->cr = NULL;
-       }
-       if (us->iobuf) {
-               usb_buffer_free(us->pusb_dev, US_IOBUF_SIZE, us->iobuf,
-                               us->iobuf_dma);
-               us->iobuf = NULL;
+       /* Start up our control thread */
+       us->sm_state = US_STATE_IDLE;
+       p = kernel_thread(usb_stor_control_thread, us, CLONE_VM);
+       if (p < 0) {
+               printk(KERN_WARNING USB_STORAGE 
+                      "Unable to start control thread\n");
+               return p;
        }
+       us->pid = p;
 
-       /* Remove our private data from the interface and decrement the
-        * device's reference count */
-       usb_set_intfdata(us->pusb_intf, NULL);
-       usb_put_dev(us->pusb_dev);
+       /* Wait for the thread to start */
+       wait_for_completion(&(us->notify));
 
-       us->pusb_dev = NULL;
-       us->pusb_intf = NULL;
-       up(&us->dev_semaphore);
+       return 0;
 }
 
-/* Release all our static and dynamic resources */
+/* Release all our dynamic resources */
 void usb_stor_release_resources(struct us_data *us)
 {
-       /*
-        * The host must already have been removed
-        * and dissociate_dev() must have been called.
-        */
-
-       /* Finish the SCSI host removal sequence */
-       if (us->host) {
-               us->host->hostdata[0] = 0;
-               scsi_host_put(us->host);
-       }
+       US_DEBUGP("-- %s\n", __FUNCTION__);
 
-       /* Kill the control thread
-        *
-        * Enqueue the command, wake up the thread, and wait for 
-        * notification that it has exited.
+       /* Kill the control thread.  The SCSI host must already have been
+        * removed so it won't try to queue any more commands.
         */
        if (us->pid) {
+
+               /* Wait for the thread to be idle */
+               down(&us->dev_semaphore);
                US_DEBUGP("-- sending exit command to thread\n");
                BUG_ON(us->sm_state != US_STATE_IDLE);
+
+               /* If the SCSI midlayer queued a final command just before
+                * scsi_remove_host() was called, us->srb might not be
+                * NULL.  We can overwrite it safely, because the midlayer
+                * will not wait for the command to finish.  Also the
+                * control thread will already have been awakened.
+                * That's okay, an extra up() on us->sema won't hurt.
+                *
+                * Enqueue the command, wake up the thread, and wait for 
+                * notification that it has exited.
+                */
+               scsi_lock(us->host);
                us->srb = NULL;
-               up(&(us->sema));
-               wait_for_completion(&(us->notify));
+               scsi_unlock(us->host);
+               up(&us->dev_semaphore);
+
+               up(&us->sema);
+               wait_for_completion(&us->notify);
        }
 
        /* Call the destructor routine, if it exists */
@@ -855,15 +839,36 @@ void usb_stor_release_resources(struct us_data *us)
                us->extra_destructor(us->extra);
        }
 
+       /* Finish the host removal sequence */
+       if (us->host)
+               scsi_host_put(us->host);
+
        /* Free the extra data and the URB */
        if (us->extra)
                kfree(us->extra);
        if (us->current_urb)
                usb_free_urb(us->current_urb);
 
+}
+
+/* Dissociate from the USB device */
+static void dissociate_dev(struct us_data *us)
+{
+       US_DEBUGP("-- %s\n", __FUNCTION__);
+
+       /* Free the device-related DMA-mapped buffers */
+       if (us->cr)
+               usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr,
+                               us->cr_dma);
+       if (us->iobuf)
+               usb_buffer_free(us->pusb_dev, US_IOBUF_SIZE, us->iobuf,
+                               us->iobuf_dma);
+
+       /* Remove our private data from the interface */
+       usb_set_intfdata(us->pusb_intf, NULL);
+
        /* Free the structure itself */
        kfree(us);
-       US_DEBUGP("-- %s finished\n", __FUNCTION__);
 }
 
 /* Probe to see if we can drive a newly-connected USB device */
@@ -889,6 +894,7 @@ static int storage_probe(struct usb_interface *intf,
        init_MUTEX(&(us->dev_semaphore));
        init_MUTEX_LOCKED(&(us->sema));
        init_completion(&(us->notify));
+       init_waitqueue_head(&us->dev_reset_wait);
 
        /* Associate the us_data structure with the USB device */
        result = associate_dev(us, intf);
@@ -959,8 +965,8 @@ static int storage_probe(struct usb_interface *intf,
        /* We come here if there are any problems */
 BadDevice:
        US_DEBUGP("storage_probe() failed\n");
-       dissociate_dev(us);
        usb_stor_release_resources(us);
+       dissociate_dev(us);
        return result;
 }
 
@@ -971,20 +977,20 @@ static void storage_disconnect(struct usb_interface *intf)
 
        US_DEBUGP("storage_disconnect() called\n");
 
-       /* Prevent new USB transfers and stop the current command */
+       /* Prevent new USB transfers, stop the current command, and
+        * interrupt a device-reset delay */
        set_bit(US_FLIDX_DISCONNECTING, &us->flags);
        usb_stor_stop_transport(us);
+       wake_up(&us->dev_reset_wait);
 
-       /* Dissociate from the USB device */
-       dissociate_dev(us);
-
+       /* Wait for the current command to finish, then remove the host */
+       down(&us->dev_semaphore);
+       up(&us->dev_semaphore);
        scsi_remove_host(us->host);
 
-       /* TODO: somehow, wait for the device to
-        * be 'idle' (tasklet completion) */
-
-       /* Release all our other resources */
+       /* Wait for everything to become idle and release all our resources */
        usb_stor_release_resources(us);
+       dissociate_dev(us);
 }
 
 /***********************************************************************
@@ -1017,47 +1023,6 @@ static void __exit usb_stor_exit(void)
         */
        US_DEBUGP("-- calling usb_deregister()\n");
        usb_deregister(&usb_storage_driver) ;
-
-#if 0
-       /* While there are still virtual hosts, unregister them
-        * Note that it's important to do this completely before removing
-        * the structures because of possible races with the /proc
-        * interface
-        */
-       for (next = us_list; next; next = next->next) {
-               US_DEBUGP("-- calling scsi_unregister_host()\n");
-               scsi_unregister_host(&usb_stor_host_template);
-       }
-
-       /* While there are still structures, free them.  Note that we are
-        * now race-free, since these structures can no longer be accessed
-        * from either the SCSI command layer or the /proc interface
-        */
-       while (us_list) {
-               /* keep track of where the next one is */
-               next = us_list->next;
-
-               /* If there's extra data in the us_data structure then
-                * free that first */
-               if (us_list->extra) {
-                       /* call the destructor routine, if it exists */
-                       if (us_list->extra_destructor) {
-                               US_DEBUGP("-- calling extra_destructor()\n");
-                               us_list->extra_destructor(us_list->extra);
-                       }
-
-                       /* destroy the extra data */
-                       US_DEBUGP("-- freeing the data structure\n");
-                       kfree(us_list->extra);
-               }
-
-               /* free the structure itself */
-               kfree (us_list);
-
-               /* advance the list pointer */
-               us_list = next;
-       }
-#endif
 }
 
 module_init(usb_stor_init);
index 7ef571a..35d0144 100644 (file)
@@ -158,9 +158,10 @@ struct us_data {
        dma_addr_t              cr_dma;          /* buffer DMA addresses */
        dma_addr_t              iobuf_dma;
 
-       /* mutual exclusion structures */
+       /* mutual exclusion and synchronization structures */
        struct semaphore        sema;            /* to sleep thread on   */
-       struct completion       notify;          /* thread begin/end        */
+       struct completion       notify;          /* thread begin/end     */
+       wait_queue_head_t       dev_reset_wait;  /* wait during reset    */
 
        /* subdriver information */
        void                    *extra;          /* Any extra data          */
index 4d58fc5..7c551a2 100644 (file)
@@ -432,6 +432,11 @@ config FB_RIVA
          To compile this driver as a module, choose M here: the
          module will be called rivafb.
 
+config FB_RIVA_I2C
+       bool "Enable DDC Support"
+       depends on FB_RIVA && I2C
+       help
+
 config FB_I810
        tristate "Intel 810/815 support (EXPERIMENTAL)"
        depends on FB && AGP && AGP_INTEL && EXPERIMENTAL && PCI        
index 82614b4..a98130c 100644 (file)
@@ -38,8 +38,8 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
                return;
        }
 
-       vxres = info->var.xres;
-       vyres = info->var.yres;
+       vxres = info->var.xres_virtual;
+       vyres = info->var.yres_virtual;
 
        memcpy(&modded, region, sizeof(struct fb_fillrect));
 
@@ -104,8 +104,8 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
                return;
        }
 
-       vxres = info->var.xres;
-       vyres = info->var.yres;
+       vxres = info->var.xres_virtual;
+       vyres = info->var.yres_virtual;
 
        if(!modded.width || !modded.height ||
           modded.sx >= vxres || modded.sy >= vyres ||
index 7ec7756..c227e7a 100644 (file)
@@ -858,6 +858,7 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var,
         if (rinfo->asleep)
                return 0;
 
+       radeon_fifo_wait(2);
         OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
                             * var->bits_per_pixel / 8) & ~7);
         return 0;
@@ -882,11 +883,12 @@ static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int
                        if (!rinfo->is_mobility)
                                return -EINVAL;
 
-                       rc = get_user(value, (__u32*)arg);
+                       rc = get_user(value, (__u32 __user *)arg);
 
                        if (rc)
                                return rc;
 
+                       radeon_fifo_wait(2);
                        if (value & 0x01) {
                                tmp = INREG(LVDS_GEN_CNTL);
 
@@ -926,7 +928,7 @@ static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int
                        if (CRTC_CRT_ON & tmp)
                                value |= 0x02;
 
-                       return put_user(value, (__u32*)arg);
+                       return put_user(value, (__u32 __user *)arg);
                default:
                        return -EINVAL;
        }
@@ -963,6 +965,7 @@ static int radeon_screen_blank (struct radeonfb_info *rinfo, int blank)
                         break;
         }
 
+       radeon_fifo_wait(1);
        switch (rinfo->mon1_type) {
                case MT_LCD:
                        OUTREG(LVDS_GEN_CNTL, val2);
@@ -1021,6 +1024,7 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
         if (!rinfo->asleep) {
                u32 dac_cntl2, vclk_cntl = 0;
                
+               radeon_fifo_wait(9);
                if (rinfo->is_mobility) {
                        vclk_cntl = INPLL(VCLK_ECP_CNTL);
                        OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
@@ -1112,6 +1116,8 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
 {
        int i;
 
+       radeon_fifo_wait(20);
+
        /* Workaround from XFree */
        if (rinfo->is_mobility) {
                /* A temporal workaround for the occational blanking on certain laptop panels. 
@@ -1198,6 +1204,8 @@ static void radeon_lvds_timer_func(unsigned long data)
 {
        struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
 
+       radeon_fifo_wait(3);
+
        OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl);
        if (rinfo->pending_pixclks_cntl) {
                OUTPLL(PIXCLKS_CNTL, rinfo->pending_pixclks_cntl);
@@ -1222,6 +1230,7 @@ static void radeon_write_mode (struct radeonfb_info *rinfo,
 
        radeon_screen_blank(rinfo, VESA_POWERDOWN);
 
+       radeon_fifo_wait(31);
        for (i=0; i<10; i++)
                OUTREG(common_regs[i].reg, common_regs[i].val);
 
@@ -1249,6 +1258,7 @@ static void radeon_write_mode (struct radeonfb_info *rinfo,
        radeon_write_pll_regs(rinfo, mode);
 
        if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
+               radeon_fifo_wait(10);
                OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
                OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
                OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
@@ -1288,6 +1298,7 @@ static void radeon_write_mode (struct radeonfb_info *rinfo,
 
        radeon_screen_blank(rinfo, VESA_NO_BLANKING);
 
+       radeon_fifo_wait(2);
        OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
        
        return;
@@ -1701,7 +1712,7 @@ int radeonfb_set_par(struct fb_info *info)
 
 
 
-static ssize_t radeonfb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+static ssize_t radeonfb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
        unsigned long p = *ppos;
        struct inode *inode = file->f_dentry->d_inode;
@@ -1728,7 +1739,7 @@ static ssize_t radeonfb_read(struct file *file, char *buf, size_t count, loff_t
        return count;
 }
 
-static ssize_t radeonfb_write(struct file *file, const char *buf, size_t count,
+static ssize_t radeonfb_write(struct file *file, const char __user *buf, size_t count,
                              loff_t *ppos)
 {
        unsigned long p = *ppos;
@@ -1869,6 +1880,7 @@ static int radeon_set_backlight_enable(int on, int level, void *data)
        del_timer_sync(&rinfo->lvds_timer);
 
        lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);
+       radeon_fifo_wait(3);
        if (on && (level > BACKLIGHT_OFF)) {
                lvds_gen_cntl |= LVDS_DIGON;
                if (!(lvds_gen_cntl & LVDS_ON)) {
@@ -2141,6 +2153,7 @@ static int radeonfb_pci_register (struct pci_dev *pdev,
           u32 tom = INREG(NB_TOM);
           tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
  
+               radeon_fifo_wait(6);
           OUTREG(MC_FB_LOCATION, tom);
           OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
           OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
index d0f9920..e928f4e 100644 (file)
@@ -601,8 +601,9 @@ static void fbcon_init(struct vc_data *vc, int init)
        int display_fg = (*default_mode)->vc_num;
        int logo = 1, rows, cols, charcnt = 256;
        unsigned short *save = NULL, *r, *q;
+       int cap = info->flags;
 
-       if (vc->vc_num != display_fg || (info->flags & FBINFO_FLAG_MODULE) ||
+       if (vc->vc_num != display_fg || (info->flags & FBINFO_MODULE) ||
            (info->fix.type == FB_TYPE_TEXT))
                logo = 0;
 
@@ -635,10 +636,10 @@ static void fbcon_init(struct vc_data *vc, int init)
        rows = info->var.yres / vc->vc_font.height;
        vc_resize(vc->vc_num, cols, rows);
 
-       if (info->var.accel_flags)
-               p->scrollmode = SCROLL_YNOMOVE;
-       else
-               p->scrollmode = SCROLL_YREDRAW;
+       if ((cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED))
+               p->scrollmode = SCROLL_ACCEL;
+       else /* default to something safe */
+               p->scrollmode = SCROLL_REDRAW;
 
        /*
         *  ++guenther: console.c:vc_allocate() relies on initializing
@@ -1245,7 +1246,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
 {
        struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
        struct display *p = &fb_display[vc->vc_num];
-       int scroll_partial = !(p->scrollmode & __SCROLL_YNOPARTIAL);
+       int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
 
        if (!info->fbops->fb_blank && console_blanked)
                return 0;
@@ -1269,15 +1270,15 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
                        fbcon_softback_note(vc, t, count);
                if (logo_shown >= 0)
                        goto redraw_up;
-               switch (p->scrollmode & __SCROLL_YMASK) {
-               case __SCROLL_YMOVE:
+               switch (p->scrollmode) {
+               case SCROLL_ACCEL:
                        accel_bmove(vc, info, t + count, 0, t, 0,
                                         b - t - count, vc->vc_cols);
                        accel_clear(vc, info, b - count, 0, count,
                                         vc->vc_cols);
                        break;
 
-               case __SCROLL_YWRAP:
+               case SCROLL_WRAP:
                        if (b - t - count > 3 * vc->vc_rows >> 2) {
                                if (t > 0)
                                        fbcon_bmove(vc, 0, 0, count, 0, t,
@@ -1287,15 +1288,15 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
                                        fbcon_bmove(vc, b - count, 0, b, 0,
                                                    vc->vc_rows - b,
                                                    vc->vc_cols);
-                       } else if (p->scrollmode & __SCROLL_YPANREDRAW)
-                               goto redraw_up;
-                       else
+                       } else if (info->flags & FBINFO_READS_FAST)
                                fbcon_bmove(vc, t + count, 0, t, 0,
                                            b - t - count, vc->vc_cols);
+                       else
+                               goto redraw_up;
                        fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
                        break;
 
-               case __SCROLL_YPAN:
+               case SCROLL_PAN:
                        if ((p->yscroll + count <=
                             2 * (p->vrows - vc->vc_rows))
                            && ((!scroll_partial && (b - t == vc->vc_rows))
@@ -1310,15 +1311,15 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
                                        fbcon_bmove(vc, b - count, 0, b, 0,
                                                    vc->vc_rows - b,
                                                    vc->vc_cols);
-                       } else if (p->scrollmode & __SCROLL_YPANREDRAW)
-                               goto redraw_up;
-                       else
+                       } else if (info->flags & FBINFO_READS_FAST)
                                fbcon_bmove(vc, t + count, 0, t, 0,
                                            b - t - count, vc->vc_cols);
+                       else
+                               goto redraw_up;
                        fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
                        break;
 
-               case __SCROLL_YREDRAW:
+               case SCROLL_REDRAW:
                      redraw_up:
                        fbcon_redraw(vc, p, t, b - t - count,
                                     count * vc->vc_cols);
@@ -1336,14 +1337,14 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
        case SM_DOWN:
                if (count > vc->vc_rows)        /* Maximum realistic size */
                        count = vc->vc_rows;
-               switch (p->scrollmode & __SCROLL_YMASK) {
-               case __SCROLL_YMOVE:
+               switch (p->scrollmode) {
+               case SCROLL_ACCEL:
                        accel_bmove(vc, info, t, 0, t + count, 0,
                                         b - t - count, vc->vc_cols);
                        accel_clear(vc, info, t, 0, count, vc->vc_cols);
                        break;
 
-               case __SCROLL_YWRAP:
+               case SCROLL_WRAP:
                        if (b - t - count > 3 * vc->vc_rows >> 2) {
                                if (vc->vc_rows - b > 0)
                                        fbcon_bmove(vc, b, 0, b - count, 0,
@@ -1353,15 +1354,15 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
                                if (t > 0)
                                        fbcon_bmove(vc, count, 0, 0, 0, t,
                                                    vc->vc_cols);
-                       } else if (p->scrollmode & __SCROLL_YPANREDRAW)
-                               goto redraw_down;
-                       else
+                       } else if (info->flags & FBINFO_READS_FAST)
                                fbcon_bmove(vc, t, 0, t + count, 0,
                                            b - t - count, vc->vc_cols);
+                       else
+                               goto redraw_down;
                        fbcon_clear(vc, t, 0, count, vc->vc_cols);
                        break;
 
-               case __SCROLL_YPAN:
+               case SCROLL_PAN:
                        if ((count - p->yscroll <= p->vrows - vc->vc_rows)
                            && ((!scroll_partial && (b - t == vc->vc_rows))
                                || (scroll_partial
@@ -1375,15 +1376,15 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
                                if (t > 0)
                                        fbcon_bmove(vc, count, 0, 0, 0, t,
                                                    vc->vc_cols);
-                       } else if (p->scrollmode & __SCROLL_YPANREDRAW)
-                               goto redraw_down;
-                       else
+                       } else if (info->flags & FBINFO_READS_FAST)
                                fbcon_bmove(vc, t, 0, t + count, 0,
                                            b - t - count, vc->vc_cols);
+                       else
+                               goto redraw_down;
                        fbcon_clear(vc, t, 0, count, vc->vc_cols);
                        break;
 
-               case __SCROLL_YREDRAW:
+               case SCROLL_REDRAW:
                      redraw_down:
                        fbcon_redraw(vc, p, b - 1, b - t - count,
                                     -count * vc->vc_cols);
@@ -1467,21 +1468,27 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s
 
 static __inline__ void updatescrollmode(struct display *p, struct fb_info *info, struct vc_data *vc)
 {
-       int m;
-
-       if (p->scrollmode & __SCROLL_YFIXED)
-               return;
-       if (divides(info->fix.ywrapstep, vc->vc_font.height) &&
-           divides(vc->vc_font.height, info->var.yres_virtual))
-               m = __SCROLL_YWRAP;
-       else if (divides(info->fix.ypanstep, vc->vc_font.height) &&
-                info->var.yres_virtual >= info->var.yres + vc->vc_font.height)
-               m = __SCROLL_YPAN;
-       else if (p->scrollmode & __SCROLL_YNOMOVE)
-               m = __SCROLL_YREDRAW;
-       else
-               m = __SCROLL_YMOVE;
-       p->scrollmode = (p->scrollmode & ~__SCROLL_YMASK) | m;
+       int cap = info->flags;
+       int good_pan = (cap & FBINFO_HWACCEL_YPAN)
+                && divides(info->fix.ypanstep, vc->vc_font.height)
+                && info->var.yres_virtual >= 2*info->var.yres;
+       int good_wrap = (cap & FBINFO_HWACCEL_YWRAP)
+                && divides(info->fix.ywrapstep, vc->vc_font.height)
+                && divides(vc->vc_font.height, info->var.yres_virtual);
+       int reading_fast = cap & FBINFO_READS_FAST;
+       int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED);
+
+       if (good_wrap || good_pan) {
+               if (reading_fast || fast_copyarea)
+                       p->scrollmode = good_wrap ? SCROLL_WRAP : SCROLL_PAN;
+               else
+                       p->scrollmode = SCROLL_REDRAW;
+       } else {
+               if (reading_fast || fast_copyarea)
+                       p->scrollmode = SCROLL_ACCEL;
+               else
+                       p->scrollmode = SCROLL_REDRAW;
+       }
 }
 
 static int fbcon_resize(struct vc_data *vc, unsigned int width, 
@@ -1505,9 +1512,10 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
                if (!info->fbops->fb_set_par)
                        return -EINVAL;
 
-               sprintf(mode, "%dx%d", var.xres, var.yres);
-               err = fb_find_mode(&var, info, mode, NULL, 0, NULL,
-                                       info->var.bits_per_pixel);
+               snprintf(mode, 40, "%ix%i", var.xres, var.yres);
+               err = fb_find_mode(&var, info, mode, info->monspecs.modedb,
+                                  info->monspecs.modedb_len, NULL,
+                                  info->var.bits_per_pixel);
                if (!err || width > var.xres/fw || height > var.yres/fh)
                        return -EINVAL;
                DPRINTK("resize now %ix%i\n", var.xres, var.yres);
@@ -1555,12 +1563,12 @@ static int fbcon_switch(struct vc_data *vc)
        }
        if (info)
                info->var.yoffset = p->yscroll = 0;
-        fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
-       switch (p->scrollmode & __SCROLL_YMASK) {
-       case __SCROLL_YWRAP:
+       fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
+       switch (p->scrollmode) {
+       case SCROLL_WRAP:
                scrollback_phys_max = p->vrows - vc->vc_rows;
                break;
-       case __SCROLL_YPAN:
+       case SCROLL_PAN:
                scrollback_phys_max = p->vrows - 2 * vc->vc_rows;
                if (scrollback_phys_max < 0)
                        scrollback_phys_max = 0;
@@ -2133,11 +2141,11 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
 
        offset = p->yscroll - scrollback_current;
        limit = p->vrows;
-       switch (p->scrollmode && __SCROLL_YMASK) {
-       case __SCROLL_YWRAP:
+       switch (p->scrollmode) {
+       case SCROLL_WRAP:
                info->var.vmode |= FB_VMODE_YWRAP;
                break;
-       case __SCROLL_YPAN:
+       case SCROLL_PAN:
                limit -= vc->vc_rows;
                info->var.vmode &= ~FB_VMODE_YWRAP;
                break;
index a9d036b..6764dbc 100644 (file)
@@ -67,40 +67,27 @@ extern int set_con2fb_map(int unit, int newidx);
      *  Scroll Method
      */
      
-/* Internal flags */
-#define __SCROLL_YPAN          0x001
-#define __SCROLL_YWRAP         0x002
-#define __SCROLL_YMOVE         0x003
-#define __SCROLL_YREDRAW       0x004
-#define __SCROLL_YMASK         0x00f
-#define __SCROLL_YFIXED                0x010
-#define __SCROLL_YNOMOVE       0x020
-#define __SCROLL_YPANREDRAW    0x040
-#define __SCROLL_YNOPARTIAL    0x080
-
-/* Only these should be used by the drivers */
-/* Which one should you use? If you have a fast card and slow bus,
-   then probably just 0 to indicate fbcon should choose between
-   YWRAP/YPAN+MOVE/YMOVE. On the other side, if you have a fast bus
-   and even better if your card can do fonting (1->8/32bit painting),
-   you should consider either SCROLL_YREDRAW (if your card is
-   able to do neither YPAN/YWRAP), or SCROLL_YNOMOVE.
-   The best is to test it with some real life scrolling (usually, not
-   all lines on the screen are filled completely with non-space characters,
-   and REDRAW performs much better on such lines, so don't cat a file
-   with every line covering all screen columns, it would not be the right
-   benchmark).
+/* There are several methods fbcon can use to move text around the screen:
+ *
+ * + use the hardware engine to move the text
+ *    (hw-accelerated copyarea() and fillrect())
+ * + use hardware-supported panning on a large virtual screen
+ * + amifb can not only pan, but also wrap the display by N lines
+ *    (i.e. visible line i = physical line (i+N) % yres).
+ * + read what's already rendered on the screen and
+ *     write it in a different place (this is cfb_copyarea())
+ * + re-render the text to the screen
+ *
+ * Whether to use wrapping or panning can only be figured out at
+ * runtime (when we know whether our font height is a multiple
+ * of the pan/wrap step)
+ *
  */
-#define SCROLL_YREDRAW         (__SCROLL_YFIXED|__SCROLL_YREDRAW)
-#define SCROLL_YNOMOVE         (__SCROLL_YNOMOVE|__SCROLL_YPANREDRAW)
 
-/* SCROLL_YNOPARTIAL, used in combination with the above, is for video
-   cards which can not handle using panning to scroll a portion of the
-   screen without excessive flicker.  Panning will only be used for
-   whole screens.
- */
-/* Namespace consistency */
-#define SCROLL_YNOPARTIAL      __SCROLL_YNOPARTIAL
+#define SCROLL_ACCEL   0x001
+#define SCROLL_PAN     0x002
+#define SCROLL_WRAP    0x003
+#define SCROLL_REDRAW  0x004
 
 extern int fb_console_init(void);
 
index 5d9a6e8..7cf956e 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/pci.h>
 #include <linux/font.h>
 
-#include <asm/pgalloc.h>
 #include <asm/hardware.h>
 #include <asm/parisc-device.h>
 #include <asm/cacheflush.h>
index b75ab0d..23e1e7e 100644 (file)
@@ -963,6 +963,8 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
                p = (c->vc_visible_origin - vga_vram_base - ul + we) % we +
                    lines * c->vc_size_row;
                st = (c->vc_origin - vga_vram_base - ul + we) % we;
+               if (st < 2 * margin)
+                       margin = 0;
                if (p < margin)
                        p = 0;
                if (p > st - margin)
index 80d81e3..65a4021 100644 (file)
@@ -172,6 +172,7 @@ extern int kyrofb_init(void);
 extern int kyrofb_setup(char*);
 extern int mc68x328fb_init(void);
 extern int mc68x328fb_setup(char *);
+extern int asiliantfb_init(void);
 
 static struct {
        const char *name;
@@ -385,6 +386,9 @@ static struct {
 #ifdef CONFIG_FB_68328
        { "68328fb", mc68x328fb_init, mc68x328fb_setup },
 #endif
+#ifdef CONFIG_FB_ASILIANT
+       { "asiliantfb", asiliantfb_init, NULL },
+#endif
 
        /*
         * Generic drivers that don't use resource management (yet)
@@ -802,7 +806,7 @@ static int fbmem_read_proc(char *buf, char **start, off_t offset,
 }
 
 static ssize_t
-fb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
        unsigned long p = *ppos;
        struct inode *inode = file->f_dentry->d_inode;
@@ -839,7 +843,7 @@ fb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 }
 
 static ssize_t
-fb_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
        unsigned long p = *ppos;
        struct inode *inode = file->f_dentry->d_inode;
@@ -916,26 +920,30 @@ fb_cursor(struct fb_info *info, struct fb_cursor *sprite)
        
        if (cursor.set & FB_CUR_SETSHAPE) {
                int size = ((cursor.image.width + 7) >> 3) * cursor.image.height;               
+               char *data, *mask;
+
                if ((cursor.image.height != info->cursor.image.height) ||
                    (cursor.image.width != info->cursor.image.width))
                        cursor.set |= FB_CUR_SETSIZE;
                
-               cursor.image.data = kmalloc(size, GFP_KERNEL);
-               if (!cursor.image.data)
+               data = kmalloc(size, GFP_KERNEL);
+               if (!data)
                        return -ENOMEM;
                
-               cursor.mask = kmalloc(size, GFP_KERNEL);
-               if (!cursor.mask) {
-                       kfree(cursor.image.data);
+               mask = kmalloc(size, GFP_KERNEL);
+               if (!mask) {
+                       kfree(data);
                        return -ENOMEM;
                }
                
-               if (copy_from_user(cursor.image.data, sprite->image.data, size) ||
-                   copy_from_user(cursor.mask, sprite->mask, size)) { 
-                       kfree(cursor.image.data);
-                       kfree(cursor.mask);
+               if (copy_from_user(data, sprite->image.data, size) ||
+                   copy_from_user(mask, sprite->mask, size)) {
+                       kfree(data);
+                       kfree(mask);
                        return -EFAULT;
                }
+               cursor.image.data = data;
+               cursor.mask = mask;
        }
        info->cursor.set = cursor.set;
        info->cursor.rop = cursor.rop;
index 6b1635c..c4a5dbd 100644 (file)
@@ -1267,48 +1267,49 @@ imsttfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
              u_long arg, struct fb_info *info)
 {
        struct imstt_par *par = (struct imstt_par *) info->par;
+       void __user *argp = (void __user *)arg;
        __u32 reg[2];
        __u8 idx[2];
 
        switch (cmd) {
                case FBIMSTT_SETREG:
-                       if (copy_from_user(reg, (void *)arg, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
+                       if (copy_from_user(reg, argp, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
                                return -EFAULT;
                        write_reg_le32(par->dc_regs, reg[0], reg[1]);
                        return 0;
                case FBIMSTT_GETREG:
-                       if (copy_from_user(reg, (void *)arg, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
+                       if (copy_from_user(reg, argp, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
                                return -EFAULT;
                        reg[1] = read_reg_le32(par->dc_regs, reg[0]);
-                       if (copy_to_user((void *)(arg + 4), &reg[1], 4))
+                       if (copy_to_user((void __user *)(arg + 4), &reg[1], 4))
                                return -EFAULT;
                        return 0;
                case FBIMSTT_SETCMAPREG:
-                       if (copy_from_user(reg, (void *)arg, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
+                       if (copy_from_user(reg, argp, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
                                return -EFAULT;
                        write_reg_le32(((u_int *)par->cmap_regs), reg[0], reg[1]);
                        return 0;
                case FBIMSTT_GETCMAPREG:
-                       if (copy_from_user(reg, (void *)arg, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
+                       if (copy_from_user(reg, argp, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
                                return -EFAULT;
                        reg[1] = read_reg_le32(((u_int *)par->cmap_regs), reg[0]);
-                       if (copy_to_user((void *)(arg + 4), &reg[1], 4))
+                       if (copy_to_user((void __user *)(arg + 4), &reg[1], 4))
                                return -EFAULT;
                        return 0;
                case FBIMSTT_SETIDXREG:
-                       if (copy_from_user(idx, (void *)arg, 2))
+                       if (copy_from_user(idx, argp, 2))
                                return -EFAULT;
                        par->cmap_regs[PIDXHI] = 0;             eieio();
                        par->cmap_regs[PIDXLO] = idx[0];        eieio();
                        par->cmap_regs[PIDXDATA] = idx[1];      eieio();
                        return 0;
                case FBIMSTT_GETIDXREG:
-                       if (copy_from_user(idx, (void *)arg, 1))
+                       if (copy_from_user(idx, argp, 1))
                                return -EFAULT;
                        par->cmap_regs[PIDXHI] = 0;             eieio();
                        par->cmap_regs[PIDXLO] = idx[0];        eieio();
                        idx[1] = par->cmap_regs[PIDXDATA];
-                       if (copy_to_user((void *)(arg + 1), &idx[1], 1))
+                       if (copy_to_user((void __user *)(arg + 1), &idx[1], 1))
                                return -EFAULT;
                        return 0;
                default:
index aad0ab3..8639b25 100644 (file)
@@ -592,11 +592,11 @@ static int kyrofb_ioctl(struct inode *inode, struct file *file,
 {
        overlay_create ol_create;
        overlay_viewport_set ol_viewport_set;
+       void __user *argp = (void __user *)arg;
 
        switch (cmd) {
        case KYRO_IOCTL_OVERLAY_CREATE:
-               copy_from_user((void *) &ol_create, (void *) arg,
-                              sizeof(overlay_create));
+               copy_from_user(&ol_create, argp, sizeof(overlay_create));
 
                if (kyro_dev_overlay_create(ol_create.ulWidth,
                                            ol_create.ulHeight, 0) < 0) {
@@ -606,7 +606,7 @@ static int kyrofb_ioctl(struct inode *inode, struct file *file,
                }
                break;
        case KYRO_IOCTL_OVERLAY_VIEWPORT_SET:
-               copy_from_user((void *) &ol_viewport_set, (void *) arg,
+               copy_from_user(&ol_viewport_set, argp,
                               sizeof(overlay_viewport_set));
 
                if (kyro_dev_overlay_viewport_set(ol_viewport_set.xOrgin,
@@ -627,13 +627,13 @@ static int kyrofb_ioctl(struct inode *inode, struct file *file,
                }
                break;
        case KYRO_IOCTL_UVSTRIDE:
-               copy_to_user((void *)arg, (void *)&deviceInfo.ulOverlayUVStride, sizeof(unsigned long));
+               copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(unsigned long));
                break;
        case KYRO_IOCTL_STRIDE:
-               copy_to_user((void *)arg, (void *)&deviceInfo.ulOverlayStride, sizeof(unsigned long));
+               copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(unsigned long));
                break;
        case KYRO_IOCTL_OVERLAY_OFFSET:
-               copy_to_user((void *)arg, (void *)&deviceInfo.ulOverlayOffset, sizeof(unsigned long));
+               copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(unsigned long));
                break;
        }
 
index 88c0aea..8074e85 100644 (file)
@@ -874,6 +874,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                          unsigned int cmd, unsigned long arg,
                          struct fb_info *info)
 {
+       void __user *argp = (void __user *)arg;
        MINFO_FROM_INFO(info);
        
        DBG(__FUNCTION__)
@@ -891,7 +892,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                err = matroxfb_get_vblank(PMINFO &vblank);
                                if (err)
                                        return err;
-                               if (copy_to_user((struct fb_vblank*)arg, &vblank, sizeof(vblank)))
+                               if (copy_to_user(argp, &vblank, sizeof(vblank)))
                                        return -EFAULT;
                                return 0;
                        }
@@ -899,7 +900,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                        {
                                u_int32_t crt;
 
-                               if (get_user(crt, (u_int32_t *)arg))
+                               if (get_user(crt, (u_int32_t __user *)arg))
                                        return -EFAULT;
 
                                return matroxfb_wait_for_sync(PMINFO crt);
@@ -910,7 +911,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                struct matrox_altout *oproc;
                                int val;
 
-                               if (copy_from_user(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom)))
+                               if (copy_from_user(&mom, argp, sizeof(mom)))
                                        return -EFAULT;
                                if (mom.output >= MATROXFB_MAX_OUTPUTS)
                                        return -ENXIO;
@@ -960,7 +961,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                struct matrox_altout *oproc;
                                int val;
 
-                               if (copy_from_user(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom)))
+                               if (copy_from_user(&mom, argp, sizeof(mom)))
                                        return -EFAULT;
                                if (mom.output >= MATROXFB_MAX_OUTPUTS)
                                        return -ENXIO;
@@ -975,7 +976,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                up_read(&ACCESS_FBINFO(altout.lock));
                                if (val)
                                        return val;
-                               if (copy_to_user((struct matroxioc_output_mode*)arg, &mom, sizeof(mom)))
+                               if (copy_to_user(argp, &mom, sizeof(mom)))
                                        return -EFAULT;
                                return 0;
                        }
@@ -985,7 +986,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                int i;
                                int changes;
 
-                               if (copy_from_user(&tmp, (u_int32_t*)arg, sizeof(tmp)))
+                               if (copy_from_user(&tmp, argp, sizeof(tmp)))
                                        return -EFAULT;
                                for (i = 0; i < 32; i++) {
                                        if (tmp & (1 << i)) {
@@ -1040,7 +1041,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                                conn |= 1 << i;
                                        }
                                }
-                               if (put_user(conn, (u_int32_t*)arg))
+                               if (put_user(conn, (u_int32_t __user *)arg))
                                        return -EFAULT;
                                return 0;
                        }
@@ -1065,7 +1066,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                        if (conn & MATROXFB_OUTPUT_CONN_SECONDARY)
                                                conn &= ~MATROXFB_OUTPUT_CONN_DFP;
                                }
-                               if (put_user(conn, (u_int32_t*)arg))
+                               if (put_user(conn, (u_int32_t __user *)arg))
                                        return -EFAULT;
                                return 0;
                        }
@@ -1079,7 +1080,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                                conn |= 1 << i;
                                        }
                                }
-                               if (put_user(conn, (u_int32_t*)arg))
+                               if (put_user(conn, (u_int32_t __user *)arg))
                                        return -EFAULT;
                                return 0;
                        }
@@ -1093,7 +1094,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                sprintf(r.bus_info, "PCI:%s", pci_name(ACCESS_FBINFO(pcidev)));
                                r.version = KERNEL_VERSION(1,0,0);
                                r.capabilities = V4L2_CAP_VIDEO_OUTPUT;
-                               if (copy_to_user((void*)arg, &r, sizeof(r)))
+                               if (copy_to_user(argp, &r, sizeof(r)))
                                        return -EFAULT;
                                return 0;
                                
@@ -1103,7 +1104,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                struct v4l2_queryctrl qctrl;
                                int err;
 
-                               if (copy_from_user(&qctrl, (struct v4l2_queryctrl*)arg, sizeof(qctrl)))
+                               if (copy_from_user(&qctrl, argp, sizeof(qctrl)))
                                        return -EFAULT;
 
                                down_read(&ACCESS_FBINFO(altout).lock);
@@ -1116,7 +1117,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                }
                                up_read(&ACCESS_FBINFO(altout).lock);
                                if (err >= 0 &&
-                                   copy_to_user((struct v4l2_queryctrl*)arg, &qctrl, sizeof(qctrl)))
+                                   copy_to_user(argp, &qctrl, sizeof(qctrl)))
                                        return -EFAULT;
                                return err;
                        }
@@ -1125,7 +1126,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                struct v4l2_control ctrl;
                                int err;
 
-                               if (copy_from_user(&ctrl, (struct v4l2_control*)arg, sizeof(ctrl)))
+                               if (copy_from_user(&ctrl, argp, sizeof(ctrl)))
                                        return -EFAULT;
 
                                down_read(&ACCESS_FBINFO(altout).lock);
@@ -1138,7 +1139,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                }
                                up_read(&ACCESS_FBINFO(altout).lock);
                                if (err >= 0 &&
-                                   copy_to_user((struct v4l2_control*)arg, &ctrl, sizeof(ctrl)))
+                                   copy_to_user(argp, &ctrl, sizeof(ctrl)))
                                        return -EFAULT;
                                return err;
                        }
@@ -1147,7 +1148,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
                                struct v4l2_control ctrl;
                                int err;
 
-                               if (copy_from_user(&ctrl, (struct v4l2_control*)arg, sizeof(ctrl)))
+                               if (copy_from_user(&ctrl, argp, sizeof(ctrl)))
                                        return -EFAULT;
 
                                down_read(&ACCESS_FBINFO(altout).lock);
index d6f3935..0d7e067 100644 (file)
@@ -437,7 +437,7 @@ static int matroxfb_dh_ioctl(struct inode* inode,
                                err = matroxfb_dh_get_vblank(m2info, &vblank);
                                if (err)
                                        return err;
-                               if (copy_to_user((struct fb_vblank*)arg, &vblank, sizeof(vblank)))
+                               if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank)))
                                        return -EFAULT;
                                return 0;
                        }
@@ -445,7 +445,7 @@ static int matroxfb_dh_ioctl(struct inode* inode,
                        {
                                u_int32_t crt;
 
-                               if (get_user(crt, (u_int32_t *)arg))
+                               if (get_user(crt, (u_int32_t __user *)arg))
                                        return -EFAULT;
 
                                if (crt != 0)
@@ -464,7 +464,7 @@ static int matroxfb_dh_ioctl(struct inode* inode,
                                int out;
                                int changes;
 
-                               if (get_user(tmp, (u_int32_t*)arg))
+                               if (get_user(tmp, (u_int32_t __user *)arg))
                                        return -EFAULT;
                                for (out = 0; out < 32; out++) {
                                        if (tmp & (1 << out)) {
@@ -514,7 +514,7 @@ static int matroxfb_dh_ioctl(struct inode* inode,
                                                conn |= 1 << out;
                                        }
                                }
-                               if (put_user(conn, (u_int32_t*)arg))
+                               if (put_user(conn, (u_int32_t __user *)arg))
                                        return -EFAULT;
                                return 0;
                        }
@@ -539,7 +539,7 @@ static int matroxfb_dh_ioctl(struct inode* inode,
                                                tmp = 0;
                                        }
                                }
-                               if (put_user(tmp, (u_int32_t*)arg))
+                               if (put_user(tmp, (u_int32_t __user *)arg))
                                        return -EFAULT;
                                return 0;
                        }
index cd15734..d046edf 100644 (file)
@@ -490,6 +490,7 @@ int fb_find_mode(struct fb_var_screeninfo *var,
        int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
        unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
        int yres_specified = 0;
+       u32 best = -1, diff = -1;
 
        for (i = namelen-1; i >= 0; i--) {
            switch (name[i]) {
@@ -529,8 +530,8 @@ int fb_find_mode(struct fb_var_screeninfo *var,
        }
 done:
        for (i = refresh_specified; i >= 0; i--) {
-           DPRINTK("Trying specified video mode%s\n",
-                   i ? "" : " (ignoring refresh rate)");
+           DPRINTK("Trying specified video mode%s %ix%i\n",
+                   i ? "" : " (ignoring refresh rate)", xres, yres);
            for (j = 0; j < dbsize; j++)
                if ((name_matches(db[j], name, namelen) ||
                     (res_specified && res_matches(db[j], xres, yres))) &&
@@ -538,6 +539,22 @@ done:
                    !fb_try_mode(var, info, &db[j], bpp))
                    return 2-i;
        }
+       DPRINTK("Trying best-fit modes\n");
+       for (i = 0; i < dbsize; i++) {
+           if (xres <= db[i].xres && yres <= db[i].yres) {
+               DPRINTK("Trying %ix%i\n", db[i].xres, db[i].yres);
+               if (!fb_try_mode(var, info, &db[i], bpp)) {
+                   if (diff > (db[i].xres - xres) + (db[i].yres - yres)) {
+                       diff = (db[i].xres - xres) + (db[i].yres - yres);
+                       best = i;
+                   }
+               }
+           }
+       }
+       if (best != -1) {
+           fb_try_mode(var, info, &db[best], bpp);
+           return 5;
+       }
     }
 
     DPRINTK("Trying default video mode\n");
index bfa3f8b..7ded3f7 100644 (file)
@@ -42,7 +42,6 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/mach-types.h>
 #include <asm/uaccess.h>
 #include <asm/arch/bitfield.h>
 #include <asm/arch/pxafb.h>
@@ -109,10 +108,13 @@ pxafb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
        u_int val, ret = 1;
 
        if (regno < fbi->palette_size) {
-               val  = ((red   >>  0) & 0xf800);
-               val |= ((green >>  5) & 0x07e0);
-               val |= ((blue  >> 11) & 0x001f);
-
+               if (fbi->fb.var.grayscale) {
+                       val = ((blue >> 8) & 0x00ff);
+               } else {
+                       val  = ((red   >>  0) & 0xf800);
+                       val |= ((green >>  5) & 0x07e0);
+                       val |= ((blue  >> 11) & 0x001f);
+               }
                fbi->palette_cpu[regno] = val;
                ret = 0;
        }
@@ -150,7 +152,7 @@ pxafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
        switch (fbi->fb.fix.visual) {
        case FB_VISUAL_TRUECOLOR:
                /*
-                * 12 or 16-bit True Colour.  We encode the RGB value
+                * 16-bit True Colour.  We encode the RGB value
                 * according to the RGB bitfield information.
                 */
                if (regno < 16) {
@@ -242,7 +244,7 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
         * The pixel packing format is described on page 7-11 of the
         * PXA2XX Developer's Manual.
          */
-       if ( var->bits_per_pixel == 16 ) {
+       if (var->bits_per_pixel == 16) {
                var->red.offset   = 11; var->red.length   = 5;
                var->green.offset = 5;  var->green.length = 6;
                var->blue.offset  = 0;  var->blue.length  = 5;
@@ -297,7 +299,10 @@ static int pxafb_set_par(struct fb_info *info)
 
        fbi->fb.fix.line_length = var->xres_virtual *
                                  var->bits_per_pixel / 8;
-       fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
+       if (var->bits_per_pixel == 16)
+               fbi->palette_size = 0;
+       else
+               fbi->palette_size = var->bits_per_pixel == 1 ? 4 : 1 << var->bits_per_pixel;
 
        palette_mem_size = fbi->palette_size * sizeof(u16);
 
@@ -311,6 +316,11 @@ static int pxafb_set_par(struct fb_info *info)
         */
        pxafb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR);
 
+       if (fbi->fb.var.bits_per_pixel == 16)
+               fb_dealloc_cmap(&fbi->fb.cmap);
+       else
+               fb_alloc_cmap(&fbi->fb.cmap, 1<<fbi->fb.var.bits_per_pixel, 0);
+
        pxafb_activate_var(var, fbi);
 
        return 0;
@@ -349,7 +359,7 @@ static int pxafb_set_par(struct fb_info *info)
 /*
  * pxafb_blank():
  *     Blank the display by setting all palette values to zero.  Note, the
- *     12 and 16 bpp modes don't really use the palette, so this will not
+ *     16 bpp mode does not really use the palette, so this will not
  *      blank the display in all modes.
  */
 static int pxafb_blank(int blank, struct fb_info *info)
@@ -514,7 +524,7 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
         * the YRES parameter.
         */
        lines_per_panel = var->yres;
-       if (fbi->lccr0 & LCCR0_SDS)
+       if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual)
                lines_per_panel /= 2;
 
        new_regs.lccr2 =
@@ -566,20 +576,16 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
        fbi->dmadesc_palette_cpu->fidr  = 0;
        fbi->dmadesc_palette_cpu->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL;
 
-       if( var->bits_per_pixel < 12)
-       {
-               /* assume any mode with <12 bpp is palette driven */
-               fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
-               fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_palette_dma;
-               fbi->fdadr0 = fbi->dmadesc_palette_dma; /* flips back and forth between pal and fbhigh */
-       }
-       else
-       {
+       if (var->bits_per_pixel == 16) {
                /* palette shouldn't be loaded in true-color mode */
                fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
                fbi->fdadr0 = fbi->dmadesc_fbhigh_dma; /* no pal just fbhigh */
                /* init it to something, even though we won't be using it */
                fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_palette_dma;
+       } else {
+               fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
+               fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_palette_dma;
+               fbi->fdadr0 = fbi->dmadesc_palette_dma; /* flips back and forth between pal and fbhigh */
        }
 
 #if 0
@@ -696,7 +702,7 @@ static void pxafb_setup_gpio(struct pxafb_info *fbi)
        }
 
        else {
-               printk( KERN_ERR "pxafb_setup_gpio: unable to determine bits per pixel\n");
+               printk(KERN_ERR "pxafb_setup_gpio: unable to determine bits per pixel\n");
         }
 }
 
@@ -1123,11 +1129,11 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                                res_specified = 1;
                        }
                done:
-                       if ( res_specified ) {
-                               dev_info(dev, "overriding resolution: %dx%x\n", xres, yres);
+                       if (res_specified) {
+                               dev_info(dev, "overriding resolution: %dx%d\n", xres, yres);
                                inf->xres = xres; inf->yres = yres;
                        }
-                       if ( bpp_specified )
+                       if (bpp_specified)
                                switch (bpp) {
                                case 1:
                                case 2:
@@ -1142,7 +1148,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                                }
                 } else if (!strncmp(this_opt, "pixclock:", 9)) {
                         inf->pixclock = simple_strtoul(this_opt+9, NULL, 0);
-                       dev_info(dev, "override pixclock: %u\n", inf->pixclock);
+                       dev_info(dev, "override pixclock: %ld\n", inf->pixclock);
                 } else if (!strncmp(this_opt, "left:", 5)) {
                         inf->left_margin = simple_strtoul(this_opt+5, NULL, 0);
                        dev_info(dev, "override left: %u\n", inf->left_margin);
@@ -1162,7 +1168,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                         inf->vsync_len = simple_strtoul(this_opt+9, NULL, 0);
                        dev_info(dev, "override vsynclen: %u\n", inf->vsync_len);
                 } else if (!strncmp(this_opt, "hsync:", 6)) {
-                        if ( simple_strtoul(this_opt+6, NULL, 0) == 0 ) {
+                        if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
                                dev_info(dev, "override hsync: Active Low\n");
                                inf->sync &= ~FB_SYNC_HOR_HIGH_ACT;
                        } else {
@@ -1170,7 +1176,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                                inf->sync |= FB_SYNC_HOR_HIGH_ACT;
                        }
                 } else if (!strncmp(this_opt, "vsync:", 6)) {
-                        if ( simple_strtoul(this_opt+6, NULL, 0) == 0 ) {
+                        if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
                                dev_info(dev, "override vsync: Active Low\n");
                                inf->sync &= ~FB_SYNC_VERT_HIGH_ACT;
                        } else {
@@ -1178,7 +1184,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                                inf->sync |= FB_SYNC_VERT_HIGH_ACT;
                        }
                 } else if (!strncmp(this_opt, "dpc:", 4)) {
-                        if ( simple_strtoul(this_opt+4, NULL, 0) == 0 ) {
+                        if (simple_strtoul(this_opt+4, NULL, 0) == 0) {
                                dev_info(dev, "override double pixel clock: false\n");
                                inf->lccr3 &= ~LCCR3_DPC;
                        } else {
@@ -1186,20 +1192,20 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                                inf->lccr3 |= LCCR3_DPC;
                        }
                 } else if (!strncmp(this_opt, "outputen:", 9)) {
-                        if ( simple_strtoul(this_opt+9, NULL, 0) == 0 ) {
+                        if (simple_strtoul(this_opt+9, NULL, 0) == 0) {
                                dev_info(dev, "override output enable: active low\n");
-                               inf->lccr3 = ( inf->lccr3 & ~LCCR3_OEP ) | LCCR3_OutEnL;
+                               inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnL;
                        } else {
                                dev_info(dev, "override output enable: active high\n");
-                               inf->lccr3 = ( inf->lccr3 & ~LCCR3_OEP ) | LCCR3_OutEnH;
+                               inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnH;
                        }
                 } else if (!strncmp(this_opt, "pixclockpol:", 12)) {
-                        if ( simple_strtoul(this_opt+12, NULL, 0) == 0 ) {
+                        if (simple_strtoul(this_opt+12, NULL, 0) == 0) {
                                dev_info(dev, "override pixel clock polarity: falling edge\n");
-                               inf->lccr3 = ( inf->lccr3 & ~LCCR3_PCP ) | LCCR3_PixFlEdg;
+                               inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixFlEdg;
                        } else {
                                dev_info(dev, "override pixel clock polarity: rising edge\n");
-                               inf->lccr3 = ( inf->lccr3 & ~LCCR3_PCP ) | LCCR3_PixRsEdg;
+                               inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixRsEdg;
                        }
                 } else if (!strncmp(this_opt, "color", 5)) {
                        inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Color;
@@ -1244,7 +1250,7 @@ int __init pxafb_probe(struct device *dev)
 
 #ifdef CONFIG_FB_PXA_PARAMETERS
        ret = pxafb_parse_options(dev, g_options);
-       if ( ret < 0 )
+       if (ret < 0)
                goto failed;
 #endif
 
@@ -1252,23 +1258,23 @@ int __init pxafb_probe(struct device *dev)
         /* Check for various illegal bit-combinations. Currently only
         * a warning is given. */
 
-        if ( inf->lccr0 & LCCR0_INVALID_CONFIG_MASK )
+        if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK)
                 dev_warn(dev, "machine LCCR0 setting contains illegal bits: %08x\n",
                         inf->lccr0 & LCCR0_INVALID_CONFIG_MASK);
-        if ( inf->lccr3 & LCCR3_INVALID_CONFIG_MASK )
+        if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK)
                 dev_warn(dev, "machine LCCR3 setting contains illegal bits: %08x\n",
                         inf->lccr3 & LCCR3_INVALID_CONFIG_MASK);
-        if ( inf->lccr0 & LCCR0_DPD &&
-             ( ( inf->lccr0 & LCCR0_PAS ) != LCCR0_Pas ||
-               ( inf->lccr0 & LCCR0_SDS ) != LCCR0_Sngl ||
-               ( inf->lccr0 & LCCR0_CMS ) != LCCR0_Mono ) )
+        if (inf->lccr0 & LCCR0_DPD &&
+           ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas ||
+            (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl ||
+            (inf->lccr0 & LCCR0_CMS) != LCCR0_Mono))
                 dev_warn(dev, "Double Pixel Data (DPD) mode is only valid in passive mono"
                         " single panel mode\n");
-        if ( (inf->lccr0 & LCCR0_PAS) == LCCR0_Act &&
-             ( inf->lccr0 & LCCR0_SDS ) == LCCR0_Dual )
+        if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act &&
+           (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual)
                 dev_warn(dev, "Dual panel only valid in passive mode\n");
-        if ( (inf->lccr0 & LCCR0_PAS ) == LCCR0_Pas &&
-             (inf->upper_margin || inf->lower_margin) )
+        if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas &&
+             (inf->upper_margin || inf->lower_margin))
                 dev_warn(dev, "Upper and lower margins must be 0 in passive mode\n");
 #endif
 
index 9f258b0..50235d7 100644 (file)
@@ -1544,7 +1544,7 @@ static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int
                                        break;
                        }
 
-                       rc = get_user(value, (__u32*)arg);
+                       rc = get_user(value, (__u32 __user *)arg);
 
                        if (rc)
                                return rc;
@@ -1598,7 +1598,7 @@ static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int
                        if (CRTC_CRT_ON & tmp)
                                value |= 0x02;
 
-                       return put_user(value, (__u32*)arg);
+                       return put_user(value, (__u32 __user *)arg);
                default:
                        return -EINVAL;
        }
index f5a4db7..8898c99 100644 (file)
@@ -2,6 +2,10 @@
 # Makefile for the Riva framebuffer driver
 #
 
-obj-$(CONFIG_FB_RIVA) += rivafb.o
+obj-$(CONFIG_FB_RIVA)     += rivafb.o
 
-rivafb-objs := fbdev.o riva_hw.o nv_driver.o
+rivafb-objs               := fbdev.o riva_hw.o nv_driver.o
+
+ifdef CONFIG_FB_RIVA_I2C
+       rivafb-objs       += rivafb-i2c.o
+endif
index 1dc6e95..316e461 100644 (file)
@@ -296,9 +296,8 @@ static int forceCRTC __initdata = -1;
 static int nomtrr __initdata = 0;
 #endif
 
-#ifndef MODULE
 static char *mode_option __initdata = NULL;
-#endif
+static int  strictmode       = 0;
 
 static struct fb_fix_screeninfo rivafb_fix = {
        .id             = "nVidia",
@@ -493,54 +492,30 @@ static inline void reverse_order(u32 *l)
  * rivafb_cursor()
  */
 static void rivafb_load_cursor_image(struct riva_par *par, u8 *data8,
-                                    u8 *mask8, u16 bg, u16 fg, u32 w, u32 h)
+                                    u16 bg, u16 fg, u32 w, u32 h)
 {
        int i, j, k = 0;
-       u32 b, m, tmp;
+       u32 b, tmp;
        u32 *data = (u32 *)data8;
-       u32 *mask = (u32 *)mask8;
 
        for (i = 0; i < h; i++) {
                b = *data++;
-               m = *mask++;
                reverse_order(&b);
                
                for (j = 0; j < w/2; j++) {
                        tmp = 0;
 #if defined (__BIG_ENDIAN)
-                       if (m & (1 << 31)) {
-                               fg |= 1 << 15;
-                               bg |= 1 << 15;
-                       }
                        tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
                        b <<= 1;
-                       m <<= 1;
-
-                       if (m & (1 << 31)) {
-                               fg |= 1 << 15;
-                               bg |= 1 << 15;
-                       }
                        tmp |= (b & (1 << 31)) ? fg : bg;
                        b <<= 1;
-                       m <<= 1;
 #else
-                       if (m & 1) {
-                               fg |= 1 << 15;
-                               bg |= 1 << 15;
-                       }
                        tmp = (b & 1) ? fg : bg;
                        b >>= 1;
-                       m >>= 1;
-                       
-                       if (m & 1) {
-                               fg |= 1 << 15;
-                               bg |= 1 << 15;
-                       }
                        tmp |= (b & 1) ? fg << 16 : bg << 16;
                        b >>= 1;
-                       m >>= 1;
 #endif
-                       writel(tmp, par->riva.CURSOR + k++);
+                       writel(tmp, &par->riva.CURSOR[k++]);
                }
                k += (MAX_CURS - w)/2;
        }
@@ -833,6 +808,24 @@ static void riva_load_video_mode(struct fb_info *info)
        rivafb_blank(0, info);
 }
 
+static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
+{
+       var->xres = var->xres_virtual = modedb->xres;
+       var->yres = modedb->yres;
+        if (var->yres_virtual < var->yres)
+           var->yres_virtual = var->yres;
+        var->xoffset = var->yoffset = 0;
+        var->pixclock = modedb->pixclock;
+        var->left_margin = modedb->left_margin;
+        var->right_margin = modedb->right_margin;
+        var->upper_margin = modedb->upper_margin;
+        var->lower_margin = modedb->lower_margin;
+        var->hsync_len = modedb->hsync_len;
+        var->vsync_len = modedb->vsync_len;
+        var->sync = modedb->sync;
+        var->vmode = modedb->vmode;
+}
+
 /**
  * rivafb_do_maximize - 
  * @info: pointer to fb_info object containing info for current riva board
@@ -872,7 +865,7 @@ static int rivafb_do_maximize(struct fb_info *info,
                       "using maximum available virtual resolution\n");
                for (i = 0; modes[i].xres != -1; i++) {
                        if (modes[i].xres * nom / den * modes[i].yres <
-                           info->fix.smem_len / 2)
+                           info->fix.smem_len)
                                break;
                }
                if (modes[i].xres == -1) {
@@ -927,35 +920,47 @@ static int rivafb_do_maximize(struct fb_info *info,
                       "virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
                return -EINVAL;
        }
+       if (var->xres_virtual > 0x7fff)
+           var->xres_virtual = 0x7fff;
+       if (var->yres_virtual > 0x7fff)
+           var->yres_virtual = 0x7fff;
        return 0;
 }
 
+static void
+riva_set_pattern(struct riva_par *par, int clr0, int clr1, int pat0, int pat1)
+{
+       RIVA_FIFO_FREE(par->riva, Patt, 4);
+       par->riva.Patt->Color0        = clr0;
+       par->riva.Patt->Color1        = clr1;
+       par->riva.Patt->Monochrome[0] = pat0;
+       par->riva.Patt->Monochrome[1] = pat1;
+}
+
 /* acceleration routines */
 inline void wait_for_idle(struct riva_par *par)
 {
        while (par->riva.Busy(&par->riva));
 }
 
-/* set copy ROP, no mask */
-static void riva_setup_ROP(struct riva_par *par)
+/*
+ * Set ROP.  Translate X rop into ROP3.  Internal routine.
+ */
+static void
+riva_set_rop_solid(struct riva_par *par, int rop)
 {
-       RIVA_FIFO_FREE(par->riva, Patt, 5);
-       par->riva.Patt->Shape = 0;
-       par->riva.Patt->Color0 = 0xffffffff;
-       par->riva.Patt->Color1 = 0xffffffff;
-       par->riva.Patt->Monochrome[0] = 0xffffffff;
-       par->riva.Patt->Monochrome[1] = 0xffffffff;
-
-       RIVA_FIFO_FREE(par->riva, Rop, 1);
-       par->riva.Rop->Rop3 = 0xCC;
+       riva_set_pattern(par, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+        RIVA_FIFO_FREE(par->riva, Rop, 1);
+        par->riva.Rop->Rop3 = rop;
+
 }
 
 void riva_setup_accel(struct riva_par *par)
 {
        RIVA_FIFO_FREE(par->riva, Clip, 2);
        par->riva.Clip->TopLeft     = 0x0;
-       par->riva.Clip->WidthHeight = 0x80008000;
-       riva_setup_ROP(par);
+       par->riva.Clip->WidthHeight = 0x7fff7fff;
+       riva_set_rop_solid(par, 0xcc);
        wait_for_idle(par);
 }
 
@@ -1043,7 +1048,9 @@ static int rivafb_release(struct fb_info *info, int user)
 
 static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
+       struct fb_monspecs *specs = &info->monspecs;
        int nom, den;           /* translating from pixels->bytes */
+       int mode_valid = 0;
        
        switch (var->bits_per_pixel) {
        case 1 ... 8:
@@ -1094,6 +1101,73 @@ static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
                return -EINVAL;
        }
 
+       if (!strictmode) {
+               if (!fb_validate_mode(var, info))
+                       mode_valid = 1;
+       }
+
+       /* find best mode from modedb */
+       if (!mode_valid && specs->modedb_len) {
+               int i, best, best_refresh, best_x, best_y, diff_x, diff_y;
+
+               best_refresh = best = best_x = best_y = 0;
+               diff_x = diff_y = -1;
+
+               for (i = 0; i < specs->modedb_len; i++) {
+                       if (var->xres <= specs->modedb[i].xres &&
+                           !(specs->modedb[i].flag & FB_MODE_IS_CALCULATED) &&
+                           specs->modedb[i].xres - var->xres < diff_x) {
+                               best_x = specs->modedb[i].xres;
+                               diff_x = best_x - var->xres;
+                       }
+                       if (!diff_x) break;
+               }
+
+               if (diff_x != -1) {
+                       for (i = 0; i < specs->modedb_len; i++) {
+                               if (best_x == specs->modedb[i].xres &&
+                                   var->yres <= specs->modedb[i].yres &&
+                                   !(specs->modedb[i].flag &
+                                     FB_MODE_IS_CALCULATED) &&
+                                   specs->modedb[i].yres-var->yres < diff_y) {
+                                       best_y = specs->modedb[i].yres;
+                                       diff_y = best_y - var->yres;
+                               }
+                               if (!diff_y) break;
+                       }
+               }
+
+               if (diff_y != -1) {
+                       for (i = 0; i < specs->modedb_len; i++) {
+                               if (best_x == specs->modedb[i].xres &&
+                                   best_y == specs->modedb[i].yres &&
+                                   !(specs->modedb[i].flag &
+                                     FB_MODE_IS_CALCULATED) &&
+                                   specs->modedb[i].refresh > best_refresh) {
+                                       best_refresh=specs->modedb[i].refresh;
+                                       best = i;
+                               }
+                       }
+               }
+
+               if (best_refresh) {
+                       riva_update_var(var, &specs->modedb[best]);
+                       mode_valid = 1;
+               }
+       }
+
+       /* calculate modeline if supported by monitor */
+       if (!mode_valid && info->monspecs.gtf) {
+               if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
+                       mode_valid = 1;
+       }
+       if (!mode_valid && info->monspecs.modedb_len)
+               return -EINVAL;
+
+       if (var->xres_virtual < var->xres)
+               var->xres_virtual = var->xres;
+       if (var->yres_virtual <= var->yres)
+               var->yres_virtual = -1;
        if (rivafb_do_maximize(info, var, nom, den) < 0)
                return -EINVAL;
 
@@ -1329,8 +1403,7 @@ static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect
                break;
        }
 
-       RIVA_FIFO_FREE(par->riva, Rop, 1);
-       par->riva.Rop->Rop3 = rop;
+       riva_set_rop_solid(par, rop);
 
        RIVA_FIFO_FREE(par->riva, Bitmap, 1);
        par->riva.Bitmap->Color1A = color;
@@ -1338,10 +1411,12 @@ static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect
        RIVA_FIFO_FREE(par->riva, Bitmap, 2);
        par->riva.Bitmap->UnclippedRectangle[0].TopLeft =
                        (rect->dx << 16) | rect->dy;
+       mb();
        par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
                        (rect->width << 16) | rect->height;
-       RIVA_FIFO_FREE(par->riva, Rop, 1);
-       par->riva.Rop->Rop3 = 0xCC;     // back to COPY
+       mb();
+       riva_set_rop_solid(par, 0xcc);
+
 }
 
 /**
@@ -1362,8 +1437,9 @@ static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *regi
        RIVA_FIFO_FREE(par->riva, Blt, 3);
        par->riva.Blt->TopLeftSrc  = (region->sy << 16) | region->sx;
        par->riva.Blt->TopLeftDst  = (region->dy << 16) | region->dx;
+       mb();
        par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
-       wait_for_idle(par);
+       mb();
 }
 
 static inline void convert_bgcolor_16(u32 *col)
@@ -1372,6 +1448,7 @@ static inline void convert_bgcolor_16(u32 *col)
                | ((*col & 0x000003E0) << 6)
                | ((*col & 0x0000001F) << 3)
                |          0xFF000000;
+       mb();
 }
 
 /**
@@ -1478,7 +1555,6 @@ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
        struct riva_par *par = (struct riva_par *) info->par;
        u8 data[MAX_CURS * MAX_CURS/8];
-       u8 mask[MAX_CURS * MAX_CURS/8];
        u16 fg, bg;
        int i;
 
@@ -1508,7 +1584,7 @@ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
                info->cursor.image.fg_color = cursor->image.fg_color;
        }
 
-       if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) {
+       if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETCUR)) {
                u32 bg_idx = info->cursor.image.bg_color;
                u32 fg_idx = info->cursor.image.fg_color;
                u32 s_pitch = (info->cursor.image.width+7) >> 3;
@@ -1517,34 +1593,35 @@ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
                u8 *msk = (u8 *) info->cursor.mask;
                u8 src[64];     
                
+               info->cursor.image.data = cursor->image.data;
                switch (info->cursor.rop) {
                case ROP_XOR:
-                       for (i = 0; i < s_pitch * info->cursor.image.height; i++)
-                                       src[i] = dat[i] ^ msk[i];
+                       for (i = 0; i < s_pitch * info->cursor.image.height;
+                            i++)
+                               src[i] = dat[i] ^ msk[i];
                        break;
                case ROP_COPY:
                default:
-                       for (i = 0; i < s_pitch * info->cursor.image.height; i++)
-                               
-                                       src[i] = dat[i] & msk[i];
+                       for (i = 0; i < s_pitch * info->cursor.image.height;
+                            i++)
+                               src[i] = dat[i] & msk[i];
                        break;
                }
                
-               fb_move_buf_aligned(info, &info->sprite, data, d_pitch, src, s_pitch, info->cursor.image.height);
-
-               fb_move_buf_aligned(info, &info->sprite, mask, d_pitch, msk, s_pitch, info->cursor.image.height);
+               fb_move_buf_aligned(info, &info->sprite, data, d_pitch, src,
+                                   s_pitch, info->cursor.image.height);
 
                bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
                     ((info->cmap.green[bg_idx] & 0xf8) << 2) |
-                    ((info->cmap.blue[bg_idx] & 0xf8) >> 3);
+                    ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
 
                fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
                     ((info->cmap.green[fg_idx] & 0xf8) << 2) |
-                    ((info->cmap.blue[fg_idx] & 0xf8) >> 3);
+                    ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
 
                par->riva.LockUnlock(&par->riva, 0);
 
-               rivafb_load_cursor_image(par, data, mask, bg, fg,
+               rivafb_load_cursor_image(par, data, bg, fg,
                                         info->cursor.image.width, 
                                         info->cursor.image.height);
        }
@@ -1586,24 +1663,19 @@ static struct fb_ops riva_fb_ops = {
 
 static int __devinit riva_set_fbinfo(struct fb_info *info)
 {
-       struct riva_par *par = (struct riva_par *) info->par;
        unsigned int cmap_len;
 
-       info->flags = FBINFO_FLAG_DEFAULT;
+       info->flags = FBINFO_DEFAULT
+                   | FBINFO_HWACCEL_XPAN
+                   | FBINFO_HWACCEL_YPAN
+                   | FBINFO_HWACCEL_COPYAREA
+                   | FBINFO_HWACCEL_FILLRECT
+                   | FBINFO_HWACCEL_IMAGEBLIT;
        info->var = rivafb_default_var;
-       info->fix = rivafb_fix;
-       info->fbops = &riva_fb_ops;
+       info->fix.visual = (info->var.bits_per_pixel == 8) ?
+                               FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
        info->pseudo_palette = pseudo_palette;
 
-#ifndef MODULE
-       if (mode_option)
-               fb_find_mode(&info->var, info, mode_option,
-                            NULL, 0, NULL, 8);
-#endif
-       if (par->use_default_var)
-               /* We will use the modified default var */
-               info->var = rivafb_default_var;
-
        cmap_len = riva_get_cmap_len(&info->var);
        fb_alloc_cmap(&info->cmap, cmap_len, 0);        
 
@@ -1611,7 +1683,8 @@ static int __devinit riva_set_fbinfo(struct fb_info *info)
        info->pixmap.buf_align = 4;
        info->pixmap.scan_align = 4;
        info->pixmap.flags = FB_PIXMAP_SYSTEM;
-       return 0;
+       info->var.yres_virtual = -1;
+       return (rivafb_check_var(&info->var, info));
 }
 
 #ifdef CONFIG_PPC_OF
@@ -1620,89 +1693,60 @@ static int riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
        struct riva_par *par = (struct riva_par *) info->par;
        struct device_node *dp;
        unsigned char *pedid = NULL;
+       unsigned char *disptype = NULL;
+       static char *propnames[] = {
+               "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL };
+       int i;
 
        dp = pci_device_to_OF_node(pd);
-       pedid = (unsigned char *)get_property(dp, "EDID,B", 0);
-
-       if (pedid) {
+       for (; dp != NULL; dp = dp->child) {
+               disptype = (unsigned char *)get_property(dp, "display-type", NULL);
+               if (disptype == NULL)
+                       continue;
+               if (strncmp(disptype, "LCD", 3) != 0)
+                       continue;
+               for (i = 0; propnames[i] != NULL; ++i) {
+                       pedid = (unsigned char *)
+                               get_property(dp, propnames[i], NULL);
+                       if (pedid != NULL) {
                par->EDID = pedid;
                return 1;
-       } else
+                       }
+               }
+       }
                return 0;
 }
 #endif /* CONFIG_PPC_OF */
 
-static int riva_dfp_parse_EDID(struct riva_par *par)
+static void riva_update_default_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-       unsigned char *block = par->EDID;
-
-       if (!block)
-               return 0;
-
-       /* jump to detailed timing block section */
-       block += 54;
-
-       par->clock = (block[0] + (block[1] << 8));
-       par->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
-       par->hblank = (block[3] + ((block[4] & 0x0f) << 8));
-       par->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
-       par->vblank = (block[6] + ((block[7] & 0x0f) << 8));
-       par->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
-       par->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
-       par->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
-       par->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
-       par->interlaced = ((block[17] & 0x80) >> 7);
-       par->synct = ((block[17] & 0x18) >> 3);
-       par->misc = ((block[17] & 0x06) >> 1);
-       par->hAct_high = par->vAct_high = 0;
-       if (par->synct == 3) {
-               if (par->misc & 2)
-                       par->hAct_high = 1;
-               if (par->misc & 1)
-                       par->vAct_high = 1;
+       struct fb_monspecs *specs = &info->monspecs;
+       struct fb_videomode modedb;
+
+       /* respect mode options */
+       if (mode_option) {
+               fb_find_mode(var, info, mode_option,
+                            specs->modedb, specs->modedb_len,
+                            NULL, 8);
+       } else if (specs->modedb != NULL) {
+               /* get preferred timing */
+               if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
+                       int i;
+
+                       for (i = 0; i < specs->modedb_len; i++) {
+                               if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
+                                       modedb = specs->modedb[i];
+                                       break;
+                               }
+                       }
+               } else {
+                       /* otherwise, get first mode in database */
+                       modedb = specs->modedb[0];
+               }
+               var->bits_per_pixel = 8;
+               riva_update_var(var, &modedb);
        }
-
-       printk(KERN_INFO PFX
-                       "detected DFP panel size from EDID: %dx%d\n", 
-                       par->panel_xres, par->panel_yres);
-       par->got_dfpinfo = 1;
-       return 1;
-}
-
-static void riva_update_default_var(struct fb_info *info)
-{
-       struct fb_var_screeninfo *var = &rivafb_default_var;
-       struct riva_par *par = (struct riva_par *) info->par;
-
-        var->xres = par->panel_xres;
-        var->yres = par->panel_yres;
-        var->xres_virtual = par->panel_xres;
-        var->yres_virtual = par->panel_yres;
-        var->xoffset = var->yoffset = 0;
-        var->bits_per_pixel = 8;
-        var->pixclock = 100000000 / par->clock;
-        var->left_margin = (par->hblank - par->hOver_plus - par->hSync_width);
-        var->right_margin = par->hOver_plus;
-        var->upper_margin = (par->vblank - par->vOver_plus - par->vSync_width);
-        var->lower_margin = par->vOver_plus;
-        var->hsync_len = par->hSync_width;
-        var->vsync_len = par->vSync_width;
-        var->sync = 0;
-
-        if (par->synct == 3) {
-                if (par->hAct_high)
-                        var->sync |= FB_SYNC_HOR_HIGH_ACT;
-                if (par->vAct_high)
-                        var->sync |= FB_SYNC_VERT_HIGH_ACT;
-        }
-        var->vmode = 0;
-        if (par->interlaced)
-                var->vmode |= FB_VMODE_INTERLACED;
-
        var->accel_flags |= FB_ACCELF_TEXT;
-        
-        par->use_default_var = 1;
 }
 
 
@@ -1713,19 +1757,27 @@ static void riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
                printk("rivafb: could not retrieve EDID from OF\n");
 #else
        /* XXX use other methods later */
+#ifdef CONFIG_FB_RIVA_I2C
+       struct riva_par *par = (struct riva_par *) info->par;
+
+       riva_create_i2c_busses(par);
+       riva_probe_i2c_connector(par, 1, &par->EDID);
+       riva_delete_i2c_busses(par);
+#endif
 #endif
 }
 
 
-static void riva_get_dfpinfo(struct fb_info *info)
+static void riva_get_edidinfo(struct fb_info *info)
 {
+       struct fb_var_screeninfo *var = &rivafb_default_var;
        struct riva_par *par = (struct riva_par *) info->par;
 
-       if (riva_dfp_parse_EDID(par))
-               riva_update_default_var(info);
+       fb_edid_to_monspecs(par->EDID, &info->monspecs);
+       riva_update_default_var(var, info);
 
        /* if user specified flatpanel, we respect that */
-       if (par->got_dfpinfo == 1)
+       if (info->monspecs.input & FB_DISP_DDI)
                par->FlatPanel = 1;
 }
 
@@ -1755,6 +1807,7 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
 
        memset(info, 0, sizeof(struct fb_info));
        memset(default_par, 0, sizeof(struct riva_par));
+       default_par->pdev = pd;
 
        info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
        if (info->pixmap.addr == NULL)
@@ -1802,10 +1855,6 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
 
        info->par = default_par;
 
-       riva_get_EDID(info, pd);
-
-       riva_get_dfpinfo(info);
-
        switch (default_par->riva.Architecture) {
        case NV_ARCH_03:
                /* Riva128's PRAMIN is in the "framebuffer" space
@@ -1870,6 +1919,11 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
        }
 #endif /* CONFIG_MTRR */
 
+       info->fbops = &riva_fb_ops;
+       info->fix = rivafb_fix;
+       riva_get_EDID(info, pd);
+       riva_get_edidinfo(info);
+
        if (riva_set_fbinfo(info) < 0) {
                printk(KERN_ERR PFX "error setting initial video mode\n");
                goto err_out_iounmap_fb;
@@ -1978,6 +2032,8 @@ int __init rivafb_setup(char *options)
                } else if (!strncmp(this_opt, "nomtrr", 6)) {
                        nomtrr = 1;
 #endif
+               } else if (!strncmp(this_opt, "strictmode", 10)) {
+                       strictmode = 1;
                } else
                        mode_option = this_opt;
        }
@@ -2026,6 +2082,8 @@ MODULE_PARM_DESC(forceCRTC, "Forces usage of a particular CRTC in case autodetec
 #ifdef CONFIG_MTRR
 MODULE_PARM(nomtrr, "i");
 MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
+MODULE_PARM(strictmode, "i");
+MODULE_PARM_DESC(strictmode, "Only use video modes from EDID");
 #endif
 #endif /* MODULE */
 
index 863142e..beb2df6 100644 (file)
@@ -4,6 +4,10 @@
 #include <linux/config.h>
 #include <linux/fb.h>
 #include <video/vga.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/i2c-algo-bit.h>
+
 #include "riva_hw.h"
 
 /* GGI compatibility macros */
 #define NUM_GRC_REGS           0x09
 #define NUM_ATC_REGS           0x15
 
+/* I2C */
+#define DDC_SCL_READ_MASK       (1 << 2)
+#define DDC_SCL_WRITE_MASK      (1 << 5)
+#define DDC_SDA_READ_MASK       (1 << 3)
+#define DDC_SDA_WRITE_MASK      (1 << 4)
+
 /* holds the state of the VGA core and extended Riva hw state from riva_hw.c.
  * From KGI originally. */
 struct riva_regs {
@@ -23,6 +33,15 @@ struct riva_regs {
        RIVA_HW_STATE ext;
 };
 
+struct riva_par;
+
+struct riva_i2c_chan {
+       struct riva_par *par;
+       unsigned long   ddc_base;
+       struct i2c_adapter adapter;
+       struct i2c_algo_bit_data algo;
+};
+
 struct riva_par {
        RIVA_HW_INST riva;      /* interface to riva_hw.c */
 
@@ -36,26 +55,22 @@ struct riva_par {
        u32 cursor_data[32 * 32/4];
        int cursor_reset;
        unsigned char *EDID;
-
-       int panel_xres, panel_yres;
-       int hOver_plus, hSync_width, hblank;
-       int vOver_plus, vSync_width, vblank;
-       int hAct_high, vAct_high, interlaced;
-       int synct, misc, clock;
-
-       int use_default_var;
-       int got_dfpinfo;
        unsigned int Chipset;
        int forceCRTC;
        Bool SecondCRTC;
        int FlatPanel;
+       struct pci_dev *pdev;
 #ifdef CONFIG_MTRR
        struct { int vram; int vram_valid; } mtrr;
 #endif
+       struct riva_i2c_chan chan[3];
 };
 
 void riva_common_setup(struct riva_par *);
 unsigned long riva_get_memlen(struct riva_par *);
 unsigned long riva_get_maxdclk(struct riva_par *);
+void riva_delete_i2c_busses(struct riva_par *par);
+void riva_create_i2c_busses(struct riva_par *par);
+int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid);
 
 #endif /* __RIVAFB_H */
index a09be52..c1ab754 100644 (file)
@@ -122,6 +122,7 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
                cmap.red = &red;
                cmap.green = &green;
                cmap.blue = &blue;
+               cmap.transp = NULL;
                for (i = 0; i < count; i++) {
                        int err;
 
index a7d798b..426d02b 100644 (file)
@@ -1,4 +1,5 @@
 /* $XFree86$ */
+/* $XdotOrg$ */
 /*
  * Register settings for SiS 300 series
  *
  * * 2) Redistributions in binary form must reproduce the above copyright
  * *    notice, this list of conditions and the following disclaimer in the
  * *    documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * *    must display the following acknowledgement: "This product includes
- * *    software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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,
  *
  */
 
-typedef struct _SiS300_StStruct
-{
-       UCHAR St_ModeID;
-       USHORT St_ModeFlag;
-       UCHAR St_StTableIndex;
-       UCHAR St_CRT2CRTC;
-       UCHAR St_ResInfo;
-       UCHAR VB_StTVFlickerIndex;
-       UCHAR VB_StTVEdgeIndex;
-       UCHAR VB_StTVYFilterIndex;
-       UCHAR St_PDC;
-} SiS300_StStruct;
-
-static const SiS300_StStruct  SiS300_SModeIDTable[] =
+static const SiS_StStruct  SiS300_SModeIDTable[] =
 {
        {0x01,0x9208,0x01,0x00,0x00,0x00,0x00,0x00, 0},
        {0x01,0x1210,0x14,0x01,0x01,0x00,0x00,0x00, 0},
@@ -89,206 +74,168 @@ static const SiS300_StStruct  SiS300_SModeIDTable[] =
        {0xff,     0,   0,   0,   0,   0,   0,   0, 0}
 };
 
-typedef struct _SiS300_ExtStruct
-{
-       UCHAR  Ext_ModeID;
-       USHORT Ext_ModeFlag;
-       UCHAR  Ext_ModeOffset;
-       USHORT Ext_VESAID;
-       UCHAR  Ext_RESINFO;
-       UCHAR  VB_ExtTVFlickerIndex;
-       UCHAR  VB_ExtTVEdgeIndex;
-       UCHAR  VB_ExtTVYFilterIndex;
-       UCHAR  VB_ExtTVYFilterIndexROM661;
-       UCHAR  REFindex;
-} SiS300_ExtStruct;
-
-static const SiS300_ExtStruct  SiS300_EModeIDTable[] =
-{
-       {0x6a,0x2212,0x04,0x0102,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00},  /* 800x600x? */
-       {0x2e,0x0a1b,0x03,0x0101,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08},
-       {0x2f,0x021b,0x03,0x0100,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10},  /* 640x400x8 */
-       {0x30,0x2a1b,0x04,0x0103,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00},
-       {0x31,0x0a1b,0x0a,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11},  /* 720x480x8 */
-       {0x32,0x2a1b,0x0a,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12},  /* 720x576x8 */
-       {0x33,0x0a1d,0x0a,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11},  /* 720x480x16 */
-       {0x34,0x2a1d,0x0a,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12},  /* 720x576x16 */
-       {0x35,0x0a1f,0x0a,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11},  /* 720x480x32 */
-       {0x36,0x2a1f,0x0a,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12},  /* 720x576x32 */
-       {0x37,0x0212,0x05,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13},  /* 1024x768x? */
-       {0x38,0x0a1b,0x05,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13},  /* 1024x768x8 */
-       {0x3a,0x0e3b,0x06,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},  /* 1280x1024x8 */
-       {0x3c,0x063b,0x07,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e},
-       {0x3d,0x067d,0x07,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e},
-       {0x40,0x921c,0x00,0x010d,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23},  /* 320x200x15 */
-       {0x41,0x921d,0x00,0x010e,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23},  /* 320x200x16 */
-       {0x43,0x0a1c,0x03,0x0110,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08},
-       {0x44,0x0a1d,0x03,0x0111,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08},
-       {0x46,0x2a1c,0x04,0x0113,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00},  /* 800x600x15 */
-       {0x47,0x2a1d,0x04,0x0114,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00},  /* 800x600x16 */
-       {0x49,0x0a3c,0x05,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13},
-       {0x4a,0x0a3d,0x05,0x0117,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13},
-       {0x4c,0x0e7c,0x06,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},
-       {0x4d,0x0e7d,0x06,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},
-       {0x50,0x921b,0x00,0x0132,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x24},  /* 320x240x8  */
-       {0x51,0xb21b,0x01,0x0133,SIS_RI_400x300,  0x00,0x00,0x00,0x00,0x25},  /* 400x300x8  */
-       {0x52,0x921b,0x02,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x26},  /* 512x384x8  */
-       {0x56,0x921d,0x00,0x0135,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x24},  /* 320x240x16 */
-       {0x57,0xb21d,0x01,0x0136,SIS_RI_400x300,  0x00,0x00,0x00,0x00,0x25},  /* 400x300x16 */
-       {0x58,0x921d,0x02,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x26},  /* 512x384x16 */
-       {0x59,0x921b,0x00,0x0138,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23},  /* 320x200x8  */
-       {0x5c,0x921f,0x02,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x26},  /* 512x384x32 */
-       {0x5d,0x021d,0x03,0x0139,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10},  /* 640x400x16 */
-       {0x5e,0x021f,0x03,0x0000,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10},  /* 640x400x32 */
-       {0x62,0x0a3f,0x03,0x013a,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08},
-       {0x63,0x2a3f,0x04,0x013b,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00},  /* 800x600x32 */
-       {0x64,0x0a7f,0x05,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13},
-       {0x65,0x0eff,0x06,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},
-       {0x66,0x06ff,0x07,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e},
-       {0x68,0x067b,0x08,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27},
-       {0x69,0x06fd,0x08,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27},
-       {0x6b,0x07ff,0x08,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27},
-       {0x6c,0x067b,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28},  /* 2048x1536x8 - not in BIOS! */
-       {0x6d,0x06fd,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28},  /* 2048x1536x16 - not in BIOS! */
-       {0x70,0x2a1b,0x04,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d},  /* 800x480x8 */
-       {0x71,0x0a1b,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30},  /* 1024x576x8 */
-       {0x74,0x0a1d,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30},  /* 1024x576x16 */
-       {0x75,0x0e3d,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33},  /* 1280x720x16 */
-       {0x76,0x2a1f,0x04,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d},  /* 800x480x32 */
-       {0x77,0x0a3f,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30},  /* 1024x576x32 */
-       {0x78,0x0eff,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33},  /* 1280x720x32 */
-       {0x79,0x0e3b,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33},  /* 1280x720x8 */
-       {0x7a,0x2a1d,0x04,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d},  /* 800x480x16 */
-       {0x7c,0x0a3b,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29},  /* 1280x960x8 */
-       {0x7d,0x0a7d,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29},  /* 1280x960x16 */
-       {0x7e,0x0aff,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29},  /* 1280x960x32 */
-       {0x20,0x0a1b,0x05,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b},  /* 1024x600 */
-       {0x21,0x0a3d,0x05,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b},
-       {0x22,0x0a7f,0x05,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b},
-       {0x23,0x0a1b,0x0c,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c},  /* 1152x768 */
-       {0x24,0x0a3d,0x0c,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c},
-       {0x25,0x0a7f,0x0c,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c},
-       {0x29,0x0e1b,0x0c,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36},  /* 1152x864 */
-       {0x2a,0x0e3d,0x0c,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36},
-       {0x2b,0x0e7f,0x0c,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36},
-       {0x39,0x2a1b,0x0d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38},  /* 848x480 */
-       {0x3b,0x2a3d,0x0d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38},
-       {0x3e,0x2a7f,0x0d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38},
-       {0x3f,0x2a1b,0x0d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a},  /* 856x480 */
-       {0x42,0x2a3d,0x0d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a},
-       {0x45,0x2a7f,0x0d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a},
-       {0x48,0x223b,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c},  /* 1360x768 */
-       {0x4b,0x227d,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c},
-       {0x4e,0x22ff,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c},
-       {0x4f,0x921f,0x00,0x0000,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23},  /* 320x200x32 */
-       {0x53,0x921f,0x00,0x0000,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x24},  /* 320x240x32 */
-       {0x54,0xb21f,0x01,0x0000,SIS_RI_400x300,  0x00,0x00,0x00,0x00,0x25},  /* 400x300x32 */
-       {0x55,0x2e3b,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d},  /* 1280x768   */
-       {0x5a,0x2e7d,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d},
-       {0x5b,0x2eff,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d},
-       {0x5f,0x2a1b,0x0f,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e},  /* 768x576x8 */
-       {0x60,0x2a1d,0x0f,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e},  /* 768x576x16 */
-       {0x61,0x2a1f,0x0f,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e},  /* 768x576x32 */
-       {0x67,0x2e3b,0x0e,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f},  /* 1360x1024x8 (BARCO) */
-       {0x6f,0x2e7d,0x0e,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f},  /* 1360x1024x16 (BARCO) */
-       {0x72,0x2eff,0x0e,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f},  /* 1360x1024x32 (BARCO) */
-       {0xff,0x0000,0x00,0xffff,0,               0x00,0x00,0x00,0x00,0x00}
-};
-
-typedef struct _SiS300_Ext2Struct
-{
-       USHORT Ext_InfoFlag;
-       UCHAR  Ext_CRT1CRTC;  /* Index in SiS300_CRT1Table */
-       UCHAR  Ext_CRTVCLK;   /* Index in VCLK array */
-       UCHAR  Ext_CRT2CRTC;  /* Index in LCD Paneltype arrays (&3f) */
-       UCHAR  ModeID;
-       USHORT XRes;
-       USHORT YRes;
-       UCHAR  Ext_PDC;
-} SiS300_Ext2Struct;
-
-static const SiS300_Ext2Struct  SiS300_RefIndex[] =
-{
-       {0x085f,0x0d,0x03,0x05,0x6a, 800, 600, 0}, /* 00 */
-       {0x0467,0x0e,0x44,0x05,0x6a, 800, 600, 0}, /* 01 */
-       {0x0067,0x0f,0x07,0x48,0x6a, 800, 600, 0}, /* 02 - CRT1CRTC was 0x4f */
-       {0x0067,0x10,0x06,0x8b,0x6a, 800, 600, 0}, /* 03 */
-       {0x0147,0x11,0x08,0x00,0x6a, 800, 600, 0}, /* 04 */
-       {0x0147,0x12,0x0c,0x00,0x6a, 800, 600, 0}, /* 05 */
-       {0x0047,0x11,0x4e,0x00,0x6a, 800, 600, 0}, /* 06 - CRT1CRTC was 0x51 */
-       {0x0047,0x11,0x13,0x00,0x6a, 800, 600, 0}, /* 07 */
-       {0xc85f,0x05,0x00,0x04,0x2e, 640, 480, 0}, /* 08 */
-       {0xc067,0x06,0x02,0x04,0x2e, 640, 480, 0}, /* 09 */
-       {0xc067,0x07,0x02,0x47,0x2e, 640, 480, 0}, /* 0a */
-       {0xc067,0x08,0x03,0x8a,0x2e, 640, 480, 0}, /* 0b */
-       {0xc047,0x09,0x05,0x00,0x2e, 640, 480, 0}, /* 0c */
-       {0xc047,0x0a,0x08,0x00,0x2e, 640, 480, 0}, /* 0d */
-       {0xc047,0x0b,0x0a,0x00,0x2e, 640, 480, 0}, /* 0e */
-       {0xc047,0x0c,0x10,0x00,0x2e, 640, 480, 0}, /* 0f */
-       {0x487f,0x04,0x00,0x00,0x2f, 640, 400, 0}, /* 10 */
-       {0xc04f,0x31,0x01,0x06,0x31, 720, 480, 0}, /* 11 */
-       {0x004f,0x32,0x03,0x06,0x32, 720, 576, 0}, /* 12 */
-       {0x0187,0x15,0x05,0x00,0x37,1024, 768, 0}, /* 13 */
-        {0xc877,0x16,0x09,0x06,0x37,1024, 768, 0}, /* 14 */
-       {0xc067,0x17,0x0b,0x49,0x37,1024, 768, 0}, /* 15 - CRT1CRTC was 0x97 */
-       {0x0267,0x18,0x0d,0x00,0x37,1024, 768, 0}, /* 16 */
-       {0x0047,0x19,0x11,0x8c,0x37,1024, 768, 0}, /* 17 - CRT1CRTC was 0x59 */
-       {0x0047,0x1a,0x52,0x00,0x37,1024, 768, 0}, /* 18 */
-       {0x0007,0x1b,0x16,0x00,0x37,1024, 768, 0}, /* 19 - CRT1CRTC was 0x5b */
-       {0x0387,0x1c,0x4d,0x00,0x3a,1280,1024, 0}, /* 1a - CRT1CRTC was 0x5c */
-       {0x0077,0x1d,0x14,0x07,0x3a,1280,1024, 0}, /* 1b */
-       {0x0047,0x1e,0x17,0x00,0x3a,1280,1024, 0}, /* 1c */
-       {0x0007,0x1f,0x98,0x00,0x3a,1280,1024, 0}, /* 1d */
-       {0x0007,0x20,0x59,0x00,0x3c,1600,1200, 0}, /* 1e - CRT1CRTC was 0x60 */
-       {0x0007,0x21,0x5a,0x00,0x3c,1600,1200, 0}, /* 1f */
-       {0x0007,0x22,0x1b,0x00,0x3c,1600,1200, 0}, /* 20 */
-       {0x0007,0x23,0x1d,0x00,0x3c,1600,1200, 0}, /* 21 - CRT1CRTC was 0x63 */
-       {0x0007,0x24,0x1e,0x00,0x3c,1600,1200, 0}, /* 22 */
-       {0x407f,0x00,0x00,0x00,0x40, 320, 200, 0}, /* 23 */
-       {0xc07f,0x01,0x00,0x04,0x50, 320, 240, 0}, /* 24 */
-       {0x0077,0x02,0x04,0x05,0x51, 400, 300, 0}, /* 25 */
-       {0xc877,0x03,0x09,0x06,0x52, 512, 384, 0}, /* 26 */  /* was c077 */
-       {0x8207,0x25,0x1f,0x00,0x68,1920,1440, 0}, /* 27 */
-       {0x0007,0x26,0x20,0x00,0x6c,2048,1536, 0}, /* 28 */
-       {0x0067,0x27,0x14,0x08,0x6e,1280, 960, 0}, /* 29 - TW: 1280x960-60 */
-       {0x0027,0x45,0x3c,0x08,0x6e,1280, 960, 0}, /* 2a - TW: 1280x960-85 */
-       {0xc077,0x33,0x09,0x06,0x20,1024, 600, 0}, /* 2b */
-       {0xc077,0x34,0x0b,0x06,0x23,1152, 768, 0}, /* 2c */     /* VCLK 0x09 */
-       {0x0057,0x35,0x27,0x08,0x70, 800, 480, 0}, /* 2d */
-       {0x0047,0x36,0x37,0x08,0x70, 800, 480, 0}, /* 2e */
-       {0x0047,0x37,0x08,0x08,0x70, 800, 480, 0}, /* 2f */
-       {0x0057,0x38,0x09,0x09,0x71,1024, 576, 0}, /* 30 */
-       {0x0047,0x39,0x38,0x09,0x71,1024, 576, 0}, /* 31 */
-       {0x0047,0x3a,0x11,0x09,0x71,1024, 576, 0}, /* 32 */
-       {0x0057,0x3b,0x39,0x0a,0x75,1280, 720, 0}, /* 33 */
-       {0x0047,0x3c,0x3a,0x0a,0x75,1280, 720, 0}, /* 34 */
-       {0x0007,0x3d,0x3b,0x0a,0x75,1280, 720, 0}, /* 35 */
-       {0x0047,0x3e,0x34,0x06,0x29,1152, 864, 0}, /* 36 1152x864-75Hz */
-       {0x0047,0x44,0x3a,0x06,0x29,1152, 864, 0}, /* 37 1152x864-85Hz */
-       {0x00c7,0x3f,0x28,0x00,0x39, 848, 480, 0}, /* 38 848x480-38Hzi */
-       {0xc067,0x40,0x3d,0x0b,0x39, 848, 480, 0}, /* 39 848x480-60Hz  */
-       {0x00c7,0x41,0x28,0x00,0x3f, 856, 480, 0}, /* 3a 856x480-38Hzi */
-       {0xc047,0x42,0x28,0x00,0x3f, 856, 480, 0}, /* 3b 856x480-60Hz  */
-       {0x0067,0x43,0x3e,0x0c,0x48,1360, 768, 0}, /* 3c 1360x768-60Hz */
-       {0x0077,0x46,0x3f,0x08,0x55,1280, 768, 0}, /* 3d 1280x768-60Hz */
-       {0x004f,0x47,0x03,0x06,0x5f, 768, 576, 0}, /* 3e 768x576 */
-       {0x0027,0x48,0x13,0x08,0x67,1360,1024, 0}, /* 3f 1360x1024-59Hz (BARCO1366 only) */
-       {0xffff,   0,   0,   0,   0,   0,   0, 0}
-};
-
-typedef struct _SiS_VBModeIDTableStruct
-{
-       UCHAR  ModeID;
-       UCHAR  VB_TVDelayIndex;
-       UCHAR  VB_TVFlickerIndex;
-       UCHAR  VB_TVPhaseIndex;
-       UCHAR  VB_TVYFilterIndex;
-       UCHAR  VB_LCDDelayIndex;
-       UCHAR  _VB_LCDHIndex;
-       UCHAR  _VB_LCDVIndex;
-}SiS_VBModeIDTableStruct;
-
-static const SiS_VBModeIDTableStruct  SiS300_VBModeIDTable[] =
+static const SiS_ExtStruct  SiS300_EModeIDTable[] =
+{
+       {0x6a,0x2212,0x0102,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00,-1},  /* 800x600x? */
+       {0x2e,0x0a1b,0x0101,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08,-1},
+       {0x2f,0x021b,0x0100,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10,-1},  /* 640x400x8 */
+       {0x30,0x2a1b,0x0103,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00,-1},
+       {0x31,0x0a1b,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x8 */
+       {0x32,0x2a1b,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x8 */
+       {0x33,0x0a1d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x16 */
+       {0x34,0x2a1d,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x16 */
+       {0x35,0x0a1f,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x32 */
+       {0x36,0x2a1f,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x32 */
+       {0x37,0x0212,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},  /* 1024x768x? */
+       {0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},  /* 1024x768x8 */
+       {0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},  /* 1280x1024x8 */
+       {0x3c,0x063b,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,-1},
+       {0x3d,0x067d,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,-1},
+       {0x40,0x921c,0x010d,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23,-1},  /* 320x200x15 */
+       {0x41,0x921d,0x010e,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23,-1},  /* 320x200x16 */
+       {0x43,0x0a1c,0x0110,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08,-1},
+       {0x44,0x0a1d,0x0111,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08,-1},
+       {0x46,0x2a1c,0x0113,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00,-1},  /* 800x600x15 */
+       {0x47,0x2a1d,0x0114,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00,-1},  /* 800x600x16 */
+       {0x49,0x0a3c,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
+       {0x4a,0x0a3d,0x0117,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
+       {0x4c,0x0e7c,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},
+       {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},
+       {0x50,0x921b,0x0132,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x24,-1},  /* 320x240x8  */
+       {0x51,0xb21b,0x0133,SIS_RI_400x300,  0x00,0x00,0x00,0x00,0x25,-1},  /* 400x300x8  */
+       {0x52,0x921b,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x26,-1},  /* 512x384x8  */
+       {0x56,0x921d,0x0135,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x24,-1},  /* 320x240x16 */
+       {0x57,0xb21d,0x0136,SIS_RI_400x300,  0x00,0x00,0x00,0x00,0x25,-1},  /* 400x300x16 */
+       {0x58,0x921d,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x26,-1},  /* 512x384x16 */
+       {0x59,0x921b,0x0138,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23,-1},  /* 320x200x8  */
+       {0x5c,0x921f,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x26,-1},  /* 512x384x32 */
+       {0x5d,0x021d,0x0139,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10,-1},  /* 640x400x16 */
+       {0x5e,0x021f,0x0000,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10,-1},  /* 640x400x32 */
+       {0x62,0x0a3f,0x013a,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08,-1},
+       {0x63,0x2a3f,0x013b,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00,-1},  /* 800x600x32 */
+       {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
+       {0x65,0x0eff,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},
+       {0x66,0x06ff,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,-1},
+       {0x68,0x067b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
+       {0x69,0x06fd,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
+       {0x6b,0x07ff,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
+       {0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1},  /* 2048x1536x8 - not in BIOS! */
+       {0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1},  /* 2048x1536x16 - not in BIOS! */
+       {0x70,0x2a1b,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x8 */
+       {0x71,0x0a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x8 */
+       {0x74,0x0a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x16 */
+       {0x75,0x0e3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1},  /* 1280x720x16 */
+       {0x76,0x2a1f,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x32 */
+       {0x77,0x0a3f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x32 */
+       {0x78,0x0eff,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1},  /* 1280x720x32 */
+       {0x79,0x0e3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1},  /* 1280x720x8 */
+       {0x7a,0x2a1d,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x16 */
+       {0x7c,0x0a3b,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1},  /* 1280x960x8 */
+       {0x7d,0x0a7d,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1},  /* 1280x960x16 */
+       {0x7e,0x0aff,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1},  /* 1280x960x32 */
+       {0x20,0x0a1b,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},  /* 1024x600 */
+       {0x21,0x0a3d,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
+       {0x22,0x0a7f,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
+       {0x23,0x0a1b,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},  /* 1152x768 */
+       {0x24,0x0a3d,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
+       {0x25,0x0a7f,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
+       {0x29,0x0e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},  /* 1152x864 */
+       {0x2a,0x0e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
+       {0x2b,0x0e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
+       {0x39,0x2a1b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38,-1},  /* 848x480 */
+       {0x3b,0x2a3d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38,-1},
+       {0x3e,0x2a7f,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38,-1},
+       {0x3f,0x2a1b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a,-1},  /* 856x480 */
+       {0x42,0x2a3d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a,-1},
+       {0x45,0x2a7f,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a,-1},
+       {0x48,0x223b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c,-1},  /* 1360x768 */
+       {0x4b,0x227d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c,-1},
+       {0x4e,0x22ff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c,-1},
+       {0x4f,0x921f,0x0000,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23,-1},  /* 320x200x32 */
+       {0x53,0x921f,0x0000,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x24,-1},  /* 320x240x32 */
+       {0x54,0xb21f,0x0000,SIS_RI_400x300,  0x00,0x00,0x00,0x00,0x25,-1},  /* 400x300x32 */
+       {0x55,0x2e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d,-1},  /* 1280x768   */
+       {0x5a,0x2e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d,-1},
+       {0x5b,0x2eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d,-1},
+       {0x5f,0x2a1b,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e,-1},  /* 768x576x8 */
+       {0x60,0x2a1d,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e,-1},  /* 768x576x16 */
+       {0x61,0x2a1f,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e,-1},  /* 768x576x32 */
+       {0x67,0x2e3b,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f,-1},  /* 1360x1024x8 (BARCO) */
+       {0x6f,0x2e7d,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f,-1},  /* 1360x1024x16 (BARCO) */
+       {0x72,0x2eff,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f,-1},  /* 1360x1024x32 (BARCO) */
+       {0xff,0x0000,0xffff,0,               0x00,0x00,0x00,0x00,0x00}
+};
+
+static const SiS_Ext2Struct  SiS300_RefIndex[] =
+{
+       {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0}, /* 00 */
+       {0x0467,0x0e,0x44,0x05,0x05,0x6a, 800, 600, 0}, /* 01 */
+       {0x0067,0x0f,0x07,0x48,0x00,0x6a, 800, 600, 0}, /* 02 - CRT1CRTC was 0x4f */
+       {0x0067,0x10,0x06,0x8b,0x00,0x6a, 800, 600, 0}, /* 03 */
+       {0x0147,0x11,0x08,0x00,0x00,0x6a, 800, 600, 0}, /* 04 */
+       {0x0147,0x12,0x0c,0x00,0x00,0x6a, 800, 600, 0}, /* 05 */
+       {0x0047,0x11,0x4e,0x00,0x00,0x6a, 800, 600, 0}, /* 06 - CRT1CRTC was 0x51 */
+       {0x0047,0x11,0x13,0x00,0x00,0x6a, 800, 600, 0}, /* 07 */
+       {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0}, /* 08 */
+       {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0}, /* 09 */
+       {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0}, /* 0a */
+       {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0}, /* 0b */
+       {0xc047,0x09,0x05,0x00,0x00,0x2e, 640, 480, 0}, /* 0c */
+       {0xc047,0x0a,0x08,0x00,0x00,0x2e, 640, 480, 0}, /* 0d */
+       {0xc047,0x0b,0x0a,0x00,0x00,0x2e, 640, 480, 0}, /* 0e */
+       {0xc047,0x0c,0x10,0x00,0x00,0x2e, 640, 480, 0}, /* 0f */
+       {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0}, /* 10 */
+       {0xc04f,0x31,0x01,0x06,0x00,0x31, 720, 480, 0}, /* 11 */
+       {0x004f,0x32,0x03,0x06,0x00,0x32, 720, 576, 0}, /* 12 */
+       {0x0187,0x15,0x05,0x00,0x00,0x37,1024, 768, 0}, /* 13 */
+        {0xc877,0x16,0x09,0x06,0x06,0x37,1024, 768, 0}, /* 14 */
+       {0xc067,0x17,0x0b,0x49,0x06,0x37,1024, 768, 0}, /* 15 - CRT1CRTC was 0x97 */
+       {0x0267,0x18,0x0d,0x00,0x06,0x37,1024, 768, 0}, /* 16 */
+       {0x0047,0x19,0x11,0x8c,0x00,0x37,1024, 768, 0}, /* 17 - CRT1CRTC was 0x59 */
+       {0x0047,0x1a,0x52,0x00,0x00,0x37,1024, 768, 0}, /* 18 */
+       {0x0007,0x1b,0x16,0x00,0x00,0x37,1024, 768, 0}, /* 19 - CRT1CRTC was 0x5b */
+       {0x0387,0x1c,0x4d,0x00,0x00,0x3a,1280,1024, 0}, /* 1a - CRT1CRTC was 0x5c */
+       {0x0077,0x1d,0x14,0x07,0x00,0x3a,1280,1024, 0}, /* 1b */
+       {0x0047,0x1e,0x17,0x00,0x00,0x3a,1280,1024, 0}, /* 1c */
+       {0x0007,0x1f,0x98,0x00,0x00,0x3a,1280,1024, 0}, /* 1d */
+       {0x0007,0x20,0x59,0x00,0x00,0x3c,1600,1200, 0}, /* 1e - CRT1CRTC was 0x60 */
+       {0x0007,0x21,0x5a,0x00,0x00,0x3c,1600,1200, 0}, /* 1f */
+       {0x0007,0x22,0x1b,0x00,0x00,0x3c,1600,1200, 0}, /* 20 */
+       {0x0007,0x23,0x1d,0x00,0x00,0x3c,1600,1200, 0}, /* 21 - CRT1CRTC was 0x63 */
+       {0x0007,0x24,0x1e,0x00,0x00,0x3c,1600,1200, 0}, /* 22 */
+       {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0}, /* 23 */
+       {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0}, /* 24 */
+       {0x0077,0x02,0x04,0x05,0x05,0x51, 400, 300, 0}, /* 25 */
+       {0xc877,0x03,0x09,0x06,0x06,0x52, 512, 384, 0}, /* 26 */  /* was c077 */
+       {0x8207,0x25,0x1f,0x00,0x00,0x68,1920,1440, 0}, /* 27 */
+       {0x0007,0x26,0x20,0x00,0x00,0x6c,2048,1536, 0}, /* 28 */
+       {0x0067,0x27,0x14,0x08,0x0a,0x6e,1280, 960, 0}, /* 29 - 1280x960-60 */
+       {0x0027,0x45,0x3c,0x08,0x0a,0x6e,1280, 960, 0}, /* 2a - 1280x960-85 */
+       {0xc077,0x33,0x09,0x06,0x00,0x20,1024, 600, 0}, /* 2b */
+       {0xc077,0x34,0x0b,0x06,0x00,0x23,1152, 768, 0}, /* 2c */        /* VCLK 0x09 */
+       {0x0057,0x35,0x27,0x08,0x00,0x70, 800, 480, 0}, /* 2d */
+       {0x0047,0x36,0x37,0x08,0x00,0x70, 800, 480, 0}, /* 2e */
+       {0x0047,0x37,0x08,0x08,0x00,0x70, 800, 480, 0}, /* 2f */
+       {0x0057,0x38,0x09,0x09,0x00,0x71,1024, 576, 0}, /* 30 */
+       {0x0047,0x39,0x38,0x09,0x00,0x71,1024, 576, 0}, /* 31 */
+       {0x0047,0x3a,0x11,0x09,0x00,0x71,1024, 576, 0}, /* 32 */
+       {0x0057,0x3b,0x39,0x0a,0x00,0x75,1280, 720, 0}, /* 33 */
+       {0x0047,0x3c,0x3a,0x0a,0x00,0x75,1280, 720, 0}, /* 34 */
+       {0x0007,0x3d,0x3b,0x0a,0x00,0x75,1280, 720, 0}, /* 35 */
+       {0x0047,0x3e,0x34,0x06,0x00,0x29,1152, 864, 0}, /* 36 1152x864-75Hz */
+       {0x0047,0x44,0x3a,0x06,0x00,0x29,1152, 864, 0}, /* 37 1152x864-85Hz */
+       {0x00c7,0x3f,0x28,0x00,0x00,0x39, 848, 480, 0}, /* 38 848x480-38Hzi */
+       {0xc067,0x40,0x3d,0x0b,0x0b,0x39, 848, 480, 0}, /* 39 848x480-60Hz  */
+       {0x00c7,0x41,0x28,0x00,0x00,0x3f, 856, 480, 0}, /* 3a 856x480-38Hzi */
+       {0xc047,0x42,0x28,0x00,0x00,0x3f, 856, 480, 0}, /* 3b 856x480-60Hz  */
+       {0x0067,0x43,0x3e,0x0c,0x0b,0x48,1360, 768, 0}, /* 3c 1360x768-60Hz */
+       {0x0077,0x46,0x3f,0x08,0x00,0x55,1280, 768, 0}, /* 3d 1280x768-60Hz */
+       {0x004f,0x47,0x03,0x06,0x00,0x5f, 768, 576, 0}, /* 3e 768x576 */
+       {0x0027,0x48,0x13,0x08,0x08,0x67,1360,1024, 0}, /* 3f 1360x1024-59Hz (BARCO1366 only) */
+       {0xffff,   0,   0,   0,   0,   0,   0,   0, 0}
+};
+
+static const SiS_VBModeStruct SiS300_VBModeIDTable[] =
 {
        {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
@@ -355,12 +302,7 @@ static const SiS_VBModeIDTableStruct  SiS300_VBModeIDTable[] =
        {0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-typedef struct _SiS300_CRT1TableStruct
-{
-       UCHAR CR[17];
-} SiS300_CRT1TableStruct;
-
-static const SiS300_CRT1TableStruct  SiS300_CRT1Table[] =
+static const SiS_CRT1TableStruct  SiS300_CRT1Table[] =
 {
 #if 1
  {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,    /* 0x00 - 320x200 */
@@ -625,13 +567,7 @@ static const SiS300_CRT1TableStruct  SiS300_CRT1Table[] =
    0x00}}   /* 0x48 */
 };
 
-typedef struct _SiS300_MCLKDataStruct
-{
-       UCHAR SR28,SR29,SR2A;
-       USHORT CLOCK;
-} SiS300_MCLKDataStruct;
-
-static const SiS300_MCLKDataStruct  SiS300_MCLKData_630[] =
+static const SiS_MCLKDataStruct  SiS300_MCLKData_630[] =
 {
        { 0x5a,0x64,0x80, 66},
        { 0xb3,0x45,0x80, 83},
@@ -643,7 +579,7 @@ static const SiS300_MCLKDataStruct  SiS300_MCLKData_630[] =
        { 0x37,0x61,0x80,100}
 };
 
-static const SiS300_MCLKDataStruct  SiS300_MCLKData_300[] =
+static const SiS_MCLKDataStruct  SiS300_MCLKData_300[] =
 {
        { 0x68,0x43,0x80,125},
        { 0x68,0x43,0x80,125},
@@ -655,13 +591,7 @@ static const SiS300_MCLKDataStruct  SiS300_MCLKData_300[] =
        { 0x37,0x61,0x80,100}
 };
 
-typedef struct _SiS300_VCLKDataStruct
-{
-       UCHAR SR2B,SR2C;
-       USHORT CLOCK;
-} SiS300_VCLKDataStruct;
-
-static const SiS300_VCLKDataStruct  SiS300_VCLKData[] =
+static SiS_VCLKDataStruct SiS300_VCLKData[] =
 {
        { 0x1b,0xe1, 25}, /* 0x00 */
        { 0x4e,0xe4, 28}, /* 0x01 */
@@ -736,14 +666,7 @@ static const SiS300_VCLKDataStruct  SiS300_VCLKData[] =
        { 0x37,0x61,100}, /* 0x43 */  /* 1280x960 LCD */
        { 0xe3,0x9a,106}, /* 0x44 */  /* 1360x1024 - special for Barco iQ R300 */
        { 0xe2,0x46,135}, /* 0x45 */  /* 1280x1024-75, better clock for VGA2 */
-       { 0xff,0x00,  0}
-};
-
-static const UCHAR  SiS300_ScreenOffset[] =
-{
-       0x14,0x19,0x20,0x28,0x32,0x40,0x50,
-        0x64,0x78,0x80,0x2d,0x35,0x48,0x35,
-       0x55,0x30,0xff
+       {    0,   0,  0}  /* 0x46 custom (will be filled out) */
 };
 
 #ifndef LINUX_XF86
@@ -789,12 +712,7 @@ static const DRAM4Type SiS300_CR40[5];
 static UCHAR SiS300_CR49[2];
 #endif
 
-typedef struct _SiS300_PanelDelayTblStruct
-{
-       UCHAR timer[2];
-} SiS300_PanelDelayTblStruct;
-
-static const SiS300_PanelDelayTblStruct  SiS300_PanelDelayTbl[] =
+static const SiS_PanelDelayTblStruct  SiS300_PanelDelayTbl[] =
 {
        {{0x05,0xaa}},
        {{0x05,0x14}},
@@ -815,7 +733,7 @@ static const SiS300_PanelDelayTblStruct  SiS300_PanelDelayTbl[] =
 };
 
 #if 0
-static const SiS300_PanelDelayTblStruct  SiS300_PanelDelayTblLVDS[] =
+static const SiS_PanelDelayTblStruct  SiS300_PanelDelayTblLVDS[] =
 {
        {{0x05,0xaa}},
        {{0x05,0x14}},
@@ -840,28 +758,18 @@ static const SiS300_PanelDelayTblStruct  SiS300_PanelDelayTblLVDS[] =
 /* SIS VIDEO BRIDGE ----------------------------------------- */
 /**************************************************************/
 
-typedef struct _SiS300_LCDDataStruct
-{
-       USHORT RVBHCMAX;
-       USHORT RVBHCFACT;
-       USHORT VGAHT;
-       USHORT VGAVT;
-       USHORT LCDHT;
-       USHORT LCDVT;
-} SiS300_LCDDataStruct;
-
-static const SiS300_LCDDataStruct  SiS300_StLCD1024x768Data[] =
+static const SiS_LCDDataStruct  SiS300_St2LCD1024x768Data[] =
 {
-       {   66,  31, 992, 510,1320, 816},
-       {   66,  31, 992, 510,1320, 816},
-       {  176,  75, 900, 510,1320, 816},
-       {  176,  75, 900, 510,1320, 816},
-       {   66,  31, 992, 510,1320, 816},
-       {   27,  16,1024, 650,1350, 832},
+       {   62,  25, 800, 546,1344, 806},
+       {   32,  15, 930, 546,1344, 806},
+       {   32,  15, 930, 546,1344, 806},
+       {  104,  45, 945, 496,1344, 806},
+       {   62,  25, 800, 546,1344, 806},
+       {   31,  18,1008, 624,1344, 806},
        {    1,   1,1344, 806,1344, 806}
 };
 
-static const SiS300_LCDDataStruct  SiS300_ExtLCD1024x768Data[] =
+static const SiS_LCDDataStruct  SiS300_ExtLCD1024x768Data[] =
 {
        {   12,   5, 896, 512,1344, 806},
        {   12,   5, 896, 510,1344, 806},
@@ -878,30 +786,19 @@ static const SiS300_LCDDataStruct  SiS300_ExtLCD1024x768Data[] =
        {    1,   1,1344, 806,1344, 806}
 };
 
-static const SiS300_LCDDataStruct  SiS300_St2LCD1024x768Data[] =
-{
-       {   62,  25, 800, 546,1344, 806},
-       {   32,  15, 930, 546,1344, 806},
-       {   32,  15, 930, 546,1344, 806},
-       {  104,  45, 945, 496,1344, 806},
-       {   62,  25, 800, 546,1344, 806},
-       {   31,  18,1008, 624,1344, 806},
-       {    1,   1,1344, 806,1344, 806}
-};
-
-static const SiS300_LCDDataStruct  SiS300_StLCD1280x1024Data[] =
+static const SiS_LCDDataStruct  SiS300_St2LCD1280x1024Data[] =
 {
-       {    4,   1, 880, 510,1650,1088},
-       {    4,   1, 880, 510,1650,1088},
+       {   22,   5, 800, 510,1650,1088},
+       {   22,   5, 800, 510,1650,1088},
        {  176,  45, 900, 510,1650,1088},
        {  176,  45, 900, 510,1650,1088},
-       {    4,   1, 880, 510,1650,1088},
+       {   22,   5, 800, 510,1650,1088},
        {   13,   5,1024, 675,1560,1152},
        {   16,   9,1266, 804,1688,1072},
        {    1,   1,1688,1066,1688,1066}
 };
 
-static const SiS300_LCDDataStruct  SiS300_ExtLCD1280x1024Data[] =
+static const SiS_LCDDataStruct  SiS300_ExtLCD1280x1024Data[] =
 {
        {  211,  60,1024, 501,1688,1066},
        {  211,  60,1024, 508,1688,1066},
@@ -913,74 +810,18 @@ static const SiS300_LCDDataStruct  SiS300_ExtLCD1280x1024Data[] =
        {    1,   1,1688,1066,1688,1066}
 };
 
-static const SiS300_LCDDataStruct  SiS300_St2LCD1280x1024Data[] =
-{
-       {   22,   5, 800, 510,1650,1088},
-       {   22,   5, 800, 510,1650,1088},
-       {  176,  45, 900, 510,1650,1088},
-       {  176,  45, 900, 510,1650,1088},
-       {   22,   5, 800, 510,1650,1088},
-       {   13,   5,1024, 675,1560,1152},
-       {   16,   9,1266, 804,1688,1072},
-       {    1,   1,1688,1066,1688,1066}
-};
-
-static const SiS300_LCDDataStruct  SiS300_NoScaleData1024x768[] =
-{
-       {    1,   1, 800, 449, 800, 449},
-       {    1,   1, 800, 449, 800, 449},
-       {    1,   1, 900, 449, 900, 449},
-       {    1,   1, 900, 449, 900, 449},
-       {    1,   1, 800, 525, 800, 525},
-       {    1,   1,1056, 628,1056, 628},
-       {    1,   1,1344, 806,1344, 806},
-       {    1,   1,1688,1066,1688,1066}
-};
-
-static const SiS300_LCDDataStruct  SiS300_NoScaleData1280x1024[] =  /* TW: Fake */
-{
-       {    1,   1, 800, 449, 800, 449},
-       {    1,   1, 800, 449, 800, 449},
-       {    1,   1, 900, 449, 900, 449},
-       {    1,   1, 900, 449, 900, 449},
-       {    1,   1, 800, 525, 800, 525},
-       {    1,   1,1056, 628,1056, 628},
-       {    1,   1,1344, 806,1344, 806},
-       {    1,   1,1688,1066,1688,1066}
-};
-
-typedef struct _SiS300_Part2PortTblStruct
-{
-       UCHAR CR[12];
-} SiS300_Part2PortTblStruct;
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_1[] =
+static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_1[] =
 { /* VESA Timing */
- {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
- {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
- {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
- {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
 {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
 {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
 {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
 };
 
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_1[] =
-{      /* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_1[] =
-{      /* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_1[] =
-{      /* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] =
+static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] =
 {  /* Non-VESA */
  {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
  {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
@@ -991,38 +832,23 @@ static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] =
  {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}
 };
 
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_2[] =
+static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_3[] =
 {
  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
 };
 
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_2[] =
+static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_1[] =
 {
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_2[] =
-{      /* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_3[] =
-{      /* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_3[] =
-{      /* TW: Temporary data, invalid */
   {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
 };
 
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_3[] =
-{      /* TW: Temporary data, invalid */
 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_2[] =
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
 };
 
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_3[] =
-{      /* TW: Temporary data, invalid */
+static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_3[] =
+{
   {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
 };
 
@@ -1030,15 +856,7 @@ static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_3[] =
 /* LVDS/Chrontel -------------------------------------------- */
 /**************************************************************/
 
-typedef struct _SiS300_LVDSDataStruct
-{
-       USHORT VGAHT;
-       USHORT VGAVT;
-       USHORT LCDHT;
-       USHORT LCDVT;
-} SiS300_LVDSDataStruct;
-
-static const SiS300_LVDSDataStruct  SiS300_CHTVUPALData[] =
+static const SiS_LVDSDataStruct  SiS300_CHTVUPALData[] =
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -1048,7 +866,7 @@ static const SiS300_LVDSDataStruct  SiS300_CHTVUPALData[] =
        { 936, 836, 936, 836}
 };
 
-static const SiS300_LVDSDataStruct  SiS300_CHTVOPALData[] =
+static const SiS_LVDSDataStruct  SiS300_CHTVOPALData[] =
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -1058,7 +876,7 @@ static const SiS300_LVDSDataStruct  SiS300_CHTVOPALData[] =
        { 960, 750, 960, 750}
 };
 
-static const SiS300_LVDSDataStruct  SiS300_CHTVSOPALData[] =
+static const SiS_LVDSDataStruct  SiS300_CHTVSOPALData[] =
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -1068,13 +886,8 @@ static const SiS300_LVDSDataStruct  SiS300_CHTVSOPALData[] =
        { 944, 625, 944, 625}
 };
 
-typedef struct _SiS300_LVDSDesStruct
-{
-       USHORT LCDHDES;
-       USHORT LCDVDES;
-} SiS300_LVDSDesStruct;
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType00_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType00_1[] =
 {
        { 1059, 626 },   /* 2.08 */
        { 1059, 624 },
@@ -1098,7 +911,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType00_1[] =
 #endif
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType01_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType01_1[] =
 {
        {   0,   0 },  /* 2.08 */
        {   0,   0 },
@@ -1122,7 +935,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType01_1[] =
 #endif
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType02_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType02_1[] =
 {
        { 1059, 626 },  /* 2.08 */
        { 1059, 624 },
@@ -1146,7 +959,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType02_1[] =
 #endif
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType03_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType03_1[] =
 {
        {   8, 436},
        {   8, 440},
@@ -1159,7 +972,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType03_1[] =
        {1343, 794}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType04_1[] =    /* 1280x1024 */
+static const SiS_LVDSDesStruct  SiS300_PanelType04_1[] =       /* 1280x1024 */
 {
        {1343, 798},
        {1343, 794},
@@ -1172,7 +985,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType04_1[] =        /* 1280x1024 */
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType05_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType05_1[] =
 {
        {1343, 798},
        {1343, 794},
@@ -1185,7 +998,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType05_1[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType06_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType06_1[] =       /* Clevo Trumpion 1024x768 */
 {
        {1343, 798},
        {1343, 794},
@@ -1198,7 +1011,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType06_1[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType07_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType07_1[] =
 {
        {1343, 798},
        {1343, 794},
@@ -1211,7 +1024,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType07_1[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType08_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType08_1[] =
 {
        {1059, 626},
        {1059, 624},
@@ -1224,7 +1037,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType08_1[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType09_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType09_1[] =
 {
        {1343, 798},
        {1343, 794},
@@ -1237,7 +1050,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType09_1[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType0a_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType0a_1[] =
 {
        {1059, 626},
        {1059, 624},
@@ -1250,7 +1063,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType0a_1[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType0b_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType0b_1[] =
 {
        {1343,   0},
        {1343,   0},
@@ -1263,7 +1076,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType0b_1[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType0c_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType0c_1[] =
 {
        {1343, 798},
        {1343, 794},
@@ -1276,7 +1089,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType0c_1[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType0d_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType0d_1[] =
 {
        {1343, 798},
        {1343, 794},
@@ -1289,7 +1102,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType0d_1[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType0e_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType0e_1[] =
 {
        {1343, 798},
        {1343, 794},
@@ -1302,7 +1115,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType0e_1[] =
        {   0,   0}     /* 1280x960 - not applicable */
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType0f_1[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType0f_1[] =
 {
        {1343, 798},
        {1343, 794},
@@ -1315,7 +1128,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType0f_1[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType00_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType00_2[] =
 {
        {976, 527},
        {976, 502},
@@ -1328,7 +1141,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType00_2[] =
        {  0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType01_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType01_2[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1341,7 +1154,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType01_2[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType02_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType02_2[] =
 {
        {976, 527},
        {976, 502},
@@ -1354,7 +1167,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType02_2[] =
        {  0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType03_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType03_2[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1367,7 +1180,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType03_2[] =
        {1152, 597}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType04_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType04_2[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1380,7 +1193,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType04_2[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType05_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType05_2[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1393,7 +1206,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType05_2[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType06_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType06_2[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1406,7 +1219,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType06_2[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType07_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType07_2[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1419,7 +1232,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType07_2[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType08_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType08_2[] =
 {
        {976, 527},
        {976, 502},
@@ -1432,7 +1245,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType08_2[] =
        {  0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType09_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType09_2[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1445,7 +1258,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType09_2[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType0a_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType0a_2[] =
 {
        {976, 527},
        {976, 502},
@@ -1458,7 +1271,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType0a_2[] =
        {  0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType0b_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType0b_2[] =
 {
        { 1152, 700},
        { 1152, 675},
@@ -1471,7 +1284,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType0b_2[] =
        {    0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType0c_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType0c_2[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1484,7 +1297,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType0c_2[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType0d_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType0d_2[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1497,7 +1310,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType0d_2[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType0e_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType0e_2[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1510,7 +1323,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType0e_2[] =
        {   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType0f_2[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType0f_2[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1523,8 +1336,36 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType0f_2[] =
        {   0,   0}
 };
 
+static const SiS_LVDSDesStruct  SiS300_PanelTypeNS_1[]=
+{
+       { 0,   0},
+       { 0,   0},
+       { 0,   0},
+       { 0,   0},
+       { 0,   0},
+       { 0,   0},
+       { 0, 805},
+       { 0,   0},
+       { 0,   0},
+       { 0,   0}
+};
+
+static const SiS_LVDSDesStruct  SiS300_PanelTypeNS_2[] =
+{
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0}
+};
+
 /* Custom data for Barco iQ R200/300/400 (BIOS 2.00.07) */
-static const SiS300_LVDSDesStruct  SiS300_PanelType04_1a[] =   /* 1280x1024 (1366x1024) */
+static const SiS_LVDSDesStruct  SiS300_PanelType04_1a[] =      /* 1280x1024 (1366x1024) */
 {
        {1330, 798},  /* 320x200 */
        {1330, 794},
@@ -1537,7 +1378,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType04_1a[] =      /* 1280x1024 (1366x
        {   0,   0}   /* 1360x1024          */
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType04_2a[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType04_2a[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1551,7 +1392,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType04_2a[] =
 };
 
 /* Custom data for Barco iQ G200/300/400 (BIOS 2.00.07) */
-static const SiS300_LVDSDesStruct  SiS300_PanelType04_1b[] =   /* 1024x768 */
+static const SiS_LVDSDesStruct  SiS300_PanelType04_1b[] =      /* 1024x768 */
 {
        {1330, 798},  /* 320x200 */
        {1330, 794},
@@ -1562,7 +1403,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType04_1b[] =      /* 1024x768 */
        {   0, 805}   /* 1024x768 / 512x384 */
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType04_2b[] =
+static const SiS_LVDSDesStruct  SiS300_PanelType04_2b[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1575,12 +1416,7 @@ static const SiS300_LVDSDesStruct  SiS300_PanelType04_2b[] =
 
 /* CRT1 CRTC for slave modes */
 
-typedef struct _SiS300_LVDSCRT1DataStruct
-{
-UCHAR CR[15];
-} SiS300_LVDSCRT1DataStruct;
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1[] =
 {
        {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
          0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -1602,7 +1438,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1[] =
          0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1_H[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1_H[] =
 {
        {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
          0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
@@ -1624,7 +1460,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1_H[] =
          0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1[] =
 {
        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
          0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
@@ -1649,7 +1485,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1[] =
          0x01}}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[] =
 {
        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
          0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
@@ -1698,7 +1534,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[] =
 #endif
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1[] =
 {
        {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
          0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
@@ -1723,7 +1559,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1[] =
          0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1_H[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1_H[] =
 {
        {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
          0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
@@ -1748,7 +1584,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1_H[] =
          0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2[] =
 {
        {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
          0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
@@ -1770,7 +1606,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2[] =
          0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2_H[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2_H[] =
 {
        {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
          0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
@@ -1792,7 +1628,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2_H[] =
          0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2[] =
 {
        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
          0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
@@ -1817,7 +1653,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2[] =
          0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2_H[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2_H[] =
 {
        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
          0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
@@ -1842,7 +1678,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2_H[] =
          0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2[] =
 {
        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
          0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
@@ -1867,7 +1703,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2[] =
          0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2_H[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2_H[] =
 {
        {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
          0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
@@ -1892,7 +1728,64 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2_H[] =
          0x01}}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UNTSC[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT1XXXxXXX_1[] =
+{
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+   0x01}},
+ {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
+   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+   0x01}},
+ {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT1XXXxXXX_1_H[] =
+{
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}},
+ {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
+   0x01}},
+ {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+   0x01}}
+};
+
+
+static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1UNTSC[] =
 {
        {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
          0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
@@ -1914,7 +1807,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UNTSC[] =
          0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1ONTSC[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1ONTSC[] =
 {
        {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
          0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
@@ -1936,7 +1829,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1ONTSC[] =
          0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UPAL[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1UPAL[] =
 {
        {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
          0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -1958,7 +1851,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UPAL[] =
          0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1OPAL[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1OPAL[] =
 {
        {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
          0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -1980,7 +1873,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1OPAL[] =
          0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1SOPAL[] =
+static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1SOPAL[] =
 {
        {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
          0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -2002,12 +1895,7 @@ static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1SOPAL[] =
          0x01 }}
 };
 
-typedef struct _SiS300_CHTVRegDataStruct
-{
-       UCHAR Reg[16];
-} SiS300_CHTVRegDataStruct;
-
-static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] =
+static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] =
 {
        {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
        {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
@@ -2017,7 +1905,7 @@ static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] =
        {{0x8d,0xc4,0x00,0x3b,0xfb,0,0,0,0,0,0,0,0,0,0,0}}  /* Mode 24: 800x600 NTSC 7/10 */
 };
 
-static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] =
+static const SiS_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] =
 {
        {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
        {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
@@ -2027,7 +1915,7 @@ static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] =
        {{0x8c,0xb4,0x00,0x32,0xf9,0,0,0,0,0,0,0,0,0,0,0}}  /* Mode 23: 800x600 NTSC 3/4 */
 };
 
-static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] =
+static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] =
 {
        {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
        {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
@@ -2038,7 +1926,7 @@ static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] =
 
 };
 
-static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] =
+static const SiS_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] =
 {
        {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
        {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
@@ -2049,7 +1937,7 @@ static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] =
 
 };
 
-static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_SOPAL[] =
+static const SiS_CHTVRegDataStruct SiS300_CHTVReg_SOPAL[] =
 {
        {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
        {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
index 47dfed7..ffa3945 100644 (file)
@@ -1,4 +1,5 @@
 /* $XFree86$ */
+/* $XdotOrg$ */
 /*
  * Register settings for SiS 315/330 series
  *
  * * 2) Redistributions in binary form must reproduce the above copyright
  * *    notice, this list of conditions and the following disclaimer in the
  * *    documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * *    must display the following acknowledgement: "This product includes
- * *    software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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,
  *
  */
 
-typedef struct _SiS310_StStruct
-{
-       UCHAR St_ModeID;
-       USHORT St_ModeFlag;
-       UCHAR St_StTableIndex;
-       UCHAR St_CRT2CRTC;
-       UCHAR St_ResInfo;
-       UCHAR VB_StTVFlickerIndex;
-       UCHAR VB_StTVEdgeIndex;
-       UCHAR VB_StTVYFilterIndex;
-       UCHAR St_PDC;
-} SiS310_StStruct;
-
-static const SiS310_StStruct SiS310_SModeIDTable[]=
+static const SiS_StStruct SiS310_SModeIDTable[]=
 {
        {0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00, 0x40},
        {0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00, 0x40},
@@ -89,207 +74,192 @@ static const SiS310_StStruct SiS310_SModeIDTable[]=
        {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00, 0x40}
 };
 
-typedef struct _SiS310_ExtStruct
-{
-       UCHAR  Ext_ModeID;
-       USHORT Ext_ModeFlag;
-       UCHAR  Ext_ModeOffset;
-       USHORT Ext_VESAID;
-       UCHAR  Ext_RESINFO;
-       UCHAR  VB_ExtTVFlickerIndex;
-       UCHAR  VB_ExtTVEdgeIndex;
-       UCHAR  VB_ExtTVYFilterIndex;
-       UCHAR  VB_ExtTVYFilterIndexROM661;
-       UCHAR  REFindex;
-} SiS310_ExtStruct;
-
-static const SiS310_ExtStruct  SiS310_EModeIDTable[]=
-{
-       {0x6a,0x2212,0x04,0x0102,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00}, /* 800x600x? */
-       {0x2e,0x0a1b,0x03,0x0101,SIS_RI_640x480,  0x00,0x00,0x05,0x05,0x08}, /* 640x480x8 */
-        {0x2f,0x0a1b,0x03,0x0100,SIS_RI_640x400,  0x00,0x00,0x05,0x05,0x10}, /* 640x400x8 */
-       {0x30,0x2a1b,0x04,0x0103,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00}, /* 800x600x8 */
-        {0x31,0x0a1b,0x0a,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x06,0x11}, /* 720x480x8 */
-       {0x32,0x0a1b,0x0a,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x06,0x12}, /* 720x576x8 */
-       {0x33,0x0a1d,0x0a,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x06,0x11}, /* 720x480x16 */
-       {0x34,0x2a1d,0x0a,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x06,0x12}, /* 720x576x16 */
-       {0x35,0x0a1f,0x0a,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x06,0x11}, /* 720x480x32 */
-       {0x36,0x2a1f,0x0a,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x06,0x12}, /* 720x576x32 */
-       {0x37,0x0212,0x05,0x0104,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13}, /* 1024x768x? */
-       {0x38,0x0a1b,0x05,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13}, /* 1024x768x8 */
-       {0x3a,0x0e3b,0x06,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
-       {0x3c,0x0e3b,0x07,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e}, /* 1600x1200x8 */
-       {0x3d,0x0e7d,0x07,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e}, /* 1600x1200x16 */
-       {0x40,0x9a1c,0x00,0x010d,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25}, /* 320x200x15 */
-       {0x41,0x9a1d,0x00,0x010e,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25}, /* 320x200x16 */
-       {0x43,0x0a1c,0x03,0x0110,SIS_RI_640x480,  0x00,0x00,0x05,0x05,0x08},
-       {0x44,0x0a1d,0x03,0x0111,SIS_RI_640x480,  0x00,0x00,0x05,0x05,0x08}, /* 640x480x16 */
-       {0x46,0x2a1c,0x04,0x0113,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00},
-       {0x47,0x2a1d,0x04,0x0114,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00}, /* 800x600x16 */
-       {0x49,0x0a3c,0x05,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x07,0x13},
-       {0x4a,0x0a3d,0x05,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13}, /* 1024x768x16 */
-       {0x4c,0x0e7c,0x06,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},
-       {0x4d,0x0e7d,0x06,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a}, /* 1280x1024x16 */
-       {0x50,0x9a1b,0x00,0x0132,SIS_RI_320x240,  0x00,0x00,0x04,0x04,0x26}, /* 320x240x8  */
-       {0x51,0xba1b,0x01,0x0133,SIS_RI_400x300,  0x00,0x00,0x07,0x07,0x27}, /* 400x300x8  */
-       {0x52,0xba1b,0x02,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x28}, /* 512x384x8  */
-       {0x56,0x9a1d,0x00,0x0135,SIS_RI_320x240,  0x00,0x00,0x04,0x04,0x26}, /* 320x240x16 */
-       {0x57,0xba1d,0x01,0x0136,SIS_RI_400x300,  0x00,0x00,0x07,0x07,0x27}, /* 400x300x16 */
-       {0x58,0xba1d,0x02,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x28}, /* 512x384x16 */
-       {0x59,0x9a1b,0x00,0x0138,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25}, /* 320x200x8  */
-       {0x5a,0x021b,0x00,0x0138,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x3f}, /* 320x240x8  fstn */
-       {0x5b,0x0a1d,0x00,0x0135,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x3f}, /* 320x240x16 fstn */
-       {0x5c,0xba1f,0x02,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x28}, /* 512x384x32 */
-       {0x5d,0x0a1d,0x03,0x0139,SIS_RI_640x400,  0x00,0x00,0x05,0x07,0x10},
-       {0x5e,0x0a1f,0x03,0x0000,SIS_RI_640x400,  0x00,0x00,0x05,0x07,0x10}, /* 640x400x32 */
-       {0x62,0x0a3f,0x03,0x013a,SIS_RI_640x480,  0x00,0x00,0x05,0x05,0x08}, /* 640x480x32 */
-       {0x63,0x2a3f,0x04,0x013b,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00}, /* 800x600x32 */
-       {0x64,0x0a7f,0x05,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13}, /* 1024x768x32 */
-       {0x65,0x0eff,0x06,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a}, /* 1280x1024x32 */
-       {0x66,0x0eff,0x07,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e}, /* 1600x1200x32 */
-       {0x68,0x067b,0x08,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29}, /* 1920x1440x8 */
-       {0x69,0x06fd,0x08,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29}, /* 1920x1440x16 */
-       {0x6b,0x07ff,0x08,0x0141,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29}, /* 1920x1440x32 */
-       {0x6c,0x067b,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f}, /* 2048x1536x8 */
-       {0x6d,0x06fd,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f}, /* 2048x1536x16 */
-       {0x6e,0x07ff,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f}, /* 2048x1536x32 */
-       {0x70,0x2a1b,0x04,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x07,0x34}, /* 800x480x8 */
-       {0x71,0x0a1b,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37}, /* 1024x576x8 */
-       {0x74,0x0a1d,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37}, /* 1024x576x16 */
-       {0x75,0x0a3d,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a}, /* 1280x720x16 */
-       {0x76,0x2a1f,0x04,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x07,0x34}, /* 800x480x32 */
-       {0x77,0x0a1f,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37}, /* 1024x576x32 */
-       {0x78,0x0a3f,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a}, /* 1280x720x32 */
-       {0x79,0x0a3b,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a}, /* 1280x720x8 */
-       {0x7a,0x2a1d,0x04,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x07,0x34}, /* 800x480x16 */
-       {0x7c,0x0e3b,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d}, /* 1280x960x8 */
-       {0x7d,0x0e7d,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d}, /* 1280x960x16 */
-       {0x7e,0x0eff,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d}, /* 1280x960x32 */
-       {0x23,0x0e3b,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40}, /* 1280x768x8 */
-       {0x24,0x0e7d,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40}, /* 1280x768x16 */
-       {0x25,0x0eff,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40}, /* 1280x768x32 */
-       {0x26,0x0e3b,0x0c,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41}, /* 1400x1050x8 */
-       {0x27,0x0e7d,0x0c,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41}, /* 1400x1050x16 */
-       {0x28,0x0eff,0x0c,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41}, /* 1400x1050x32*/
-       {0x29,0x0e1b,0x0d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43}, /* 1152x864 */
-       {0x2a,0x0e3d,0x0d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43},
-       {0x2b,0x0e7f,0x0d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43},
-       {0x39,0x2a1b,0x0b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45}, /* 848x480 */
-       {0x3b,0x2a3d,0x0b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45},
-       {0x3e,0x2a7f,0x0b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45},
-       {0x3f,0x2a1b,0x0b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47}, /* 856x480 */
-       {0x42,0x2a3d,0x0b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47},
-       {0x45,0x2a7f,0x0b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47},
-       {0x48,0x2a1b,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49}, /* 1360x768 */
-       {0x4b,0x2a3d,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49},
-       {0x4e,0x2a7f,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49},
-       {0x4f,0x9a1f,0x00,0x0000,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25}, /* 320x200x32 */
-       {0x53,0x9a1f,0x00,0x0000,SIS_RI_320x240,  0x00,0x00,0x04,0x04,0x26}, /* 320x240x32 */
-       {0x54,0xba1f,0x01,0x0000,SIS_RI_400x300,  0x00,0x00,0x07,0x07,0x27}, /* 400x300x32 */
-       {0x5f,0x2a1b,0x0f,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a}, /* 768x576x8 */
-       {0x60,0x2a1d,0x0f,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a}, /* 768x576x16 */
-       {0x61,0x2a1f,0x0f,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a}, /* 768x576x32 */
-       {0xff,0x0000,0x00,0x0000,0,               0x00,0x00,0x00,0x00,0x00}
-};
-
-typedef struct _SiS310_Ext2Struct
-{
-       USHORT Ext_InfoFlag;
-       UCHAR  Ext_CRT1CRTC;
-       UCHAR  Ext_CRTVCLK;
-       UCHAR  Ext_CRT2CRTC;
-       UCHAR  ModeID;
-       USHORT XRes;
-       USHORT YRes;
-       UCHAR  Ext_PDC;
-} SiS310_Ext2Struct;
-
-static const SiS310_Ext2Struct SiS310_RefIndex[]=
-{
-       {0x085f,0x0d,0x03,0x05,0x6a, 800, 600, 0x40}, /* 0x0 */
-       {0x0067,0x0e,0x04,0x05,0x6a, 800, 600, 0x40}, /* 0x1 */
-       {0x0067,0x0f,0x08,0x48,0x6a, 800, 600, 0x40}, /* 0x2 */
-       {0x0067,0x10,0x07,0x8b,0x6a, 800, 600, 0x40}, /* 0x3 */
-       {0x0047,0x11,0x0a,0x00,0x6a, 800, 600, 0x40}, /* 0x4 */
-       {0x0047,0x12,0x0d,0x00,0x6a, 800, 600, 0x40}, /* 0x5 */
-       {0x0047,0x13,0x13,0x00,0x6a, 800, 600, 0x20}, /* 0x6 */
-       {0x0107,0x14,0x1c,0x00,0x6a, 800, 600, 0x20}, /* 0x7 */
-       {0xc85f,0x05,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0x8 */
-       {0xc067,0x06,0x02,0x04,0x2e, 640, 480, 0x40}, /* 0x9 */
-       {0xc067,0x07,0x02,0x47,0x2e, 640, 480, 0x40}, /* 0xa */
-       {0xc067,0x08,0x03,0x8a,0x2e, 640, 480, 0x40}, /* 0xb */
-       {0xc047,0x09,0x05,0x00,0x2e, 640, 480, 0x40}, /* 0xc */
-       {0xc047,0x0a,0x09,0x00,0x2e, 640, 480, 0x40}, /* 0xd */
-       {0xc047,0x0b,0x0e,0x00,0x2e, 640, 480, 0x40}, /* 0xe */
-       {0xc047,0x0c,0x15,0x00,0x2e, 640, 480, 0x40}, /* 0xf */
-       {0x487f,0x04,0x00,0x00,0x2f, 640, 400, 0x30}, /* 0x10 */
-       {0xc04f,0x3c,0x01,0x06,0x31, 720, 480, 0x30}, /* 0x11 */
-       {0x004f,0x3d,0x03,0x06,0x32, 720, 576, 0x30}, /* 0x12 */
-       {0x0087,0x15,0x06,0x00,0x37,1024, 768, 0x30}, /* 0x13 */
-       {0xc877,0x16,0x0b,0x06,0x37,1024, 768, 0x20}, /* 0x14 */
-       {0xc067,0x17,0x0f,0x49,0x37,1024, 768, 0x20}, /* 0x15 */
-       {0x0067,0x18,0x11,0x00,0x37,1024, 768, 0x20}, /* 0x16 */
-       {0x0047,0x19,0x16,0x8c,0x37,1024, 768, 0x20}, /* 0x17 */
-       {0x0107,0x1a,0x1b,0x00,0x37,1024, 768, 0x10}, /* 0x18 */
-       {0x0107,0x1b,0x1f,0x00,0x37,1024, 768, 0x10}, /* 0x19 */
-       {0x0087,0x1c,0x11,0x00,0x3a,1280,1024, 0x30}, /* 0x1a */
-       {0x0137,0x1d,0x19,0x07,0x3a,1280,1024, 0x00}, /* 0x1b */
-       {0x0107,0x1e,0x1e,0x00,0x3a,1280,1024, 0x00}, /* 0x1c */
-       {0x0207,0x1f,0x20,0x00,0x3a,1280,1024, 0x00}, /* 0x1d */
-       {0x0227,0x20,0x21,0x09,0x3c,1600,1200, 0x00}, /* 0x1e */
-       {0x0407,0x21,0x22,0x00,0x3c,1600,1200, 0x00}, /* 0x1f */
-       {0x0407,0x22,0x23,0x00,0x3c,1600,1200, 0x00}, /* 0x20 */
-       {0x0407,0x23,0x25,0x00,0x3c,1600,1200, 0x00}, /* 0x21 */
-       {0x0007,0x24,0x26,0x00,0x3c,1600,1200, 0x00}, /* 0x22 */
-       {0x0007,0x25,0x2c,0x00,0x3c,1600,1200, 0x00}, /* 0x23 */
-       {0x0007,0x26,0x34,0x00,0x3c,1600,1200, 0x00}, /* 0x24 */
-       {0x407f,0x00,0x00,0x00,0x40, 320, 200, 0x30}, /* 0x25 */
-       {0xc07f,0x01,0x00,0x04,0x50, 320, 240, 0x30}, /* 0x26 */
-       {0x007f,0x02,0x04,0x05,0x51, 400, 300, 0x30}, /* 0x27 */
-       {0xc077,0x03,0x0b,0x06,0x52, 512, 384, 0x30}, /* 0x28 */
-       {0x8007,0x27,0x27,0x00,0x68,1920,1440, 0x00}, /* 0x29 */
-       {0x4007,0x28,0x29,0x00,0x68,1920,1440, 0x00}, /* 0x2a */
-       {0x4007,0x29,0x2e,0x00,0x68,1920,1440, 0x00}, /* 0x2b */
-       {0x4007,0x2a,0x30,0x00,0x68,1920,1440, 0x00}, /* 0x2c */
-       {0x4007,0x2b,0x35,0x00,0x68,1920,1440, 0x00}, /* 0x2d */
-       {0x4005,0x2c,0x39,0x00,0x68,1920,1440, 0x00}, /* 0x2e */
-       {0x4007,0x2d,0x2b,0x00,0x6c,2048,1536, 0x00}, /* 0x2f */
-       {0x4007,0x2e,0x31,0x00,0x6c,2048,1536, 0x00}, /* 0x30 */
-       {0x4007,0x2f,0x33,0x00,0x6c,2048,1536, 0x00}, /* 0x31 */
-       {0x4007,0x30,0x37,0x00,0x6c,2048,1536, 0x00}, /* 0x32 */
-       {0x4005,0x31,0x38,0x00,0x6c,2048,1536, 0x00}, /* 0x33 */
-       {0x0057,0x32,0x40,0x08,0x70, 800, 480, 0x30}, /* 0x34 */
-       {0x0047,0x33,0x07,0x08,0x70, 800, 480, 0x30}, /* 0x35 */
-       {0x0047,0x34,0x0a,0x08,0x70, 800, 480, 0x30}, /* 0x36 */
-       {0x0057,0x35,0x0b,0x09,0x71,1024, 576, 0x30}, /* 0x37 */
-       {0x0047,0x36,0x11,0x09,0x71,1024, 576, 0x30}, /* 0x38 */
-       {0x0047,0x37,0x16,0x09,0x71,1024, 576, 0x30}, /* 0x39 */
-       {0x0117,0x38,0x19,0x0a,0x75,1280, 720, 0x30}, /* 0x3a */
-       {0x0107,0x39,0x1e,0x0a,0x75,1280, 720, 0x30}, /* 0x3b */
-       {0x0207,0x3a,0x20,0x0a,0x75,1280, 720, 0x30}, /* 0x3c */
-       {0x0127,0x3b,0x19,0x08,0x7c,1280, 960, 0x30}, /* 0x3d */
-       {0x0227,0x4c,0x59,0x08,0x7c,1280, 960, 0x20}, /* 0x3e */
-       {0xc07f,0x4e,0x00,0x06,0x5a, 320, 240, 0x30}, /* 0x3f */    /* FSTN 320x240 */
-        {0x0077,0x42,0x5b,0x08,0x23,1280, 768, 0x30}, /* 0x40 */    /* TW: 0x5b was 0x12 */
-       {0x0127,0x43,0x4d,0x08,0x26,1400,1050, 0x30}, /* 0x41 */
-       {0x0207,0x4b,0x5a,0x08,0x26,1400,1050, 0x30}, /* 0x42 Non-BIOS, new */
-       {0x0107,0x44,0x19,0x00,0x29,1152, 864, 0x30}, /* 0x43 Non-BIOS, new */
-       {0x0107,0x4a,0x1e,0x00,0x29,1152, 864, 0x30}, /* 0x44 Non-BIOS, new */
-       {0x0087,0x45,0x57,0x00,0x39, 848, 480, 0x30}, /* 0x45 848x480-38Hzi - Non-BIOS, new */
-       {0xc067,0x46,0x55,0x0b,0x39, 848, 480, 0x30}, /* 0x46 848x480-60Hz  - Non-BIOS, new */
-       {0x0087,0x47,0x57,0x00,0x3f, 856, 480, 0x30}, /* 0x47 856x480-38Hzi - Non-BIOS, new */
-       {0xc047,0x48,0x57,0x00,0x3f, 856, 480, 0x30}, /* 0x48 856x480-60Hz  - Non-BIOS, new */
-       {0x0067,0x49,0x58,0x0c,0x48,1360, 768, 0x30}, /* 0x49 1360x768-60Hz - Non-BIOS, new */
-       {0x004f,0x4d,0x03,0x06,0x5f, 768, 576, 0x30}, /* 0x4a 768x576 */
-       {0xffff,0x00,0x00,0x00,0x00,   0,   0, 0}
-};
-
-typedef struct _SiS310_CRT1TableStruct
-{
-       UCHAR CR[17];
-} SiS310_CRT1TableStruct;
-
-static const SiS310_CRT1TableStruct SiS310_CRT1Table[]=
+static const SiS_ExtStruct  SiS310_EModeIDTable[]=
+{
+       {0x6a,0x2212,0x0102,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x? */
+       {0x2e,0x0a1b,0x0101,SIS_RI_640x480,  0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x8 */
+        {0x2f,0x0a1b,0x0100,SIS_RI_640x400,  0x00,0x00,0x05,0x05,0x10, 0}, /* 640x400x8 */
+       {0x30,0x2a1b,0x0103,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x8 */
+        {0x31,0x4a1b,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x8 */
+       {0x32,0x4a1b,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x8 */
+       {0x33,0x4a1d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x16 */
+       {0x34,0x6a1d,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x16 */
+       {0x35,0x4a1f,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x32 */
+       {0x36,0x6a1f,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x32 */
+       {0x37,0x0212,0x0104,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x? */
+       {0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x8 */
+       {0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x8 */
+       {0x3c,0x0e3b,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,10}, /* 1600x1200x8 */
+       {0x3d,0x0e7d,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,10}, /* 1600x1200x16 */
+       {0x40,0x9a1c,0x010d,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x15 */
+       {0x41,0x9a1d,0x010e,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x16 */
+       {0x43,0x0a1c,0x0110,SIS_RI_640x480,  0x00,0x00,0x05,0x05,0x08, 2},
+       {0x44,0x0a1d,0x0111,SIS_RI_640x480,  0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x16 */
+       {0x46,0x2a1c,0x0113,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00, 3},
+       {0x47,0x2a1d,0x0114,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x16 */
+       {0x49,0x0a3c,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x07,0x13, 4},
+       {0x4a,0x0a3d,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x16 */
+       {0x4c,0x0e7c,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8},
+       {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x16 */
+       {0x50,0x9a1b,0x0132,SIS_RI_320x240,  0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x8  */
+       {0x51,0xba1b,0x0133,SIS_RI_400x300,  0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x8  */
+       {0x52,0xba1b,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x8  */
+       {0x56,0x9a1d,0x0135,SIS_RI_320x240,  0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x16 */
+       {0x57,0xba1d,0x0136,SIS_RI_400x300,  0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x16 */
+       {0x58,0xba1d,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x16 */
+       {0x59,0x9a1b,0x0138,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x8  */
+       {0x5a,0x021b,0x0138,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x8  fstn */
+       {0x5b,0x0a1d,0x0135,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x16 fstn */
+       {0x5c,0xba1f,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x32 */
+       {0x5d,0x0a1d,0x0139,SIS_RI_640x400,  0x00,0x00,0x05,0x07,0x10, 0},
+       {0x5e,0x0a1f,0x0000,SIS_RI_640x400,  0x00,0x00,0x05,0x07,0x10, 0}, /* 640x400x32 */
+       {0x62,0x0a3f,0x013a,SIS_RI_640x480,  0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x32 */
+       {0x63,0x2a3f,0x013b,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x32 */
+       {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x32 */
+       {0x65,0x0eff,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x32 */
+       {0x66,0x0eff,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,10}, /* 1600x1200x32 */
+       {0x68,0x067b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29,-1}, /* 1920x1440x8 */
+       {0x69,0x06fd,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29,-1}, /* 1920x1440x16 */
+       {0x6b,0x07ff,0x0141,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29,-1}, /* 1920x1440x32 */
+       {0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f,-1}, /* 2048x1536x8 */
+       {0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f,-1}, /* 2048x1536x16 */
+       {0x6e,0x07ff,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f,-1}, /* 2048x1536x32 */
+       {0x70,0x6a1b,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x07,0x34,-1}, /* 800x480x8 */
+       {0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37,-1}, /* 1024x576x8 */
+       {0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37,-1}, /* 1024x576x16 */
+       {0x75,0x0a3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a, 5}, /* 1280x720x16 */
+       {0x76,0x6a1f,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x07,0x34,-1}, /* 800x480x32 */
+       {0x77,0x4a1f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37,-1}, /* 1024x576x32 */
+       {0x78,0x0a3f,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a, 5}, /* 1280x720x32 */
+       {0x79,0x0a3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a, 5}, /* 1280x720x8 */
+       {0x7a,0x6a1d,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x07,0x34,-1}, /* 800x480x16 */
+       {0x7c,0x0e3b,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1280x960x8 */
+       {0x7d,0x0e7d,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1280x960x16 */
+       {0x7e,0x0eff,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1280x960x32 */
+       {0x23,0x0e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x8 */
+       {0x24,0x0e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x16 */
+       {0x25,0x0eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x32 */
+       {0x26,0x0e3b,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x8 */
+       {0x27,0x0e7d,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x16 */
+       {0x28,0x0eff,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x32*/
+       {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1}, /* 1152x864 */
+       {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1},
+       {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1},
+       {0x39,0x6a1b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45,-1}, /* 848x480 */
+       {0x3b,0x6a3d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45,-1},
+       {0x3e,0x6a7f,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45,-1},
+       {0x3f,0x6a1b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47,-1}, /* 856x480 */
+       {0x42,0x6a3d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47,-1},
+       {0x45,0x6a7f,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47,-1},
+       {0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49,-1}, /* 1360x768 */
+       {0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49,-1},
+       {0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49,-1},
+       {0x4f,0x9a1f,0x0000,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x32 */
+       {0x53,0x9a1f,0x0000,SIS_RI_320x240,  0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x32 */
+       {0x54,0xba1f,0x0000,SIS_RI_400x300,  0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x32 */
+       {0x5f,0x6a1b,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a,-1}, /* 768x576 */
+       {0x60,0x6a1d,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a,-1},
+       {0x61,0x6a3f,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a,-1},
+       {0x14,0x0e3b,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4b, 7}, /* 1280x800 */
+       {0x15,0x0e7d,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4b, 7},
+       {0x16,0x0eff,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4b, 7},
+       {0x17,0x0e3b,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4c, 9}, /* 1680x1050 */
+       {0x18,0x0e7d,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4c, 9},
+       {0x19,0x0eff,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4c, 9},
+       {0x2c,0x267b,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4d,-1}, /* 1920x1080(i) */
+       {0x2d,0x26fd,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4d,-1},
+       {0x73,0x27ff,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4d,-1},
+       {0x1d,0x6a1b,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4e,-1}, /* 960x540 */
+       {0x1e,0x6a3d,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4e,-1},
+       {0x1f,0x6a7f,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4e,-1},
+       {0xff,0x0000,0x0000,0,               0x00,0x00,0x00,0x00,0x00,-1}
+};
+
+static const SiS_Ext2Struct SiS310_RefIndex[]=
+{
+       {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0x40}, /* 0x0 */
+       {0x0067,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0x40}, /* 0x1 */
+       {0x0067,0x0f,0x08,0x48,0x05,0x6a, 800, 600, 0x40}, /* 0x2 */
+       {0x0067,0x10,0x07,0x8b,0x05,0x6a, 800, 600, 0x40}, /* 0x3 */
+       {0x0047,0x11,0x0a,0x00,0x05,0x6a, 800, 600, 0x40}, /* 0x4 */
+       {0x0047,0x12,0x0d,0x00,0x05,0x6a, 800, 600, 0x40}, /* 0x5 */
+       {0x0047,0x13,0x13,0x00,0x05,0x6a, 800, 600, 0x20}, /* 0x6 */
+       {0x0107,0x14,0x1c,0x00,0x05,0x6a, 800, 600, 0x20}, /* 0x7 */
+       {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40}, /* 0x8 */
+       {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40}, /* 0x9 */
+       {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40}, /* 0xa */
+       {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40}, /* 0xb */
+       {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xc */
+       {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xd */
+       {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xe */
+       {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xf */
+       {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30}, /* 0x10 */
+       {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30}, /* 0x11 */
+       {0x006f,0x3d,0x03,0x06,0x14,0x32, 720, 576, 0x30}, /* 0x12 */
+       {0x0087,0x15,0x06,0x00,0x06,0x37,1024, 768, 0x30}, /* 0x13 */
+       {0xc877,0x16,0x0b,0x06,0x06,0x37,1024, 768, 0x20}, /* 0x14 */
+       {0xc067,0x17,0x0f,0x49,0x06,0x37,1024, 768, 0x20}, /* 0x15 */
+       {0x0067,0x18,0x11,0x00,0x06,0x37,1024, 768, 0x20}, /* 0x16 */
+       {0x0047,0x19,0x16,0x8c,0x06,0x37,1024, 768, 0x20}, /* 0x17 */
+       {0x0107,0x1a,0x1b,0x00,0x06,0x37,1024, 768, 0x10}, /* 0x18 */
+       {0x0107,0x1b,0x1f,0x00,0x06,0x37,1024, 768, 0x10}, /* 0x19 */
+       {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30}, /* 0x1a */
+       {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00}, /* 0x1b */
+       {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00}, /* 0x1c */
+       {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00}, /* 0x1d */
+       {0x0227,0x20,0x21,0x09,0x09,0x3c,1600,1200, 0x00}, /* 0x1e */
+       {0x0407,0x21,0x22,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x1f */
+       {0x0407,0x22,0x23,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x20 */
+       {0x0407,0x23,0x25,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x21 */
+       {0x0007,0x24,0x26,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x22 */
+       {0x0007,0x25,0x2c,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x23 */
+       {0x0007,0x26,0x34,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x24 */
+       {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0x30}, /* 0x25 */
+       {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30}, /* 0x26 */
+       {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30}, /* 0x27 */
+       {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30}, /* 0x28 */
+       {0x8007,0x27,0x27,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x29 */
+       {0x4007,0x28,0x29,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2a */
+       {0x4007,0x29,0x2e,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2b */
+       {0x4007,0x2a,0x30,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2c */
+       {0x4007,0x2b,0x35,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2d */
+       {0x4005,0x2c,0x39,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2e */
+       {0x4007,0x2d,0x2b,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x2f */
+       {0x4007,0x2e,0x31,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x30 */
+       {0x4007,0x2f,0x33,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x31 */
+       {0x4007,0x30,0x37,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x32 */
+       {0x4005,0x31,0x38,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x33 */
+       {0x0077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x34 */
+       {0x0047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x35 */
+       {0x0047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x36 */
+       {0x0077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x37 */
+       {0x0047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x38 */
+       {0x0047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x39 */
+       {0x1137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3a */
+       {0x1107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3b */
+       {0x1307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3c */
+       {0x0127,0x3b,0x19,0x08,0x0a,0x7c,1280, 960, 0x30}, /* 0x3d */
+       {0x0227,0x4c,0x59,0x08,0x0a,0x7c,1280, 960, 0x20}, /* 0x3e */
+       {0xc07f,0x4e,0x00,0x06,0x04,0x5a, 320, 240, 0x30}, /* 0x3f */    /* FSTN 320x240 */
+        {0x0077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30}, /* 0x40 */    /* 0x5b was 0x12 */
+       {0x0127,0x43,0x4d,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x41 */
+       {0x0207,0x4b,0x5a,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x42 1400x1050-75Hz */
+       {0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x43 1152x864-75Hz  */
+       {0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x44 1152x864-85Hz  */
+       {0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30}, /* 0x45 848x480-38Hzi  */
+       {0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30}, /* 0x46 848x480-60Hz   */
+       {0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x47 856x480-38Hzi  */
+       {0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x48 856x480-60Hz   */
+       {0x0067,0x49,0x58,0x0c,0x1b,0x48,1360, 768, 0x30}, /* 0x49 1360x768-60Hz  */
+       {0x006f,0x4d,0x03,0x06,0x15,0x5f, 768, 576, 0x30}, /* 0x4a 768x576-56Hz   */
+       {0x0067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30}, /* 0x4b 1280x800-60Hz  */
+       {0x0067,0x50,0x5d,0x0c,0x0e,0x17,1680,1050, 0x30}, /* 0x4c 1680x1050-60Hz */
+       {0x0087,0x51,0x69,0x00,0x00,0x2c,1920,1080, 0x30}, /* 0x4d 1920x1080 60Hzi */
+       {0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30}, /* 0x4e 960x540 60Hz */
+       {0xffff,0x00,0x00,0x00,0x00,0x00,   0,   0,    0}
+};
+
+static const SiS_CRT1TableStruct SiS310_CRT1Table[]=
 {
  {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
    0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
@@ -310,7 +280,7 @@ static const SiS310_CRT1TableStruct SiS310_CRT1Table[]=
  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
    0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
    0x00}}, /* 0x5 */
-#endif   
+#endif
  {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e,    /* 0x05 - corrected 640x480-60 */
    0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
    0x00}},
@@ -329,16 +299,16 @@ static const SiS310_CRT1TableStruct SiS310_CRT1Table[]=
    0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
    0x00}}, /* 0x8 */
  {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
-   0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,  /* TW: Corrected VBE */
+   0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,  /* Corrected VBE */
    0x61}}, /* 0x9 */
  {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
    0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
    0x61}}, /* 0xa */
  {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
-   0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05,  /* TW: Corrected VBE */
+   0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05,  /* Corrected VBE */
    0x61}}, /* 0xb */
  {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
-   0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01,  /* TW: Corrected VDE, VBE */
+   0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01,  /* Corrected VDE, VBE */
    0x00}}, /* 0xc */
  {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
    0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
@@ -466,7 +436,7 @@ static const SiS310_CRT1TableStruct SiS310_CRT1Table[]=
  {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
    0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
    0x01}}, /* 0x36 */
- {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,   /* TW: 95 was 15 - illegal HBE! */
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,   /* 95 was 15 - illegal HBE! */
    0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
    0x01}}, /* 0x37 */
  {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
@@ -498,7 +468,7 @@ static const SiS310_CRT1TableStruct SiS310_CRT1Table[]=
  {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,
    0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
    0x00}}, /* 0x3f */
- {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,   /* TW: The following from 650/LVDS BIOS */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,
    0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
    0x01}},  /* 0x40 */
  {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
@@ -510,31 +480,31 @@ static const SiS310_CRT1TableStruct SiS310_CRT1Table[]=
  {{0xe6,0xae,0xae,0x8a,0xbd,0x90,0x3d,0x10,
    0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x00,0x03,
    0x00}},  /* 0x43 */
- {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* New, 1152x864-75, not in BIOS */
+ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* 1152x864-75 */
    0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
    0x01}},  /* 0x44 */
- {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* New, 848x480-38i, not in BIOS */
+ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* 848x480-38i */
    0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
    0x00}},  /* 0x45 */
- {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* New, 848x480-60, not in BIOS */
+ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* 848x480-60 */
    0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
    0x00}},  /* 0x46 */
- {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* New, 856x480-38i, not in BIOS */
+ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* 856x480-38i */
    0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
    0x00}},  /* 0x47 */
- {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* New, 856x480-60, not in BIOS */
+ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* 856x480-60 */
    0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
    0x00}},  /* 0x48 */
- {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* New, 1360x768-60, not in BIOS */
+ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* 1360x768-60 */
    0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
    0x01}},  /* 0x49 */
- {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* New, 1152x864-84, not in any BIOS   */
+ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* 1152x864-84  */
    0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
    0x01}},  /* 0x4a */
- {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, /* New, 1400x1050-75, not in any BIOS  */
+ {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, /* 1400x1050-75  */
    0x1b,0x87,0x19,0x1a,0x41,0x0f,0x00,0x03,
    0x00}},  /* 0x4b */
- {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* New, 1280x960-85, not in any BIOS */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* 1280x960-85 */
    0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
    0x01}},  /* 0x4c */
  {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
@@ -542,16 +512,22 @@ static const SiS310_CRT1TableStruct SiS310_CRT1Table[]=
    0x01}},  /* 0x4d */
  {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* FSTN 320x480, TEMP - possibly invalid */
    0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
-   0x00}}   /* 0x4e */
-};
-
-typedef struct _SiS310_MCLKDataStruct
-{
-       UCHAR SR28,SR29,SR2A;
-       USHORT CLOCK;
-} SiS310_MCLKDataStruct;
-
-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] =
+   0x00}},  /* 0x4e */
+ {{0xcd,0x9f,0x9f,0x91,0xab,0x1c,0x3a,0xff, /* 1280x800-60 */
+   0x20,0x83,0x1f,0x1f,0x3b,0x10,0x00,0x07,
+   0x21}},  /* 0x4f */
+ {{0x15,0xd1,0xd1,0x99,0xe2,0x19,0x3d,0x10, /* 1680x1050-60 */
+   0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x01,0x0c,
+   0x20}},  /* 0x50 */
+ {{0x0e,0xef,0xef,0x92,0xfe,0x03,0x30,0xf0, /* 1920x1080-60i */
+   0x1e,0x83,0x1b,0x1c,0x31,0x00,0x01,0x00,
+   0x61}},  /* 0x51 */
+ {{0x85,0x77,0x77,0x89,0x7d,0x01,0x31,0xf0, /* 960x540-60 */
+   0x1e,0x84,0x1b,0x1c,0x32,0x00,0x00,0x02,
+   0x41}}   /* 0x52 */
+};
+
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_315[] =
 {
        { 0x3b,0x22,0x01,143},
        { 0x5c,0x23,0x01,166},
@@ -563,7 +539,7 @@ static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] =
        { 0x5c,0x23,0x01,166}
 };
 
-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_650[] =
 {
        { 0x5a,0x64,0x82, 66},
        { 0xb3,0x45,0x82, 83},
@@ -575,7 +551,7 @@ static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =
        { 0x37,0x22,0x82,133}
 };
 
-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_330[] =
 {
        { 0x5c,0x23,0x01,166},
        { 0x5c,0x23,0x01,166},
@@ -587,7 +563,7 @@ static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =
        { 0x79,0x06,0x01,250}
 };
 
-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_660[] =  /* TODO */
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_660[] =
 {
        { 0x5c,0x23,0x82,166},
        { 0x5c,0x23,0x82,166},
@@ -599,7 +575,19 @@ static const SiS310_MCLKDataStruct SiS310_MCLKData_0_660[] =  /* TODO */
        { 0x37,0x21,0x82,200}
 };
 
-static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_760[] =
+{
+       { 0x37,0x22,0x82,133},
+       { 0x5c,0x23,0x82,166},
+       { 0x65,0x23,0x82,183},
+       { 0x7c,0x08,0x82,200},
+       { 0x29,0x21,0x82,150},
+       { 0x5c,0x23,0x82,166},
+       { 0x65,0x23,0x82,183},
+       { 0x37,0x21,0x82,200}
+};
+
+static const SiS_MCLKDataStruct SiS310_MCLKData_1[] = /* ECLK */
 {
         { 0x29,0x21,0x82,150},
        { 0x5c,0x23,0x82,166},
@@ -611,13 +599,7 @@ static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =
        { 0x37,0x22,0x82,133}
 };
 
-typedef struct _SiS310_VCLKDataStruct
-{
-       UCHAR SR2B,SR2C;
-       USHORT CLOCK;
-} SiS310_VCLKDataStruct;
-
-static const SiS310_VCLKDataStruct SiS310_VCLKData[]=
+static SiS_VCLKDataStruct SiS310_VCLKData[]=
 {
        { 0x1b,0xe1, 25}, /* 0x00 */
        { 0x4e,0xe4, 28}, /* 0x01 */
@@ -630,7 +612,7 @@ static const SiS310_VCLKDataStruct SiS310_VCLKData[]=
        { 0x53,0xe2, 50}, /* 0x08 */
        { 0x74,0x67, 52}, /* 0x09 */
        { 0x6d,0x66, 56}, /* 0x0a */
-       { 0x5a,0x64, 65}, /* 0x0b */  /* TW: was 6c c3 - WRONG */
+       { 0x5a,0x64, 65}, /* 0x0b */  /* was 6c c3 - WRONG */
        { 0x46,0x44, 67}, /* 0x0c */
        { 0xb1,0x46, 68}, /* 0x0d */
        { 0xd3,0x4a, 72}, /* 0x0e */
@@ -677,49 +659,58 @@ static const SiS310_VCLKDataStruct SiS310_VCLKData[]=
        { 0xea,0x08,340}, /* 0x37 */
        { 0xe8,0x07,376}, /* 0x38 */
        { 0xde,0x06,389}, /* 0x39 */
-       { 0x52,0x2a, 54}, /* 0x3a */  /* 301 TV */
-       { 0x52,0x6a, 27}, /* 0x3b */  /* 301 TV */
-       { 0x62,0x24, 70}, /* 0x3c */  /* 301 TV */
-       { 0x62,0x64, 70}, /* 0x3d */  /* 301 TV */
-       { 0xa8,0x4c, 30}, /* 0x3e */  /* 301 TV */
-       { 0x20,0x26, 33}, /* 0x3f */  /* 301 TV */
+       { 0x52,0x2a, 54}, /* 0x3a 301 TV */
+       { 0x52,0x6a, 27}, /* 0x3b 301 TV */
+       { 0x62,0x24, 70}, /* 0x3c 301 TV */
+       { 0x62,0x64, 70}, /* 0x3d 301 TV */
+       { 0xa8,0x4c, 30}, /* 0x3e 301 TV */
+       { 0x20,0x26, 33}, /* 0x3f 301 TV */
        { 0x31,0xc2, 39}, /* 0x40 */
-       { 0x60,0x36, 30}, /* 0x41 */  /* Chrontel */
-       { 0x40,0x4a, 28}, /* 0x42 */  /* Chrontel */
-       { 0x9f,0x46, 44}, /* 0x43 */  /* Chrontel */
+       { 0x60,0x36, 30}, /* 0x41 Chrontel */
+       { 0x40,0x4a, 28}, /* 0x42 Chrontel */
+       { 0x9f,0x46, 44}, /* 0x43 Chrontel */
        { 0x97,0x2c, 26}, /* 0x44 */
-       { 0x44,0xe4, 25}, /* 0x45 */  /* Chrontel */
-       { 0x7e,0x32, 47}, /* 0x46 */  /* Chrontel */
-       { 0x8a,0x24, 31}, /* 0x47 */  /* Chrontel */
-       { 0x97,0x2c, 26}, /* 0x48 */  /* Chrontel */
+       { 0x44,0xe4, 25}, /* 0x45 Chrontel */
+       { 0x7e,0x32, 47}, /* 0x46 Chrontel */
+       { 0x8a,0x24, 31}, /* 0x47 Chrontel */
+       { 0x97,0x2c, 26}, /* 0x48 Chrontel */
        { 0xce,0x3c, 39}, /* 0x49 */
-       { 0x52,0x4a, 36}, /* 0x4a */  /* Chrontel */
+       { 0x52,0x4a, 36}, /* 0x4a Chrontel */
        { 0x34,0x61, 95}, /* 0x4b */
        { 0x78,0x27,108}, /* 0x4c - was 102 */
-       { 0x66,0x43,123}, /* 0x4d */  /* Modes 0x26-0x28 (1400x1050) */
+       { 0x66,0x43,123}, /* 0x4d Modes 0x26-0x28 (1400x1050) */
        { 0x41,0x4e, 21}, /* 0x4e */
-       { 0xa1,0x4a, 29}, /* 0x4f */  /* Chrontel */
+       { 0xa1,0x4a, 29}, /* 0x4f Chrontel */
        { 0x19,0x42, 42}, /* 0x50 */
-       { 0x54,0x46, 58}, /* 0x51 */  /* Chrontel */
+       { 0x54,0x46, 58}, /* 0x51 Chrontel */
        { 0x25,0x42, 61}, /* 0x52 */
-       { 0x44,0x44, 66}, /* 0x53 */  /* Chrontel */
-       { 0x3a,0x62, 70}, /* 0x54 */  /* Chrontel */
-       { 0x62,0xc6, 34}, /* 0x55 - added for 848x480-60 (not in any BIOS) */
-       { 0x6a,0xc6, 37}, /* 0x56 - added for 848x480-75 (not in any BIOS)    - TEMP */
-       { 0xbf,0xc8, 35}, /* 0x57 - added for 856x480-38i,60 (not in any BIOS) */
-       { 0x30,0x23, 88}, /* 0x58 - added for 1360x768-62 (is 60Hz!) (not in any BIOS) */
-       { 0x52,0x07,149}, /* 0x59 - added for 1280x960-85 (Not in any BIOS) */
-       { 0x56,0x07,156}, /* 0x5a - added for 1400x1050-75 */
-       { 0x70,0x29, 81}  /* 0x5b - added for 1280x768 LCD */
-};
-
-typedef struct _SiS310_VBVCLKDataStruct
-{
-       UCHAR Part4_A,Part4_B;
-       USHORT CLOCK;
-} SiS310_VBVCLKDataStruct;
-
-static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
+       { 0x44,0x44, 66}, /* 0x53 Chrontel */
+       { 0x3a,0x62, 70}, /* 0x54 Chrontel */
+       { 0x62,0xc6, 34}, /* 0x55 848x480-60 */
+       { 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP */
+       { 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60 */
+       { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */
+       { 0x52,0x07,149}, /* 0x59 1280x960-85 */
+       { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
+       { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
+       { 0x45,0x25, 83}, /* 0x5c 1280x800  */
+       { 0x70,0x0a,147}, /* 0x5d 1680x1050 */
+       { 0x70,0x24,162}, /* 0x5e 1600x1200 */
+       { 0x5a,0x64, 65}, /* 0x5f 1280x720 - temp */
+       { 0x63,0x46, 68}, /* 0x60 1280x768_2 */
+       { 0x31,0x42, 79}, /* 0x61 1280x768_3 - temp */
+       {    0,   0,  0}, /* 0x62 - custom (will be filled out at run-time) */
+       { 0x5a,0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */
+       { 0x70,0x28, 90}, /* 0x64 1152x864@60 */
+       { 0x41,0xc4, 32}, /* 0x65 848x480@60 */
+       { 0x5c,0xc6, 32}, /* 0x66 856x480@60 */
+       { 0x76,0xe7, 27}, /* 0x67 720x480@60 */
+       { 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
+       { 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced */
+       { 0x7c,0x6b, 38}  /* 0x6a 960x540@60 */
+};
+
+static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
 {
        { 0x1b,0xe1, 25}, /* 0x00 */
        { 0x4e,0xe4, 28}, /* 0x01 */
@@ -732,7 +723,7 @@ static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
        { 0x53,0x47, 50}, /* 0x08 */
        { 0x74,0x67, 52}, /* 0x09 */
        { 0x6d,0x66, 56}, /* 0x0a */
-       { 0x35,0x62, 65}, /* 0x0b */  /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62  */
+       { 0x35,0x62, 65}, /* 0x0b */  /* Was 0x5a,0x64 - 650/LVDS+301: 35,62  */
        { 0x46,0x44, 67}, /* 0x0c */
        { 0xb1,0x46, 68}, /* 0x0d */
        { 0xd3,0x4a, 72}, /* 0x0e */
@@ -785,47 +776,55 @@ static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
        { 0xea,0x08,340}, /* 0x37 */
        { 0xe8,0x07,376}, /* 0x38 */
        { 0xde,0x06,389}, /* 0x39 */
-       { 0x52,0x2a, 54}, /* 0x3a */  /* 301 TV */
-       { 0x52,0x6a, 27}, /* 0x3b */  /* 301 TV */
-       { 0x62,0x24, 70}, /* 0x3c */  /* 301 TV */
-       { 0x62,0x64, 70}, /* 0x3d */  /* 301 TV */
-       { 0xa8,0x4c, 30}, /* 0x3e */  /* 301 TV */
-       { 0x20,0x26, 33}, /* 0x3f */  /* 301 TV */
+       { 0x52,0x2a, 54}, /* 0x3a 301 TV - start */
+       { 0x52,0x6a, 27}, /* 0x3b 301 TV */
+       { 0x62,0x24, 70}, /* 0x3c 301 TV */
+       { 0x62,0x64, 70}, /* 0x3d 301 TV */
+       { 0xa8,0x4c, 30}, /* 0x3e 301 TV */
+       { 0x20,0x26, 33}, /* 0x3f 301 TV */
        { 0x31,0xc2, 39}, /* 0x40 */
-       { 0x2e,0x48, 25}, /* 0x41 */  /* Replacement for LCD on 315 for index 0 */
-       { 0x24,0x46, 25}, /* 0x42 */  /* Replacement for LCD on 315 for modes 0x01, 0x03, 0x0f, 0x10, 0x12 */
-       { 0x26,0x64, 28}, /* 0x43 */  /* Replacement for LCD on 315 for index 1 */
-       { 0x37,0x64, 40}, /* 0x44 */  /* Replacement for LCD on 315 for index 4 */
-       { 0xa1,0x42,108}, /* 0x45 */  /* 1280x960 LCD */
-       { 0x37,0x61,100}, /* 0x46 */  /* 1280x960 LCD */
+       { 0x2e,0x48, 25}, /* 0x41 Replacement for LCD on 315 for index 0 */
+       { 0x24,0x46, 25}, /* 0x42 Replacement for LCD on 315 for modes 0x01, 0x03, 0x0f, 0x10, 0x12 */
+       { 0x26,0x64, 28}, /* 0x43 Replacement for LCD on 315 for index 1 */
+       { 0x37,0x64, 40}, /* 0x44 Replacement for LCD on 315 for index 4 */
+       { 0xa1,0x42,108}, /* 0x45 1280x960 LCD */
+       { 0x37,0x61,100}, /* 0x46 1280x960 LCD */
        { 0x78,0x27,108}, /* 0x47 */
-       { 0x97,0x2c, 26}, /* 0x48 */  /* UNUSED - Entries from here new, not in any BIOS */
-       { 0xce,0x3c, 39}, /* 0x49 */  /* UNUSED */
-       { 0x52,0x4a, 36}, /* 0x4a */  /* UNUSED */
-       { 0x34,0x61, 95}, /* 0x4b */  /* UNUSED */
-       { 0x78,0x27,108}, /* 0x4c */  /* UNUSED */
-       { 0x66,0x43,123}, /* 0x4d */  /* 1400x1050-60 */
-       { 0x41,0x4e, 21}, /* 0x4e */  /* UNUSED */
-       { 0xa1,0x4a, 29}, /* 0x4f */  /* UNUSED */
-       { 0x19,0x42, 42}, /* 0x50 */  /* UNUSED */
-       { 0x54,0x46, 58}, /* 0x51 */  /* UNUSED */
-       { 0x25,0x42, 61}, /* 0x52 */  /* UNUSED */
-       { 0x44,0x44, 66}, /* 0x53 */  /* UNUSED */
-       { 0x3a,0x62, 70}, /* 0x54 */  /* UNUSED */
-       { 0x62,0xc6, 34}, /* 0x55 */  /* 848x480-60 */
-       { 0x6a,0xc6, 37}, /* 0x56 */  /* 848x480-75 - TEMP, UNUSED */
-       { 0xbf,0xc8, 35}, /* 0x57 */  /* 856x480-38i,60  */
-       { 0x30,0x23, 88}, /* 0x58 */  /* 1360x768-62 (is 60Hz!) TEMP, UNUSED */
-       { 0x52,0x07,149}, /* 0x59 */  /* 1280x960-85  */
-       { 0x56,0x07,156}, /* 0x5a */  /* 1400x1050-75 */
-       { 0x70,0x29, 81}  /* 0x5b */  /* 1280x768 LCD */
-};
-
-static const UCHAR SiS310_ScreenOffset[] =
-{
-        0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,
-       0x78,0x80,0x2d,0x35,0x57,0x48,0x55,0x30,
-       0xff
+       { 0x97,0x2c, 26}, /* 0x48 UNUSED */
+       { 0xce,0x3c, 39}, /* 0x49 UNUSED */
+       { 0x52,0x4a, 36}, /* 0x4a UNUSED */
+       { 0x34,0x61, 95}, /* 0x4b UNUSED */
+       { 0x78,0x27,108}, /* 0x4c UNUSED */
+       { 0x66,0x43,123}, /* 0x4d 1400x1050-60 */
+       { 0x41,0x4e, 21}, /* 0x4e UNUSED */
+       { 0xa1,0x4a, 29}, /* 0x4f UNUSED */
+       { 0x19,0x42, 42}, /* 0x50 UNUSED */
+       { 0x54,0x46, 58}, /* 0x51 UNUSED */
+       { 0x25,0x42, 61}, /* 0x52 UNUSED */
+       { 0x44,0x44, 66}, /* 0x53 UNUSED */
+       { 0x3a,0x62, 70}, /* 0x54 UNUSED */
+       { 0x62,0xc6, 34}, /* 0x55 848x480-60 */
+       { 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP, UNUSED */
+       { 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60  */
+       { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) TEMP, UNUSED */
+       { 0x52,0x07,149}, /* 0x59 1280x960-85  */
+       { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
+       { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
+       { 0x45,0x25, 83}, /* 0x5c 1280x800 LCD - (was 0x9c,0x62, 69 - wrong?) */
+       { 0xbe,0x44,121}, /* 0x5d 1680x1050 LCD */
+       { 0x70,0x24,162}, /* 0x5e 1600x1200 LCD */
+       { 0x52,0x27, 75}, /* 0x5f 1280x720 LCD TMDS + HDTV (correct) */
+       { 0x63,0x46, 68}, /* 0x60 1280x768_2 */
+       { 0x31,0x42, 79}, /* 0x61 1280x768_3 - temp */
+       {    0,   0,  0}, /* 0x62 - custom (will be filled out at run-time) */
+       { 0x5a,0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */
+       { 0x70,0x28, 90}, /* 0x64 1152x864@60 */
+       { 0x41,0xc4, 32}, /* 0x65 848x480@60 */
+       { 0x5c,0xc6, 32}, /* 0x66 856x480@60 */
+       { 0x76,0xe7, 27}, /* 0x67 720x480@60 */
+       { 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
+       { 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced (UNUSED) */
+       { 0x7c,0x6b, 38}  /* 0x6a 960x540@60 */
 };
 
 static const DRAM4Type SiS310_SR15[8] = {
@@ -873,12 +872,7 @@ static const USHORT SiS310_VideoSenseData2 = 0x0174;
 static const USHORT SiS310_YCSenseData2    = 0x016b;
 #endif
 
-typedef struct _SiS310_PanelDelayTblStruct
-{
-       UCHAR timer[2];
-} SiS310_PanelDelayTblStruct;
-
-static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
+static const SiS_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
 {
         {{0x10,0x40}},
        {{0x10,0x40}},
@@ -898,7 +892,7 @@ static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
        {{0x10,0x40}}
 };
 
-static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
+static const SiS_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
 {
        {{0x28,0xc8}},
        {{0x28,0xc8}},
@@ -922,28 +916,18 @@ static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
 /* SIS VIDEO BRIDGE ----------------------------------------- */
 /**************************************************************/
 
-typedef struct _SiS310_LCDDataStruct
-{
-       USHORT RVBHCMAX;
-       USHORT RVBHCFACT;
-       USHORT VGAHT;
-       USHORT VGAVT;
-       USHORT LCDHT;
-       USHORT LCDVT;
-} SiS310_LCDDataStruct;
-
-static const SiS310_LCDDataStruct  SiS310_StLCD1024x768Data[]=
+static const SiS_LCDDataStruct  SiS310_St2LCD1024x768Data[] =
 {
        {   62,  25, 800, 546,1344, 806},
        {   32,  15, 930, 546,1344, 806},
-       {   32,  15, 930, 546,1344, 806},
+        {   62,  25, 800, 546,1344, 806},
        {  104,  45, 945, 496,1344, 806},
        {   62,  25, 800, 546,1344, 806},
        {   31,  18,1008, 624,1344, 806},
        {    1,   1,1344, 806,1344, 806}
 };
 
-static const SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] =   
+static const SiS_LCDDataStruct  SiS310_ExtLCD1024x768Data[] =
 {
        {   42,  25,1536, 419,1344, 806},
        {   48,  25,1536, 369,1344, 806},
@@ -951,28 +935,10 @@ static const SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] =
        {   48,  25,1536, 369,1344, 806},
        {   12,   5, 896, 500,1344, 806},
        {   42,  25,1024, 625,1344, 806},
-       {    1,   1,1344, 806,1344, 806},
-       {   12,   5, 896, 500,1344, 806},
-       {   42,  25,1024, 625,1344, 806},
-       {    1,   1,1344, 806,1344, 806},
-       {   12,   5, 896, 500,1344, 806},
-       {   42,  25,1024, 625,1344, 806},
-       {    1,   1,1344, 806,1344, 806}
-        
-};
-
-static const SiS310_LCDDataStruct  SiS310_St2LCD1024x768Data[] =  
-{
-       {   62,  25, 800, 546,1344, 806},
-       {   32,  15, 930, 546,1344, 806},
-        {   62,  25, 800, 546,1344, 806},    
-       {  104,  45, 945, 496,1344, 806},
-       {   62,  25, 800, 546,1344, 806},
-       {   31,  18,1008, 624,1344, 806},
        {    1,   1,1344, 806,1344, 806}
 };
 
-static const SiS310_LCDDataStruct  SiS310_StLCD1280x1024Data[] =
+static const SiS_LCDDataStruct  SiS310_St2LCD1280x1024Data[] =
 {
        {   22,   5, 800, 510,1650,1088},
        {   22,   5, 800, 510,1650,1088},
@@ -984,7 +950,7 @@ static const SiS310_LCDDataStruct  SiS310_StLCD1280x1024Data[] =
        {    1,   1,1688,1066,1688,1066}
 };
 
-static const SiS310_LCDDataStruct  SiS310_ExtLCD1280x1024Data[] =
+static const SiS_LCDDataStruct  SiS310_ExtLCD1280x1024Data[] =
 {
        {  211,  60,1024, 501,1688,1066},
        {  211,  60,1024, 508,1688,1066},
@@ -993,53 +959,10 @@ static const SiS310_LCDDataStruct  SiS310_ExtLCD1280x1024Data[] =
        {  211,  60,1024, 500,1688,1066},
        {  211,  75,1024, 625,1688,1066},
        {  211, 120,1280, 798,1688,1066},
-       {    1,   1,1688,1066,1688,1066},
-       {    1,   1,1800,1000,1688,1066}  /* 1280x960 - does not work, use panel scaler instead */
-};
-
-static const SiS310_LCDDataStruct  SiS310_St2LCD1280x1024Data[] =
-{
-       {   22,   5, 800, 510,1650,1088},
-       {   22,   5, 800, 510,1650,1088},
-       {  176,  45, 900, 510,1650,1088},
-       {  176,  45, 900, 510,1650,1088},
-       {   22,   5, 800, 510,1650,1088},
-       {   13,   5,1024, 675,1560,1152},
-       {   16,   9,1266, 804,1688,1072},
        {    1,   1,1688,1066,1688,1066}
 };
 
-static const SiS310_LCDDataStruct  SiS310_NoScaleData1024x768[] =  
-{
-        {    1,   1,1344, 806,1344, 806},
-       {    1,   1,1344, 806,1344, 806},
-       {    1,   1,1344, 806,1344, 806},
-       {    1,   1,1344, 806,1344, 806},  /* 640x400 - does not work */
-       {    1,   1,1344, 806,1344, 806},  /* 640x480 - does not work */
-       {    1,   1,1344, 806,1344, 806},
-       {    1,   1,1344, 806,1344, 806},
-       {    1,   1,1344, 806,1344, 806}
-};
-
-static const SiS310_LCDDataStruct  SiS310_NoScaleData1280x1024[] =
-{
-        {    1,   1,1688,1066,1688,1066},
-       {    1,   1,1688,1066,1688,1066},
-       {    1,   1,1688,1066,1688,1066},
-       {    1,   1,1688,1066,1688,1066},
-       {    1,   1,1688,1066,1688,1066},
-       {    1,   1,1688,1066,1688,1066},
-       {    1,   1,1688,1066,1688,1066},
-       {    1,   1,1688,1066,1688,1066},
-       {    1,   1,1688,1066,1688,1066}
-};
-
-typedef struct _SiS310_Part2PortTblStruct
-{
-       UCHAR CR[12];
-} SiS310_Part2PortTblStruct;
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] =
+static const SiS_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] =
 {
  {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
  {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
@@ -1047,646 +970,37 @@ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] =
  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
  {{0x38,0x13,0x16,0x0c,0xe6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
  {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
+ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
 };
 
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] =
-{
- {{0x25,0x12,0x51,0x6e,0x48,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
- {{0x2c,0x12,0x38,0x55,0x2f,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
- {{0x25,0x12,0x51,0x6e,0x48,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
- {{0x2c,0x12,0x38,0x55,0x2f,0xc1,0x35,0xb1,0x47,0xe9,0x71,0x33}},
- {{0x2d,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
- {{0x29,0x12,0xb5,0xd2,0xac,0xe9,0x35,0xd9,0x47,0x11,0x99,0x33}},
- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},  /* others  */
-/* 0x36,0x13,0x02,0x25,0xff,0x03,0x45,0x09,0x07,0xf9,0x00,0x24        my      */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
+/* *** LCDA *** */
 
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
-{
-#if 1   /* Data from 650/301LVx 1.10.6s and others */
- {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x25,0x13,0xc9,0x24,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x25,0x13,0xc9,0x25,0xff,0xf9,0x45,0x09,0x07,0xf9,0x09,0x24}}
+#if 0
+static const SiS_LVDSDataStruct  SiS_LCDA1600x1200Data_1[]=
+{ /* Clevo, 651+301C */
+       {1200, 450, 2048,1250},
+       {1200, 400, 2048,1250},
+       {1280, 450, 2048,1250},
+       {1280, 400, 2048,1250},
+       {1200, 530, 2048,1250},
+       {1360, 650, 2048,1250},
+       {1584, 818, 2048,1250},
+       {1688,1066, 2048,1250},
+       {1688,1066, 2048,1250},
+#if 0
+       {2048,1250, 2048,1250}   /* this should be correct */
 #endif
-#if 0    /* Data from my 301LV */
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},   /* TEST */
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}
+#if 1
+       {2160,1250, 2048,1250}   /* ? */
 #endif
 };
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] =
-{ /* Acer; BIOS data invalid, last row taken from _3 */
- {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x2C,0x12,0x38,0x55,0x2F,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x2C,0x12,0x38,0x55,0x2F,0xC1,0x35,0xB1,0x47,0xE9,0x71,0x33}},
- {{0x2D,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x29,0x12,0xB5,0xD2,0xAC,0xE9,0x35,0xD9,0x47,0x11,0x99,0x33}},
- {{0x36,0x13,0x02,0x25,0xFF,0x03,0x45,0x09,0x07,0xF9,0x00,0x24}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_2[] =
-{ /* Acer */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-/*   1     2    4    5    6   1c   1d   1f   20   21   23   25   */
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
-{ /* Acer */
- {{0x31,0x1B,0xC4,0xDA,0xB0,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x34,0x1B,0x9F,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x3E,0x1B,0xCF,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] =
-{
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_2[] =
-{
- {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x33,0x13,0x01,0x0d,0xfd,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x3f,0x1b,0x3d,0x49,0x39,0x54,0x23,0xc0,0x27,0x66,0x30,0x42}},
- {{0x33,0x1b,0x91,0x9d,0x8d,0x8c,0x23,0xf8,0x27,0x9e,0x68,0x42}},
- {{0x43,0x24,0x11,0x1d,0x0d,0xcc,0x23,0x38,0x37,0xde,0xa8,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_3[] =
-{
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_1[] =
-{
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_2[] =
-{
- {{0x32,0x1B,0x2C,0x52,0x20,0x80,0x20,0x52,0x30,0xA3,0x3A,0x02}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x32,0x1B,0x2C,0x52,0x20,0x80,0x20,0x52,0x30,0xA3,0x3A,0x02}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x3A,0x1B,0x54,0x7A,0x48,0x80,0x24,0x52,0x30,0xA3,0x3A,0x02}},
- {{0x36,0x1B,0x90,0xB6,0x84,0xA8,0x24,0x7A,0x30,0xCB,0x62,0x02}},
- {{0x3A,0x1C,0xE4,0x0A,0xD8,0xE0,0x24,0xB2,0x30,0x03,0x9A,0x02}},
- {{0x4A,0x24,0x64,0x8A,0x58,0x20,0x34,0xF2,0x30,0x43,0xDA,0x52}},
- {{0x47,0x24,0x71,0x97,0x65,0x3E,0x34,0x10,0x40,0x61,0xF8,0x02}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_3[] =
-{
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
-};
-
-/* CRT1 CRTC for LCDA */
-
-typedef struct _SiS310_LCDACRT1DataStruct
-{
-       UCHAR CR[17];
-}SiS310_LCDACRT1DataStruct;
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1[]=
-{
- {{0x73,0x4f,0x4f,0x97,0x59,0x84,0xb4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x4f,0x97,0x59,0x84,0x82,0x1f,
-   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x4f,0x97,0x59,0x84,0xb4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x4f,0x97,0x59,0x84,0x82,0x1f,
-   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x4f,0x97,0x59,0x84,0x04,0x3e,
-   0xE2,0x89,0xdf,0xdf,0x05,0x00,0x00,0x05,
-   0x00}},
- {{0x87,0x63,0x63,0x8B,0x6D,0x18,0x7c,0xf0,
-   0x5A,0x81,0x57,0x57,0x7D,0x00,0x00,0x06,
-   0x01}},
- {{0xA3,0x7f,0x7f,0x87,0x89,0x94,0x24,0xf5,
-   0x02,0x89,0xff,0xff,0x25,0x10,0x00,0x02,
-   0x01}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1_H[]=
-{
- {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0xb4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0x82,0x1f,
-   0x60,0x87,0x5D,0x5D,0x83,0x10,0x00,0x05,
-   0x00}},
- {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0xb4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0x82,0x1f,
-   0x60,0x87,0x5D,0x5D,0x83,0x10,0x00,0x05,
-   0x00}},
- {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0x04,0x3e,
-   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
-   0x00}},
- {{0x55,0x31,0x31,0x99,0x3b,0x06,0x7c,0xf0,
-   0x5A,0x81,0x57,0x57,0x7D,0x00,0x00,0x01,
-   0x01}},
- {{0x63,0x3F,0x3F,0x87,0x49,0x94,0x24,0xF5,
-   0x02,0x89,0xFF,0xFF,0x25,0x10,0x00,0x01,
-   0x01}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2[]=
-{
- {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
-   0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
-   0x31,0x88,0x5d,0xc2,0xc1,0x20,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
-   0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
-   0x31,0x88,0x5d,0xc2,0xc1,0x20,0x00,0x06,
-   0x01}},
- {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xb3,
-   0x72,0x89,0xdf,0x03,0x02,0x30,0x00,0x06,
-   0x01}},
- {{0xa3,0x63,0x63,0x98,0x78,0x19,0x24,0xf1,
-   0xbb,0x82,0x57,0x57,0x25,0x10,0x00,0x02,
-   0x01}},
- {{0xa3,0x7f,0x7f,0x87,0x89,0x94,0x24,0xf5,
-   0x02,0x89,0xff,0xff,0x25,0x10,0x00,0x02,
-   0x01}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2_H[]=
-{
- {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xbb,
-   0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xbb,
-   0x31,0x88,0x5d,0xc2,0xc1,0x20,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xbb,
-   0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xbb,
-   0x31,0x88,0x5d,0xc2,0xc1,0x20,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xb3,
-   0x72,0x89,0xdf,0x03,0x02,0x30,0x00,0x01,
-   0x01 }},
- {{0x71,0x31,0x31,0x98,0x46,0x17,0x24,0xf1,
-   0xbb,0x82,0x57,0x57,0x25,0x10,0x00,0x02,
-   0x01 }},
- {{0x63,0x3f,0x3f,0x87,0x4c,0x97,0x24,0xf5,
-   0x0f,0x86,0xff,0xff,0x25,0x30,0x00,0x01,
-   0x01 }}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1[]=
-{ /* Acer */
- {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0xb8,0x1f,
-   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0x86,0x1f,
-   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0xb8,0x1f,
-   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0x86,0x1f,
-   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0x08,0x3e,
-   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x06,
-   0x00}},
- {{0x92,0x63,0x63,0x96,0x6c,0x18,0x80,0xf0,
-   0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x06,
-   0x01}},
- {{0xae,0x7f,0x7f,0x92,0x88,0x94,0x28,0xf5,
-   0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x02,
-   0x01}},
- {{0xce,0x9f,0x9f,0x92,0xa8,0x14,0x28,0x5a,
-   0x00,0x84,0xff,0xff,0x29,0x01,0x00,0x07,
-   0x01}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1_H[]=
-{  /* Acer */
- {{0x56,0x27,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
-   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x56,0x27,0x27,0x9a,0x31,0x1c,0x86,0x1f,
-   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x05,
-   0x00}},
- {{0x56,0x27,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
-   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x56,0x27,0x27,0x9a,0x31,0x1c,0x86,0x1f,
-   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x05,
-   0x01}},
- {{0x56,0x27,0x27,0x9a,0x31,0x1c,0x08,0x3e,
-   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x05,
-   0x00}},
- {{0x60,0x31,0x31,0x84,0x3a,0x86,0x80,0xf0,
-   0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x01,
-   0x01}},
- {{0x6e,0x3f,0x3f,0x92,0x48,0x94,0x28,0xf5,
-   0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x01,
-   0x01}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2[]=
-{  /* Illegal data in BIOS (Acer, Compaq) */
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x63,0x63,0x87,0x78,0x89,0x24,0xf1,
-   0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x02,
-   0x01}},
- {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
-   0x01}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2_H[]=
-{  /* Illegal data in BIOS (Acer, Compaq) */
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x31,0x31,0x93,0x3e,0x86,0x24,0xf1,
-   0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x01,
-   0x01 }},
- {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
-   0x01 }}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1[]=
-{
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
-   0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
-   0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
-   0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
-   0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0xee,0x1f,
-   0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
-   0x00}},
- {{0x83,0x63,0x63,0x87,0x68,0x16,0x66,0xf0,
-   0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x06,
-   0x01}},
- {{0x9f,0x7f,0x7f,0x83,0x84,0x92,0x0e,0xf5,
-   0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x02,
-   0x01}},
- {{0xbf,0x9f,0x9f,0x83,0xa4,0x12,0x0e,0x5a,
-   0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x07,
-   0x01}},
- {{0xce,0xae,0xae,0x92,0xb3,0x01,0x28,0x10,
-   0x1a,0x80,0x19,0x19,0x29,0x0f,0x00,0x03,
-   0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1_H[]=
-{
-  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
-    0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
-    0x00}},
-  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-    0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
-    0x00}},
-  {{0x47,0x27,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
-    0x92,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
-    0x00}},
-  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-    0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
-    0x00}},
-  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
-    0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
-    0x00}},
-  {{0x51,0x31,0x31,0x95,0x36,0x04,0x66,0xf0,
-    0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x01,
-    0x01}},
-  {{0x5f,0x3f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
-    0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x01,
-    0x01}},
-  {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
-    0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x05,
-    0x01}},
-  {{0x76,0x56,0x56,0x9a,0x5b,0x89,0x28,0x10,
-    0x1c,0x80,0x19,0x19,0x29,0x0b,0x00,0x05,
-    0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2[]=
-{
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
-   0x00}},
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
-   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03,
-   0x01}},
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
-   0x00}},
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
-   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03,
-   0x00}},
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9e,
-   0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x03,
-   0x00}},
- {{0xce,0x63,0x63,0x92,0x96,0x04,0x28,0xd4,
-   0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x07,
-   0x01}},
- {{0xce,0x7f,0x7f,0x92,0xa4,0x12,0x28,0xd4,
-   0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x07,
-   0x01}},
- {{0xce,0x9f,0x9f,0x92,0xb4,0x02,0x28,0x5a,
-   0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x03,
-   0x01}},
- {{0xce,0xae,0xae,0x92,0xbc,0x0a,0x28,0x10,
-   0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x03,
-   0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2_H[]=
-{
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
-   0x00}},
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
-   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06,
-   0x00}},
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
-   0x00}},
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
-   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06,
-   0x00}},
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9e,
-   0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x06,
-   0x00}},
- {{0x9c,0x31,0x31,0x80,0x64,0x92,0x28,0xd4,
-   0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x06,
-   0x01}},
- {{0x8e,0x3f,0x3f,0x92,0x64,0x12,0x28,0xd4,
-   0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x06,
-   0x01}},
- {{0x7e,0x4f,0x4f,0x82,0x64,0x12,0x28,0x5a,
-   0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x06,
-   0x01}},
- {{0x76,0x56,0x56,0x9a,0x64,0x92,0x28,0x10,
-   0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x05,
-   0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_1[]=
-{
- {{0x83,0x4F,0x4F,0x87,0x51,0x09,0xC0,0x1F,
-   0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x06,
-   0x00}},
- {{0x83,0x4F,0x4F,0x87,0x51,0x09,0x8E,0x1F,
-   0x5E,0x82,0x5D,0x5D,0x8F,0x10,0x00,0x06,
-   0x00}},
- {{0x83,0x4F,0x4F,0x87,0x51,0x09,0xC0,0x1F,
-   0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x06,
-   0x00}},
- {{0x83,0x4F,0x4F,0x87,0x51,0x09,0x8E,0x1F,
-   0x5E,0x82,0x5D,0x5D,0x8F,0x10,0x00,0x06,
-   0x00}},
- {{0x83,0x4F,0x4F,0x87,0x51,0x09,0x10,0x3E,
-   0xE0,0x84,0xDF,0xDF,0x11,0x00,0x00,0x06,
-   0x00}},
- {{0x97,0x63,0x63,0x9B,0x65,0x1D,0x88,0xF0,
-   0x58,0x8C,0x57,0x57,0x89,0x20,0x00,0x06,
-   0x01}},
- {{0xB3,0x7F,0x7F,0x97,0x81,0x99,0x30,0xF5,
-   0x00,0x84,0xFF,0xFF,0x31,0x10,0x00,0x02,
-   0x01}},
- {{0xD3,0x9F,0x9F,0x97,0xA1,0x19,0x30,0x5A,
-   0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x07,
-   0x01}},
- {{0xE2,0xAE,0xAE,0x86,0xB0,0x88,0x4A,0x10,
-   0x1A,0x8E,0x19,0x19,0x4B,0x2F,0x00,0x03,
-   0x00}},
- {{0xFB,0xC7,0xC7,0x9F,0xC9,0x81,0xE0,0x10,
-   0xB0,0x84,0xAF,0xAF,0xE1,0x2F,0x00,0x07,
-   0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_1_H[]=
-{
- {{0x69,0x27,0x27,0x8D,0x30,0x88,0xC0,0x1F,
-   0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x01,
-   0x00}},
- {{0x69,0x27,0x27,0x8D,0x30,0x88,0x8E,0x1F,
-   0x5E,0x82,0x5D,0x5D,0x87,0x10,0x00,0x01,
-   0x00}},
- {{0x69,0x27,0x27,0x8D,0x30,0x88,0xC0,0x1F,
-   0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x01,
-   0x00}},
- {{0x69,0x27,0x27,0x8D,0x30,0x88,0x8E,0x1F,
-   0x5E,0x82,0x5D,0x5D,0x87,0x10,0x00,0x01,
-   0x00}},
- {{0x69,0x27,0x27,0x8D,0x30,0x88,0x10,0x3E,
-   0xE0,0x84,0xDF,0xDF,0x11,0x00,0x00,0x01,
-   0x00}},
- {{0x73,0x31,0x31,0x97,0x3A,0x92,0x88,0xF0,
-   0x58,0x8C,0x57,0x57,0x89,0x20,0x00,0x01,
-   0x01}},
- {{0x81,0x3F,0x3F,0x85,0x48,0x00,0x30,0xF5,
-   0x00,0x84,0xFF,0xFF,0x31,0x10,0x00,0x06,
-   0x01}},
- {{0x91,0x4F,0x4F,0x95,0x58,0x10,0x30,0x5A,
-   0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x06,
-   0x01}},
- {{0xD4,0x9F,0x9F,0x98,0xA8,0x00,0x30,0x5A,
-   0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x03,
-   0x01}},
- {{0xA5,0x63,0x63,0x89,0x6C,0x84,0xE0,0x10,
-   0xB0,0x84,0xAF,0xAF,0xE1,0x2F,0x00,0x02,
-   0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_2[]=
-{
- {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
-   0x37,0x8B,0x8F,0x8F,0xE1,0x21,0x01,0x04,
-   0x00}},
- {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
-   0x1E,0x82,0x5D,0x5D,0xE1,0x01,0x01,0x04,
-   0x00}},
- {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
-   0x37,0x8B,0x8F,0x8F,0xE1,0x21,0x01,0x04,
-   0x00}},
- {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
-   0x1E,0x82,0x5D,0x5D,0xE1,0x01,0x01,0x04,
-   0x00}},
- {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
-   0x5F,0x83,0xDF,0xDF,0xE1,0x01,0x01,0x04,
-   0x00}},
- {{0x09,0x63,0x63,0x8D,0xAD,0x05,0xE0,0xD4,
-   0x9B,0x8F,0x57,0x57,0xE1,0x21,0x01,0x00,
-   0x01}},
- {{0x09,0x7F,0x7F,0x8D,0xBB,0x13,0xE0,0xD4,
-   0xEF,0x83,0xFF,0xFF,0xE1,0x21,0x01,0x00,
-   0x01}},
- {{0x09,0x9F,0x9F,0x8D,0xCB,0x03,0xE0,0x5A,
-   0x6F,0x83,0xFF,0xFF,0xE1,0x29,0x01,0x04,
-   0x01}},
- {{0xD4,0x9F,0x9F,0x98,0xA8,0x00,0x30,0x5A,
-   0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x03,
-   0x01}},
- {{0x09,0xC7,0xC7,0x8D,0xDF,0x17,0xE0,0x10,
-   0xC7,0x8B,0xAF,0xAF,0xE1,0x0F,0x01,0x04,
-   0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_2_H[]=
-{
- {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
-   0x37,0x8B,0x8F,0x8F,0xE1,0x21,0x00,0x03,
-   0x00}},
- {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
-   0x1E,0x82,0x5D,0x5D,0xE1,0x01,0x00,0x03,
-   0x00}},
- {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
-   0x37,0x8B,0x8F,0x8F,0xE1,0x21,0x00,0x03,
-   0x00}},
- {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
-   0x1E,0x82,0x5D,0x5D,0xE1,0x01,0x00,0x03,
-   0x00}},
- {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
-   0x5F,0x83,0xDF,0xDF,0xE1,0x01,0x00,0x03,
-   0x00}},
- {{0xD7,0x31,0x31,0x9B,0x7B,0x13,0xE0,0xD4,
-   0x9B,0x8F,0x57,0x57,0xE1,0x21,0x00,0x03,
-   0x01}},
- {{0xC9,0x3F,0x3F,0x8D,0x7B,0x13,0xE0,0xD4,
-   0xEF,0x83,0xFF,0xFF,0xE1,0x21,0x00,0x03,
-   0x01}},
- {{0xB9,0x4F,0x4F,0x9D,0x7B,0x93,0xE0,0x5A,
-   0x6F,0x83,0xFF,0xFF,0xE1,0x29,0x00,0x02,
-   0x01}},
- {{0xD4,0x9F,0x9F,0x98,0xA8,0x00,0x30,0x5A,
-   0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x03,
-   0x01}},
- {{0xA5,0x63,0x63,0x89,0x7B,0x93,0xE0,0x10,
-   0xC7,0x8B,0xAF,0xAF,0xE1,0x0F,0x00,0x02,
-   0x00}}
-};
-
+#endif
 
 /**************************************************************/
 /* LVDS, CHRONTEL ------------------------------------------- */
 /**************************************************************/
 
-typedef struct _SiS310_LVDSDataStruct
-{
-       USHORT VGAHT;
-       USHORT VGAVT;
-       USHORT LCDHT;
-       USHORT LCDVT;
-} SiS310_LVDSDataStruct;
-
-static const SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=
+static const SiS_LVDSDataStruct  SiS310_CHTVUPALData[]=
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -1697,7 +1011,7 @@ static const SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=
        {1400,1000,1400,1000}
 };
 
-static const SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]=
+static const SiS_LVDSDataStruct  SiS310_CHTVOPALData[]=
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -1708,7 +1022,7 @@ static const SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]=
         {1400, 875,1400, 875}
 };
 
-static const SiS310_LVDSDataStruct  SiS310_CHTVUPALMData[]=
+static const SiS_LVDSDataStruct  SiS310_CHTVUPALMData[]=
 {
        { 840, 600, 840, 600},
        { 840, 600, 840, 600},
@@ -1719,7 +1033,7 @@ static const SiS310_LVDSDataStruct  SiS310_CHTVUPALMData[]=
         {1160, 945,1160, 945}
 };
 
-static const SiS310_LVDSDataStruct  SiS310_CHTVOPALMData[]=
+static const SiS_LVDSDataStruct  SiS310_CHTVOPALMData[]=
 {
        { 840, 525, 840, 525},
        { 840, 525, 840, 525},
@@ -1730,7 +1044,7 @@ static const SiS310_LVDSDataStruct  SiS310_CHTVOPALMData[]=
         {1160, 840,1160, 840}
 };
 
-static const SiS310_LVDSDataStruct  SiS310_CHTVUPALNData[]=
+static const SiS_LVDSDataStruct  SiS310_CHTVUPALNData[]=
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -1741,7 +1055,7 @@ static const SiS310_LVDSDataStruct  SiS310_CHTVUPALNData[]=
        {1400,1000,1400,1000}
 };
 
-static const SiS310_LVDSDataStruct  SiS310_CHTVOPALNData[]=
+static const SiS_LVDSDataStruct  SiS310_CHTVOPALNData[]=
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -1752,7 +1066,7 @@ static const SiS310_LVDSDataStruct  SiS310_CHTVOPALNData[]=
         {1400, 875,1400, 875}
 };
 
-static const SiS310_LVDSDataStruct  SiS310_CHTVSOPALData[]=   /* TW: (super overscan - no effect on 7019) */
+static const SiS_LVDSDataStruct  SiS310_CHTVSOPALData[]=   /* (super overscan - no effect on 7019) */
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -1763,13 +1077,8 @@ static const SiS310_LVDSDataStruct  SiS310_CHTVSOPALData[]=   /* TW: (super over
         {1400, 875,1400, 875}
 };
 
-typedef struct _SiS310_LVDSDesStruct
-{
-       USHORT LCDHDES;
-       USHORT LCDVDES;
-} SiS310_LVDSDesStruct;
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=  /* 800x600 */
+static const SiS_LVDSDesStruct  SiS310_PanelType00_1[]=  /* 800x600 */
 {
        { 0, 0},
        { 0, 0},
@@ -1782,7 +1091,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=  /* 800x600 */
        { 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=  /* 1024x768 */
+static const SiS_LVDSDesStruct  SiS310_PanelType01_1[]=  /* 1024x768 */
 {
        { 0, 0},
        { 0, 0},
@@ -1795,7 +1104,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=  /* 1024x768 */
        { 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=  /* 1280x1024 */
+static const SiS_LVDSDesStruct  SiS310_PanelType02_1[]=  /* 1280x1024 */
 {
        { 0, 0},
        { 0, 0},
@@ -1810,7 +1119,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=  /* 1280x1024 */
 };
 
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType03_1[]=
+static const SiS_LVDSDesStruct  SiS310_PanelType03_1[]=
 {
        { 0, 0},
        { 0, 0},
@@ -1823,7 +1132,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType03_1[]=
        { 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType04_1[]=
+static const SiS_LVDSDesStruct  SiS310_PanelType04_1[]=
 {
        {1343, 798},
        {1343, 794},
@@ -1836,7 +1145,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType04_1[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType05_1[]=
+static const SiS_LVDSDesStruct  SiS310_PanelType05_1[]=
 {
        {1343, 798},
        {1343, 794},
@@ -1849,7 +1158,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType05_1[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType06_1[]=
+static const SiS_LVDSDesStruct  SiS310_PanelType06_1[]=
 {
        {1343, 798},
        {1343, 794},
@@ -1862,7 +1171,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType06_1[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType07_1[]=
+static const SiS_LVDSDesStruct  SiS310_PanelType07_1[]=
 {
        {1343, 798},
        {1343, 794},
@@ -1875,7 +1184,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType07_1[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType08_1[]=   /* 1400x1050 */
+static const SiS_LVDSDesStruct  SiS310_PanelType08_1[]=   /* 1400x1050 */
 {
        { 0, 0},
        { 0, 0},
@@ -1890,7 +1199,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType08_1[]=   /* 1400x1050 */
        { 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType09_1[]=   /* 1280x768 */
+static const SiS_LVDSDesStruct  SiS310_PanelType09_1[]=   /* 1280x768 */
 {
        { 0, 0},
        { 0, 0},
@@ -1905,7 +1214,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType09_1[]=   /* 1280x768 */
        { 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0a_1[]=  /* 1600x1200 */
+static const SiS_LVDSDesStruct  SiS310_PanelType0a_1[]=  /* 1600x1200 */
 {
        { 0, 0},
        { 0, 0},
@@ -1920,7 +1229,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType0a_1[]=  /* 1600x1200 */
        { 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=  /* 640x480_2 */
+static const SiS_LVDSDesStruct  SiS310_PanelType0b_1[]=  /* 640x480_2 */
 {
        { 0, 524},
        { 0, 524},
@@ -1932,7 +1241,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=  /* 640x480_2 */
        { 0, 524}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=  /* 640x480_3 */
+static const SiS_LVDSDesStruct  SiS310_PanelType0c_1[]=  /* 640x480_3 */
 {
        { 0, 524},
        { 0, 524},
@@ -1944,7 +1253,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=  /* 640x480_3 */
        { 0, 524}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]=
+static const SiS_LVDSDesStruct  SiS310_PanelType0d_1[]=
 {
        {1343, 798},
        {1343, 794},
@@ -1957,7 +1266,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0e_1[]=
+static const SiS_LVDSDesStruct  SiS310_PanelType0e_1[]=
 {
        {1343, 798},
        {1343, 794},
@@ -1970,7 +1279,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType0e_1[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0f_1[]=
+static const SiS_LVDSDesStruct  SiS310_PanelType0f_1[]=
 {
        {1343, 798},
        {1343, 794},
@@ -1983,7 +1292,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType0f_1[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType00_2[]=
+static const SiS_LVDSDesStruct  SiS310_PanelType00_2[]=
 {
        {980, 528},
        {980, 503},
@@ -1996,7 +1305,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType00_2[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType01_2[]= 
+static const SiS_LVDSDesStruct  SiS310_PanelType01_2[]=
 {
        {1152, 622},
        {1152, 597},
@@ -2009,7 +1318,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType01_2[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType02_2[]= 
+static const SiS_LVDSDesStruct  SiS310_PanelType02_2[]=
 {
        {1368, 754},
        {1368, 729},
@@ -2024,7 +1333,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType02_2[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType03_2[]=  
+static const SiS_LVDSDesStruct  SiS310_PanelType03_2[]=
 {
        { 0,   0},
        { 0,   0},
@@ -2035,7 +1344,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType03_2[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType04_2[]=  
+static const SiS_LVDSDesStruct  SiS310_PanelType04_2[]=
 {
        { 0,   0},
        { 0,   0},
@@ -2048,7 +1357,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType04_2[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType05_2[]=  
+static const SiS_LVDSDesStruct  SiS310_PanelType05_2[]=
 {
        {1152, 622},
        {1152, 597},
@@ -2061,7 +1370,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType05_2[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType06_2[]=  
+static const SiS_LVDSDesStruct  SiS310_PanelType06_2[]=
 {
        {1152, 622},
        {1152, 597},
@@ -2074,7 +1383,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType06_2[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType07_2[]=  
+static const SiS_LVDSDesStruct  SiS310_PanelType07_2[]=
 {
        {1152, 622},
        {1152, 597},
@@ -2087,7 +1396,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType07_2[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType08_2[]=  /* 1400x1050 */
+static const SiS_LVDSDesStruct  SiS310_PanelType08_2[]=  /* 1400x1050 */
 {
        {1308, 741},
        {1308, 716},
@@ -2102,7 +1411,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType08_2[]=  /* 1400x1050 */
        {   0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType09_2[]= /* 1280x768 */
+static const SiS_LVDSDesStruct  SiS310_PanelType09_2[]= /* 1280x768 */
 {
        {1083, 622},
        {1083, 597},
@@ -2115,7 +1424,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType09_2[]= /* 1280x768 */
        {   0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0a_2[]=  /* 1600x1200 */
+static const SiS_LVDSDesStruct  SiS310_PanelType0a_2[]=  /* 1600x1200 */
 {
        {1568, 920},
        {1568, 895},
@@ -2141,7 +1450,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType0a_2[]=  /* 1600x1200 */
 #endif
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=  /* 640x480_2 */
+static const SiS_LVDSDesStruct  SiS310_PanelType0b_2[]=  /* 640x480_2 */
 {
        {1152, 622},
        {1152, 597},
@@ -2154,7 +1463,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=  /* 640x480_2 */
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]=  /* 640x480_3 */
+static const SiS_LVDSDesStruct  SiS310_PanelType0c_2[]=  /* 640x480_3 */
 {
        {1152, 622},
        {1152, 597},
@@ -2167,7 +1476,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]=  /* 640x480_3 */
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0d_2[]=  
+static const SiS_LVDSDesStruct  SiS310_PanelType0d_2[]=
 {
        {1152, 622},
        {1152, 597},
@@ -2180,7 +1489,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType0d_2[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0e_2[]=
+static const SiS_LVDSDesStruct  SiS310_PanelType0e_2[]=
 {
        {1152, 622},
        {1152, 597},
@@ -2193,7 +1502,7 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType0e_2[]=
        { 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0f_2[] =
+static const SiS_LVDSDesStruct  SiS310_PanelType0f_2[] =
 {
        {1152, 622},
        {1152, 597},
@@ -2206,14 +1515,37 @@ static const SiS310_LVDSDesStruct  SiS310_PanelType0f_2[] =
        { 0,   0}
 };
 
-/* CRT1 CRTC for SlaveModes and LCDA */
+static const SiS_LVDSDesStruct  SiS310_PanelTypeNS_1[]=
+{
+       { 8,   0},
+       { 8,   0},
+       { 8,   0},
+       { 8,   0},
+       { 8,   0},
+       { 0,   0},
+       { 0,   0},
+       { 0,   0},
+       { 0, 806},
+       { 0,   0}
+};
 
-typedef struct _SiS310_LVDSCRT1DataStruct
+static const SiS_LVDSDesStruct  SiS310_PanelTypeNS_2[] =
 {
-       UCHAR CR[15];
-} SiS310_LVDSCRT1DataStruct;
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0},
+       { 0 , 0}
+};
+
+/* CRT1 CRTC for SlaveModes and LCDA */
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =
 {
  {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
    0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -2235,7 +1567,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =
    0x01 }}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1_H[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1_H[] =
 {
  {{0x43,0x27,0x87,0x2d,0x1d,0xaa,0x1f,
    0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -2257,7 +1589,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1_H[] =
    0x01 }}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2[]=
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2[]=
 {
  {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
    0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
@@ -2279,7 +1611,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2[]=
    0x01 }}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2_H[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2_H[] =
 {
  {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
    0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
@@ -2301,7 +1633,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2_H[] =
    0x01 }}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1[] =
 {
  {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
    0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
@@ -2326,7 +1658,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1[] =
    0x01}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1_H[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1_H[] =
 {
  {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
    0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
@@ -2351,7 +1683,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1_H[] =
    0x01 }}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2[] =
 {
  {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
    0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
@@ -2376,7 +1708,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2[] =
    0x01 }}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2_H[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2_H[] =
 {
  {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
    0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
@@ -2401,7 +1733,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2_H[] =
    0x01 }}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1[] =
 {
  {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f,
    0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
@@ -2429,7 +1761,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1[] =
    0x01}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1_H[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1_H[] =
 {
  {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
    0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
@@ -2454,7 +1786,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1_H[] =
    0x01}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2[] =  
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2[] =
 {
  {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
    0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02,
@@ -2482,7 +1814,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2[] =
    0x01}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2_H[] = 
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2_H[] =
 {
  {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
    0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06,
@@ -2507,7 +1839,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2_H[] =
    0x01}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =
 {
   {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
     0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
@@ -2567,7 +1899,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =
 #endif   
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1_H[] = 
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1_H[] =
 {
  {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
    0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
@@ -2627,7 +1959,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1_H[] =
 #endif   
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2[] =  
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2[] =
 {
  {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
    0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02,
@@ -2687,7 +2019,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2[] =
 #endif   
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2_H[] =  
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2_H[] =
 {
  {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
    0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06,
@@ -2747,7 +2079,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2_H[] =
 #endif   
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =
 {
  {{0x83,0x4F,0x87,0x5B,0x13,0x06,0x3E,
    0xB3,0x86,0x8F,0x07,0x20,0x00,0x06,
@@ -2813,7 +2145,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =
 #endif
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1_H[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1_H[] =
 {
  {{0x5B,0x27,0x9F,0x33,0x0B,0x06,0x2E,
    0xB3,0x86,0x8F,0x07,0x20,0x00,0x01,
@@ -2879,7 +2211,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1_H[] =
 #endif
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_2[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_2[] =
 {
  {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
    0x43,0x86,0xDB,0xDA,0x11,0x00,0x07,
@@ -2945,7 +2277,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_2[] =
 #endif
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_2_H[] = 
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_2_H[] =
 {
  {{0xD3,0x5F,0x9E,0x6F,0x07,0x26,0x97,
    0x43,0x86,0xDB,0xDA,0x11,0x00,0x02,
@@ -3011,9 +2343,66 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_2_H[] =
 #endif
 };
 
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1[] =
+{
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+   0x01}},
+ {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
+   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+   0x01}},
+ {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1_H[] =
+{
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}},
+ {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
+   0x01}},
+ {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+   0x01}}
+};
+
+
 /* CRT1 CRTC for Chrontel TV slave modes */
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UNTSC[] =  
+static const SiS_LVDSCRT1DataStruct  SiS310_CHTVCRT1UNTSC[] =
 { 
  {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
    0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
@@ -3038,7 +2427,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UNTSC[] =
    0x01}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[] =
 {
  {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
    0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
@@ -3063,7 +2452,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[] =
    0x01 }}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UPAL[] =    
+static const SiS_LVDSCRT1DataStruct  SiS310_CHTVCRT1UPAL[] =
 { 
  {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
    0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -3088,7 +2477,7 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UPAL[] =
    0x01}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[] =
+static const SiS_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[] =
 {
  {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
    0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -3113,12 +2502,8 @@ static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[] =
    0x01 }}
 };
 
-typedef struct _SiS310_CHTVRegDataStruct
-{
-       UCHAR Reg[16];
-} SiS310_CHTVRegDataStruct;
 
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
 {
  {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
  {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -3138,7 +2523,7 @@ static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
       for PAL-M and PAL-N all above is corrected.
     */
 
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] =
 {
  {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
  {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -3149,7 +2534,7 @@ static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] =
  {{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}}
 };
 
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] =
 {
  {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
  {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -3160,7 +2545,7 @@ static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] =
  {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}}
 };
 
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] =
 {
  {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
  {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -3171,7 +2556,7 @@ static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] =
  {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
 };
 
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] =
 {
  {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
  {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -3187,7 +2572,7 @@ static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] =
 #endif
 };
 
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] =
 {
  {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
  {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -3203,7 +2588,7 @@ static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] =
 #endif
 };
 
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] =
 {
  {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
  {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
@@ -3219,7 +2604,7 @@ static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] =
 #endif
 };
 
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] =
 {
  {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
  {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
index 032baf7..b8da052 100644 (file)
@@ -1,8 +1,9 @@
 /* $XFree86$ */
+/* $XdotOrg$ */
 /*
  * Mode initializing code (CRT1 section) for
  * for SiS 300/305/540/630/730 and
- *     SiS 315/550/650/M650/651/661FX/M661FX/740/741/M741/330/660/M660/760/M760
+ *     SiS 315/550/650/M650/651/661FX/M661FX/740/741(GX)/M741/330/660/M660/760/M760
  * (Universal module for Linux kernel framebuffer and XFree86 4.x)
  *
  * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  * * 2) Redistributions in binary form must reproduce the above copyright
  * *    notice, this list of conditions and the following disclaimer in the
  * *    documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * *    must display the following acknowledgement: "This product includes
- * *    software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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,
 
 #if defined(ALLOC_PRAGMA)
 #pragma alloc_text(PAGE,SiSSetMode)
-#pragma alloc_text(PAGE,SiSInit)
 #endif
 
 /*********************************************/
 /*         POINTER INITIALIZATION            */
 /*********************************************/
 
+#if defined(SIS300) || defined(SIS315H)
 static void
 InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
@@ -134,16 +132,17 @@ InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect;
    SiS_Pr->pSiS_SoftSetting  = &SiS_SoftSetting;
 
+   SiS_Pr->SiS_LCD1280x720Data      = SiS_LCD1280x720Data;
+   SiS_Pr->SiS_StLCD1280x768_2Data  = SiS_StLCD1280x768_2Data;
+   SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data;
+   SiS_Pr->SiS_LCD1280x768_3Data    = SiS_LCD1280x768_3Data;
+   SiS_Pr->SiS_LCD1280x800Data      = SiS_LCD1280x800Data;
    SiS_Pr->SiS_LCD1280x960Data      = SiS_LCD1280x960Data;
-   SiS_Pr->SiS_ExtLCD1400x1050Data  = SiS_ExtLCD1400x1050Data;
-   SiS_Pr->SiS_ExtLCD1600x1200Data  = SiS_ExtLCD1600x1200Data;
    SiS_Pr->SiS_StLCD1400x1050Data   = SiS_StLCD1400x1050Data;
+   SiS_Pr->SiS_ExtLCD1400x1050Data  = SiS_ExtLCD1400x1050Data;
+   SiS_Pr->SiS_LCD1680x1050Data     = SiS_LCD1680x1050Data;
    SiS_Pr->SiS_StLCD1600x1200Data   = SiS_StLCD1600x1200Data;
-   SiS_Pr->SiS_NoScaleData1400x1050 = SiS_NoScaleData1400x1050;
-   SiS_Pr->SiS_NoScaleData1600x1200 = SiS_NoScaleData1600x1200;
-   SiS_Pr->SiS_ExtLCD1280x768Data   = SiS_ExtLCD1280x768Data;
-   SiS_Pr->SiS_StLCD1280x768Data    = SiS_StLCD1280x768Data;
-   SiS_Pr->SiS_NoScaleData1280x768  = SiS_NoScaleData1280x768;
+   SiS_Pr->SiS_ExtLCD1600x1200Data  = SiS_ExtLCD1600x1200Data;
    SiS_Pr->SiS_NoScaleData          = SiS_NoScaleData;
 
    SiS_Pr->SiS_LVDS320x480Data_1   = SiS_LVDS320x480Data_1;
@@ -172,41 +171,12 @@ InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
    SiS_Pr->SiS_LVDS640x480Data_2   = SiS_LVDS640x480Data_2;
 
-   SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1;
-   SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2;
-   SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1;
-   SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2;
    SiS_Pr->SiS_LVDS848x480Data_1   = SiS_LVDS848x480Data_1;
    SiS_Pr->SiS_LVDS848x480Data_2   = SiS_LVDS848x480Data_2;
-
-   SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
-   SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
-
-   SiS_Pr->SiS_LCDA1024x768Data_1  = SiS_LCDA1024x768Data_1;
-   SiS_Pr->SiS_LCDA1024x768Data_2  = SiS_LCDA1024x768Data_2;
-   SiS_Pr->SiS_LCDA1280x1024Data_1 = SiS_LCDA1280x1024Data_1;
-   SiS_Pr->SiS_LCDA1280x1024Data_2 = SiS_LCDA1280x1024Data_2;
-   SiS_Pr->SiS_LCDA1400x1050Data_1 = SiS_LCDA1400x1050Data_1;
-   SiS_Pr->SiS_LCDA1400x1050Data_2 = SiS_LCDA1400x1050Data_2;
-   SiS_Pr->SiS_LCDA1600x1200Data_1 = SiS_LCDA1600x1200Data_1;
-   SiS_Pr->SiS_LCDA1600x1200Data_2 = SiS_LCDA1600x1200Data_2;
-
-   SiS_Pr->LVDS1024x768Des_1  = SiS_PanelType1076_1;
-   SiS_Pr->LVDS1280x1024Des_1 = SiS_PanelType1210_1;
-   SiS_Pr->LVDS1400x1050Des_1 = SiS_PanelType1296_1;
-   SiS_Pr->LVDS1600x1200Des_1 = SiS_PanelType1600_1;
-   SiS_Pr->LVDS1024x768Des_2  = SiS_PanelType1076_2;
-   SiS_Pr->LVDS1280x1024Des_2 = SiS_PanelType1210_2;
-   SiS_Pr->LVDS1400x1050Des_2 = SiS_PanelType1296_2;
-   SiS_Pr->LVDS1600x1200Des_2 = SiS_PanelType1600_2;
-
-   SiS_Pr->SiS_PanelTypeNS_1 = SiS_PanelTypeNS_1;
-   SiS_Pr->SiS_PanelTypeNS_2 = SiS_PanelTypeNS_2;
-
-   SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData;
-   SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData;
-   SiS_Pr->SiS_CHTVUPALDesData  = SiS_CHTVUPALDesData;
-   SiS_Pr->SiS_CHTVOPALDesData  = SiS_CHTVOPALDesData;
+   SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1;
+   SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2;
+   SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1;
+   SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2;
 
    SiS_Pr->SiS_LVDSCRT11280x768_1    = SiS_LVDSCRT11280x768_1;
    SiS_Pr->SiS_LVDSCRT11024x600_1    = SiS_LVDSCRT11024x600_1;
@@ -221,15 +191,25 @@ InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_Pr->SiS_LVDSCRT11024x600_2_H  = SiS_LVDSCRT11024x600_2_H;
    SiS_Pr->SiS_LVDSCRT11152x768_2_H  = SiS_LVDSCRT11152x768_2_H;
    SiS_Pr->SiS_LVDSCRT1320x480_1     = SiS_LVDSCRT1320x480_1;
-   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = SiS_LVDSCRT1XXXxXXX_1;
-   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = SiS_LVDSCRT1XXXxXXX_1_H;
    SiS_Pr->SiS_LVDSCRT1640x480_1     = SiS_LVDSCRT1640x480_1;
    SiS_Pr->SiS_LVDSCRT1640x480_1_H   = SiS_LVDSCRT1640x480_1_H;
    SiS_Pr->SiS_LVDSCRT1640x480_2     = SiS_LVDSCRT1640x480_2;
    SiS_Pr->SiS_LVDSCRT1640x480_2_H   = SiS_LVDSCRT1640x480_2_H;
    SiS_Pr->SiS_LVDSCRT1640x480_3     = SiS_LVDSCRT1640x480_3;
    SiS_Pr->SiS_LVDSCRT1640x480_3_H   = SiS_LVDSCRT1640x480_3_H;
+
+   SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
+   SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
+
+   SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData;
+   SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData;
+   SiS_Pr->SiS_CHTVUPALDesData  = SiS_CHTVUPALDesData;
+   SiS_Pr->SiS_CHTVOPALDesData  = SiS_CHTVOPALDesData;
+
+   SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;    /* lowest value LVDS/LCDA */
+   SiS_Pr->SiS_PanelMin301    = Panel_1024x768;   /* lowest value 301 */
 }
+#endif
 
 #ifdef SIS300
 static void
@@ -265,19 +245,18 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_StandTable[0x1c].CRTC[4] = 0x54;
    SiS_StandTable[0x1c].CRTC[5] = 0x80;
 
-   SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS300_SModeIDTable;
-   SiS_Pr->SiS_VBModeIDTable = (SiS_VBModeStruct *)SiS300_VBModeIDTable;
-   SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS300_EModeIDTable;
-   SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS300_RefIndex;
-   SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS300_CRT1Table;
+   SiS_Pr->SiS_SModeIDTable  = SiS300_SModeIDTable;
+   SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable;
+   SiS_Pr->SiS_EModeIDTable  = SiS300_EModeIDTable;
+   SiS_Pr->SiS_RefIndex      = SiS300_RefIndex;
+   SiS_Pr->SiS_CRT1Table     = SiS300_CRT1Table;
    if(HwInfo->jChipType == SIS_300) {
-      SiS_Pr->SiS_MCLKData_0    = (SiS_MCLKDataStruct *)SiS300_MCLKData_300; /* 300 */
+      SiS_Pr->SiS_MCLKData_0    = SiS300_MCLKData_300; /* 300 */
    } else {
-      SiS_Pr->SiS_MCLKData_0    = (SiS_MCLKDataStruct *)SiS300_MCLKData_630; /* 630, 730 */
+      SiS_Pr->SiS_MCLKData_0    = SiS300_MCLKData_630; /* 630, 730 */
    }
-   SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS300_VCLKData;
+   SiS_Pr->SiS_VCLKData      = SiS300_VCLKData;
    SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS300_VCLKData;
-   SiS_Pr->SiS_ScreenOffset  = SiS300_ScreenOffset;
 
    SiS_Pr->SiS_SR15  = SiS300_SR15;
 
@@ -306,97 +285,102 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_Pr->pSiS_YCSenseData2    = &SiS300_YCSenseData2;
 #endif
 
-   SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS300_StLCD1024x768Data;
-   SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_ExtLCD1024x768Data;
-   SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_St2LCD1024x768Data;
-   SiS_Pr->SiS_StLCD1280x1024Data   = (SiS_LCDDataStruct *)SiS300_StLCD1280x1024Data;
-   SiS_Pr->SiS_ExtLCD1280x1024Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1280x1024Data;
-   SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS300_St2LCD1280x1024Data;
-   SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS300_NoScaleData1024x768;
-   SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS300_NoScaleData1280x1024;
-
-   SiS_Pr->SiS_PanelDelayTbl     = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
-   SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
-#if 0
-   SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTblLVDS;
-#endif
-
-   SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;
-   SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;
-   SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData;                         /* not supported on 300 series */
-   SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData;                         /* not supported on 300 series */
-   SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;  /* not supported on 300 series */
-   SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;  /* not supported on 300 series */
-   SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVSOPALData;
-
-   SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS300_PanelType00_1;
-   SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS300_PanelType01_1;
-   SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS300_PanelType02_1;
-   SiS_Pr->SiS_PanelType03_1 = (SiS_LVDSDesStruct *)SiS300_PanelType03_1;
-   SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1;
-   SiS_Pr->SiS_PanelType05_1 = (SiS_LVDSDesStruct *)SiS300_PanelType05_1;
-   SiS_Pr->SiS_PanelType06_1 = (SiS_LVDSDesStruct *)SiS300_PanelType06_1;
-   SiS_Pr->SiS_PanelType07_1 = (SiS_LVDSDesStruct *)SiS300_PanelType07_1;
-   SiS_Pr->SiS_PanelType08_1 = (SiS_LVDSDesStruct *)SiS300_PanelType08_1;
-   SiS_Pr->SiS_PanelType09_1 = (SiS_LVDSDesStruct *)SiS300_PanelType09_1;
-   SiS_Pr->SiS_PanelType0a_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0a_1;
-   SiS_Pr->SiS_PanelType0b_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0b_1;
-   SiS_Pr->SiS_PanelType0c_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0c_1;
-   SiS_Pr->SiS_PanelType0d_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_1;
-   SiS_Pr->SiS_PanelType0e_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_1;
-   SiS_Pr->SiS_PanelType0f_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_1;
-   SiS_Pr->SiS_PanelType00_2 = (SiS_LVDSDesStruct *)SiS300_PanelType00_2;
-   SiS_Pr->SiS_PanelType01_2 = (SiS_LVDSDesStruct *)SiS300_PanelType01_2;
-   SiS_Pr->SiS_PanelType02_2 = (SiS_LVDSDesStruct *)SiS300_PanelType02_2;
-   SiS_Pr->SiS_PanelType03_2 = (SiS_LVDSDesStruct *)SiS300_PanelType03_2;
-   SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2;
-   SiS_Pr->SiS_PanelType05_2 = (SiS_LVDSDesStruct *)SiS300_PanelType05_2;
-   SiS_Pr->SiS_PanelType06_2 = (SiS_LVDSDesStruct *)SiS300_PanelType06_2;
-   SiS_Pr->SiS_PanelType07_2 = (SiS_LVDSDesStruct *)SiS300_PanelType07_2;
-   SiS_Pr->SiS_PanelType08_2 = (SiS_LVDSDesStruct *)SiS300_PanelType08_2;
-   SiS_Pr->SiS_PanelType09_2 = (SiS_LVDSDesStruct *)SiS300_PanelType09_2;
-   SiS_Pr->SiS_PanelType0a_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0a_2;
-   SiS_Pr->SiS_PanelType0b_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0b_2;
-   SiS_Pr->SiS_PanelType0c_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0c_2;
-   SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_2;
-   SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_2;
-   SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_2;
+   SiS_Pr->SiS_PanelDelayTbl     = SiS300_PanelDelayTbl;
+   SiS_Pr->SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl;
+
+   SiS_Pr->SiS_ExtLCD1024x768Data   = SiS300_ExtLCD1024x768Data;
+   SiS_Pr->SiS_St2LCD1024x768Data   = SiS300_St2LCD1024x768Data;
+   SiS_Pr->SiS_ExtLCD1280x1024Data  = SiS300_ExtLCD1280x1024Data;
+   SiS_Pr->SiS_St2LCD1280x1024Data  = SiS300_St2LCD1280x1024Data;
+
+   SiS_Pr->SiS_CRT2Part2_1024x768_1  = SiS300_CRT2Part2_1024x768_1;
+   SiS_Pr->SiS_CRT2Part2_1280x1024_1 = SiS300_CRT2Part2_1280x1024_1;
+   SiS_Pr->SiS_CRT2Part2_1024x768_2  = SiS300_CRT2Part2_1024x768_2;
+   SiS_Pr->SiS_CRT2Part2_1280x1024_2 = SiS300_CRT2Part2_1280x1024_2;
+   SiS_Pr->SiS_CRT2Part2_1024x768_3  = SiS300_CRT2Part2_1024x768_3;
+   SiS_Pr->SiS_CRT2Part2_1280x1024_3 = SiS300_CRT2Part2_1280x1024_3;
+
+   SiS_Pr->SiS_CHTVUPALData  = SiS300_CHTVUPALData;
+   SiS_Pr->SiS_CHTVOPALData  = SiS300_CHTVOPALData;
+   SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData;    /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData;    /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVUPALNData = SiS300_CHTVUPALData;  /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVOPALNData = SiS300_CHTVOPALData;  /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVSOPALData = SiS300_CHTVSOPALData;
+
+   SiS_Pr->SiS_PanelType00_1 = SiS300_PanelType00_1;
+   SiS_Pr->SiS_PanelType01_1 = SiS300_PanelType01_1;
+   SiS_Pr->SiS_PanelType02_1 = SiS300_PanelType02_1;
+   SiS_Pr->SiS_PanelType03_1 = SiS300_PanelType03_1;
+   SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1;
+   SiS_Pr->SiS_PanelType05_1 = SiS300_PanelType05_1;
+   SiS_Pr->SiS_PanelType06_1 = SiS300_PanelType06_1;
+   SiS_Pr->SiS_PanelType07_1 = SiS300_PanelType07_1;
+   SiS_Pr->SiS_PanelType08_1 = SiS300_PanelType08_1;
+   SiS_Pr->SiS_PanelType09_1 = SiS300_PanelType09_1;
+   SiS_Pr->SiS_PanelType0a_1 = SiS300_PanelType0a_1;
+   SiS_Pr->SiS_PanelType0b_1 = SiS300_PanelType0b_1;
+   SiS_Pr->SiS_PanelType0c_1 = SiS300_PanelType0c_1;
+   SiS_Pr->SiS_PanelType0d_1 = SiS300_PanelType0d_1;
+   SiS_Pr->SiS_PanelType0e_1 = SiS300_PanelType0e_1;
+   SiS_Pr->SiS_PanelType0f_1 = SiS300_PanelType0f_1;
+   SiS_Pr->SiS_PanelType00_2 = SiS300_PanelType00_2;
+   SiS_Pr->SiS_PanelType01_2 = SiS300_PanelType01_2;
+   SiS_Pr->SiS_PanelType02_2 = SiS300_PanelType02_2;
+   SiS_Pr->SiS_PanelType03_2 = SiS300_PanelType03_2;
+   SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2;
+   SiS_Pr->SiS_PanelType05_2 = SiS300_PanelType05_2;
+   SiS_Pr->SiS_PanelType06_2 = SiS300_PanelType06_2;
+   SiS_Pr->SiS_PanelType07_2 = SiS300_PanelType07_2;
+   SiS_Pr->SiS_PanelType08_2 = SiS300_PanelType08_2;
+   SiS_Pr->SiS_PanelType09_2 = SiS300_PanelType09_2;
+   SiS_Pr->SiS_PanelType0a_2 = SiS300_PanelType0a_2;
+   SiS_Pr->SiS_PanelType0b_2 = SiS300_PanelType0b_2;
+   SiS_Pr->SiS_PanelType0c_2 = SiS300_PanelType0c_2;
+   SiS_Pr->SiS_PanelType0d_2 = SiS300_PanelType0d_2;
+   SiS_Pr->SiS_PanelType0e_2 = SiS300_PanelType0e_2;
+   SiS_Pr->SiS_PanelType0f_2 = SiS300_PanelType0f_2;
+   SiS_Pr->SiS_PanelTypeNS_1 = SiS300_PanelTypeNS_1;
+   SiS_Pr->SiS_PanelTypeNS_2 = SiS300_PanelTypeNS_2;
 
    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
-      SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1a;
-      SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2a;
+      SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1a;
+      SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2a;
    }
    if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
-      SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1b;
-      SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2b;
+      SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1b;
+      SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2b;
    }
 
-   SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1;
-   SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1;
-   SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1;
-   SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1_H;
-   SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1_H;
-   SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1_H;
-   SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2;
-   SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2;
-   SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2;
-   SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2_H;
-   SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2_H;
-   SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2_H;
-   SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UNTSC;
-   SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1ONTSC;
-   SiS_Pr->SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UPAL;
-   SiS_Pr->SiS_CHTVCRT1OPAL  = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1OPAL;
-   SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1SOPAL;
-   SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UNTSC;
-   SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_ONTSC;
-   SiS_Pr->SiS_CHTVReg_UPAL  = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UPAL;
-   SiS_Pr->SiS_CHTVReg_OPAL  = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_OPAL;
-   SiS_Pr->SiS_CHTVReg_UPALM = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UNTSC;  /* not supported on 300 series */
-   SiS_Pr->SiS_CHTVReg_OPALM = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_ONTSC;  /* not supported on 300 series */
-   SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UPAL;   /* not supported on 300 series */
-   SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_OPAL;   /* not supported on 300 series */
-   SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_SOPAL;
+   SiS_Pr->SiS_LVDSCRT1800x600_1     = SiS300_LVDSCRT1800x600_1;
+   SiS_Pr->SiS_LVDSCRT1800x600_1_H   = SiS300_LVDSCRT1800x600_1_H;
+   SiS_Pr->SiS_LVDSCRT1800x600_2     = SiS300_LVDSCRT1800x600_2;
+   SiS_Pr->SiS_LVDSCRT1800x600_2_H   = SiS300_LVDSCRT1800x600_2_H;
+   SiS_Pr->SiS_LVDSCRT11024x768_1    = SiS300_LVDSCRT11024x768_1;
+   SiS_Pr->SiS_LVDSCRT11024x768_1_H  = SiS300_LVDSCRT11024x768_1_H;
+   SiS_Pr->SiS_LVDSCRT11024x768_2    = SiS300_LVDSCRT11024x768_2;
+   SiS_Pr->SiS_LVDSCRT11024x768_2_H  = SiS300_LVDSCRT11024x768_2_H;
+   SiS_Pr->SiS_LVDSCRT11280x1024_1   = SiS300_LVDSCRT11280x1024_1;
+   SiS_Pr->SiS_LVDSCRT11280x1024_1_H = SiS300_LVDSCRT11280x1024_1_H;
+   SiS_Pr->SiS_LVDSCRT11280x1024_2   = SiS300_LVDSCRT11280x1024_2;
+   SiS_Pr->SiS_LVDSCRT11280x1024_2_H = SiS300_LVDSCRT11280x1024_2_H;
+   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = SiS300_LVDSCRT1XXXxXXX_1;
+   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = SiS300_LVDSCRT1XXXxXXX_1_H;
+
+   SiS_Pr->SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC;
+   SiS_Pr->SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC;
+   SiS_Pr->SiS_CHTVCRT1UPAL  = SiS300_CHTVCRT1UPAL;
+   SiS_Pr->SiS_CHTVCRT1OPAL  = SiS300_CHTVCRT1OPAL;
+   SiS_Pr->SiS_CHTVCRT1SOPAL = SiS300_CHTVCRT1SOPAL;
+   SiS_Pr->SiS_CHTVReg_UNTSC = SiS300_CHTVReg_UNTSC;
+   SiS_Pr->SiS_CHTVReg_ONTSC = SiS300_CHTVReg_ONTSC;
+   SiS_Pr->SiS_CHTVReg_UPAL  = SiS300_CHTVReg_UPAL;
+   SiS_Pr->SiS_CHTVReg_OPAL  = SiS300_CHTVReg_OPAL;
+   SiS_Pr->SiS_CHTVReg_UPALM = SiS300_CHTVReg_UNTSC;  /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVReg_OPALM = SiS300_CHTVReg_ONTSC;  /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVReg_UPALN = SiS300_CHTVReg_UPAL;   /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVReg_OPALN = SiS300_CHTVReg_OPAL;   /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVReg_SOPAL = SiS300_CHTVReg_SOPAL;
    SiS_Pr->SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
    SiS_Pr->SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
    SiS_Pr->SiS_CHTVVCLKUPAL  = SiS300_CHTVVCLKUPAL;
@@ -406,40 +390,6 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_Pr->SiS_CHTVVCLKUPALN = SiS300_CHTVVCLKUPAL;   /* not supported on 300 series */
    SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL;   /* not supported on 300 series */
    SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
-
-   SiS_Pr->SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_1;
-   SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_1;
-   SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_1;
-   SiS_Pr->SiS_CRT2Part2_1600x1200_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_1;
-   SiS_Pr->SiS_CRT2Part2_1024x768_2  = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_2;
-   SiS_Pr->SiS_CRT2Part2_1280x1024_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_2;
-   SiS_Pr->SiS_CRT2Part2_1400x1050_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_2;
-   SiS_Pr->SiS_CRT2Part2_1600x1200_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_2;
-   SiS_Pr->SiS_CRT2Part2_1024x768_3  = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_3;
-   SiS_Pr->SiS_CRT2Part2_1280x1024_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_3;
-   SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_3;
-   SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_3;
-
-   /* LCDResInfo will on 300 series be translated to 315 series definitions */
-   SiS_Pr->SiS_Panel320x480   = Panel_320x480;
-   SiS_Pr->SiS_Panel640x480   = Panel_640x480;
-   SiS_Pr->SiS_Panel800x600   = Panel_800x600;
-   SiS_Pr->SiS_Panel1024x768  = Panel_1024x768;
-   SiS_Pr->SiS_Panel1280x1024 = Panel_1280x1024;
-   SiS_Pr->SiS_Panel1280x960  = Panel_1280x960;
-   SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
-   SiS_Pr->SiS_Panel1152x768  = Panel_1152x768;
-   SiS_Pr->SiS_Panel1280x768  = Panel_1280x768;
-   SiS_Pr->SiS_Panel1600x1200 = 255;              /* Something illegal */
-   SiS_Pr->SiS_Panel1400x1050 = 255;
-   SiS_Pr->SiS_Panel640x480_2 = 255;
-   SiS_Pr->SiS_Panel640x480_3 = 255;
-   SiS_Pr->SiS_Panel1152x864  = 255;
-   SiS_Pr->SiS_PanelMax       = Panel_320x480;     /* highest value */
-   SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;     /* Lowest value LVDS */
-   SiS_Pr->SiS_PanelMin301    = Panel_1024x768;    /* lowest value 301 */
-   SiS_Pr->SiS_PanelCustom    = Panel_Custom;
-   SiS_Pr->SiS_PanelBarco1366 = Panel_Barco1366;
 }
 #endif
 
@@ -477,23 +427,24 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_StandTable[0x1c].CRTC[4] = 0x55;
    SiS_StandTable[0x1c].CRTC[5] = 0x81;
 
-   SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS310_SModeIDTable;
-   SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS310_EModeIDTable;
+   SiS_Pr->SiS_SModeIDTable  = SiS310_SModeIDTable;
+   SiS_Pr->SiS_EModeIDTable  = SiS310_EModeIDTable;
    SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS310_RefIndex;
-   SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS310_CRT1Table;
-   if(HwInfo->jChipType >= SIS_661) {
-      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_660;  /* 661/741/760 */
+   SiS_Pr->SiS_CRT1Table     = SiS310_CRT1Table;
+   if(HwInfo->jChipType >= SIS_760) {
+      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760;  /* 760 */
+   } else if(HwInfo->jChipType >= SIS_661) {
+      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660;  /* 661/741 */
    } else if(HwInfo->jChipType == SIS_330) {
-      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_330;  /* 330 */
+      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_330;  /* 330 */
    } else if(HwInfo->jChipType > SIS_315PRO) {
-      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_650;  /* 550, 650, 740 */
+      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_650;  /* 550, 650, 740 */
    } else {
-      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_315;  /* 315 */
+      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315;  /* 315 */
    }
-   SiS_Pr->SiS_MCLKData_1    = (SiS_MCLKDataStruct *)SiS310_MCLKData_1;
-   SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS310_VCLKData;
-   SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS310_VBVCLKData;
-   SiS_Pr->SiS_ScreenOffset  = SiS310_ScreenOffset;
+   SiS_Pr->SiS_MCLKData_1    = SiS310_MCLKData_1;
+   SiS_Pr->SiS_VCLKData      = SiS310_VCLKData;
+   SiS_Pr->SiS_VBVCLKData    = SiS310_VBVCLKData;
 
    SiS_Pr->SiS_SR15  = SiS310_SR15;
 
@@ -522,124 +473,96 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_Pr->pSiS_YCSenseData2    = &SiS310_YCSenseData2;
 #endif
 
-   SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS310_StLCD1024x768Data;
-   SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_ExtLCD1024x768Data;
-   SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_St2LCD1024x768Data;
-   SiS_Pr->SiS_StLCD1280x1024Data   = (SiS_LCDDataStruct *)SiS310_StLCD1280x1024Data;
-   SiS_Pr->SiS_ExtLCD1280x1024Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1280x1024Data;
-   SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS310_St2LCD1280x1024Data;
-   SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS310_NoScaleData1024x768;
-   SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS310_NoScaleData1280x1024;
-
-   SiS_Pr->SiS_PanelDelayTbl     = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
-   SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTblLVDS;
-
-   SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVUPALData;
-   SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVOPALData;
-   SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALMData;
-   SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALMData;
-   SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALNData;
-   SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALNData;
-   SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVSOPALData;
-
-   SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS310_PanelType00_1;
-   SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS310_PanelType01_1;
-   SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS310_PanelType02_1;
-   SiS_Pr->SiS_PanelType03_1 = (SiS_LVDSDesStruct *)SiS310_PanelType03_1;
-   SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS310_PanelType04_1;
-   SiS_Pr->SiS_PanelType05_1 = (SiS_LVDSDesStruct *)SiS310_PanelType05_1;
-   SiS_Pr->SiS_PanelType06_1 = (SiS_LVDSDesStruct *)SiS310_PanelType06_1;
-   SiS_Pr->SiS_PanelType07_1 = (SiS_LVDSDesStruct *)SiS310_PanelType07_1;
-   SiS_Pr->SiS_PanelType08_1 = (SiS_LVDSDesStruct *)SiS310_PanelType08_1;
-   SiS_Pr->SiS_PanelType09_1 = (SiS_LVDSDesStruct *)SiS310_PanelType09_1;
-   SiS_Pr->SiS_PanelType0a_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0a_1;
-   SiS_Pr->SiS_PanelType0b_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0b_1;
-   SiS_Pr->SiS_PanelType0c_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0c_1;
-   SiS_Pr->SiS_PanelType0d_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_1;
-   SiS_Pr->SiS_PanelType0e_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_1;
-   SiS_Pr->SiS_PanelType0f_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_1;
-   SiS_Pr->SiS_PanelType00_2 = (SiS_LVDSDesStruct *)SiS310_PanelType00_2;
-   SiS_Pr->SiS_PanelType01_2 = (SiS_LVDSDesStruct *)SiS310_PanelType01_2;
-   SiS_Pr->SiS_PanelType02_2 = (SiS_LVDSDesStruct *)SiS310_PanelType02_2;
-   SiS_Pr->SiS_PanelType03_2 = (SiS_LVDSDesStruct *)SiS310_PanelType03_2;
-   SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS310_PanelType04_2;
-   SiS_Pr->SiS_PanelType05_2 = (SiS_LVDSDesStruct *)SiS310_PanelType05_2;
-   SiS_Pr->SiS_PanelType06_2 = (SiS_LVDSDesStruct *)SiS310_PanelType06_2;
-   SiS_Pr->SiS_PanelType07_2 = (SiS_LVDSDesStruct *)SiS310_PanelType07_2;
-   SiS_Pr->SiS_PanelType08_2 = (SiS_LVDSDesStruct *)SiS310_PanelType08_2;
-   SiS_Pr->SiS_PanelType09_2 = (SiS_LVDSDesStruct *)SiS310_PanelType09_2;
-   SiS_Pr->SiS_PanelType0a_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0a_2;
-   SiS_Pr->SiS_PanelType0b_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0b_2;
-   SiS_Pr->SiS_PanelType0c_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0c_2;
-   SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_2;
-   SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_2;
-   SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_2;
-
-   SiS_Pr->SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_1;
-   SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_1;
-   SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_1;
-   SiS_Pr->SiS_CRT2Part2_1600x1200_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_1;
-   SiS_Pr->SiS_CRT2Part2_1024x768_2  = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_2;
-   SiS_Pr->SiS_CRT2Part2_1280x1024_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_2;
-   SiS_Pr->SiS_CRT2Part2_1400x1050_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_2;
-   SiS_Pr->SiS_CRT2Part2_1600x1200_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_2;
-   SiS_Pr->SiS_CRT2Part2_1024x768_3  = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_3;
-   SiS_Pr->SiS_CRT2Part2_1280x1024_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_3;
-   SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_3;
-   SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_3;
-
-   SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1;
-   SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1;
-   SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1;
-   SiS_Pr->SiS_LVDSCRT11400x1050_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1;
-   SiS_Pr->SiS_LVDSCRT11600x1200_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1;
-   SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1_H;
-   SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1_H;
-   SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1_H;
-   SiS_Pr->SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1_H;
-   SiS_Pr->SiS_LVDSCRT11600x1200_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1_H;
-   SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2;
-   SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2;
-   SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2;
-   SiS_Pr->SiS_LVDSCRT11400x1050_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2;
-   SiS_Pr->SiS_LVDSCRT11600x1200_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2;
-   SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2_H;
-   SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2_H;
-   SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2_H;
-   SiS_Pr->SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2_H;
-   SiS_Pr->SiS_LVDSCRT11600x1200_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2_H;
-   SiS_Pr->SiS_CHTVCRT1UNTSC         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
-   SiS_Pr->SiS_CHTVCRT1ONTSC         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
-   SiS_Pr->SiS_CHTVCRT1UPAL          = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
-   SiS_Pr->SiS_CHTVCRT1OPAL          = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
-   SiS_Pr->SiS_CHTVCRT1SOPAL         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
-
-   SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UNTSC;
-   SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_ONTSC;
-   SiS_Pr->SiS_CHTVReg_UPAL  = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPAL;
-   SiS_Pr->SiS_CHTVReg_OPAL  = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPAL;
-   SiS_Pr->SiS_CHTVReg_UPALM = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALM;
-   SiS_Pr->SiS_CHTVReg_OPALM = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALM;
-   SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALN;
-   SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALN;
-   SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPAL;
-
-   SiS_Pr->SiS_LCDACRT11024x768_1    = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1;
-   SiS_Pr->SiS_LCDACRT11280x1024_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1;
-   SiS_Pr->SiS_LCDACRT11400x1050_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1;
-   SiS_Pr->SiS_LCDACRT11600x1200_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1;
-   SiS_Pr->SiS_LCDACRT11024x768_1_H  = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1_H;
-   SiS_Pr->SiS_LCDACRT11280x1024_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1_H;
-   SiS_Pr->SiS_LCDACRT11400x1050_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1_H;
-   SiS_Pr->SiS_LCDACRT11600x1200_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1_H;
-   SiS_Pr->SiS_LCDACRT11024x768_2    = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2;
-   SiS_Pr->SiS_LCDACRT11280x1024_2   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2;
-   SiS_Pr->SiS_LCDACRT11400x1050_2   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2;
-   SiS_Pr->SiS_LCDACRT11600x1200_2   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2;
-   SiS_Pr->SiS_LCDACRT11024x768_2_H  = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2_H;
-   SiS_Pr->SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2_H;
-   SiS_Pr->SiS_LCDACRT11400x1050_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2_H;
-   SiS_Pr->SiS_LCDACRT11600x1200_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2_H;
+   SiS_Pr->SiS_PanelDelayTbl     = SiS310_PanelDelayTbl;
+   SiS_Pr->SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS;
+
+   SiS_Pr->SiS_St2LCD1024x768Data   = SiS310_St2LCD1024x768Data;
+   SiS_Pr->SiS_ExtLCD1024x768Data   = SiS310_ExtLCD1024x768Data;
+   SiS_Pr->SiS_St2LCD1280x1024Data  = SiS310_St2LCD1280x1024Data;
+   SiS_Pr->SiS_ExtLCD1280x1024Data  = SiS310_ExtLCD1280x1024Data;
+
+   SiS_Pr->SiS_CRT2Part2_1024x768_1  = SiS310_CRT2Part2_1024x768_1;
+
+   SiS_Pr->SiS_PanelType00_1 = SiS310_PanelType00_1;
+   SiS_Pr->SiS_PanelType01_1 = SiS310_PanelType01_1;
+   SiS_Pr->SiS_PanelType02_1 = SiS310_PanelType02_1;
+   SiS_Pr->SiS_PanelType03_1 = SiS310_PanelType03_1;
+   SiS_Pr->SiS_PanelType04_1 = SiS310_PanelType04_1;
+   SiS_Pr->SiS_PanelType05_1 = SiS310_PanelType05_1;
+   SiS_Pr->SiS_PanelType06_1 = SiS310_PanelType06_1;
+   SiS_Pr->SiS_PanelType07_1 = SiS310_PanelType07_1;
+   SiS_Pr->SiS_PanelType08_1 = SiS310_PanelType08_1;
+   SiS_Pr->SiS_PanelType09_1 = SiS310_PanelType09_1;
+   SiS_Pr->SiS_PanelType0a_1 = SiS310_PanelType0a_1;
+   SiS_Pr->SiS_PanelType0b_1 = SiS310_PanelType0b_1;
+   SiS_Pr->SiS_PanelType0c_1 = SiS310_PanelType0c_1;
+   SiS_Pr->SiS_PanelType0d_1 = SiS310_PanelType0d_1;
+   SiS_Pr->SiS_PanelType0e_1 = SiS310_PanelType0e_1;
+   SiS_Pr->SiS_PanelType0f_1 = SiS310_PanelType0f_1;
+   SiS_Pr->SiS_PanelType00_2 = SiS310_PanelType00_2;
+   SiS_Pr->SiS_PanelType01_2 = SiS310_PanelType01_2;
+   SiS_Pr->SiS_PanelType02_2 = SiS310_PanelType02_2;
+   SiS_Pr->SiS_PanelType03_2 = SiS310_PanelType03_2;
+   SiS_Pr->SiS_PanelType04_2 = SiS310_PanelType04_2;
+   SiS_Pr->SiS_PanelType05_2 = SiS310_PanelType05_2;
+   SiS_Pr->SiS_PanelType06_2 = SiS310_PanelType06_2;
+   SiS_Pr->SiS_PanelType07_2 = SiS310_PanelType07_2;
+   SiS_Pr->SiS_PanelType08_2 = SiS310_PanelType08_2;
+   SiS_Pr->SiS_PanelType09_2 = SiS310_PanelType09_2;
+   SiS_Pr->SiS_PanelType0a_2 = SiS310_PanelType0a_2;
+   SiS_Pr->SiS_PanelType0b_2 = SiS310_PanelType0b_2;
+   SiS_Pr->SiS_PanelType0c_2 = SiS310_PanelType0c_2;
+   SiS_Pr->SiS_PanelType0d_2 = SiS310_PanelType0d_2;
+   SiS_Pr->SiS_PanelType0e_2 = SiS310_PanelType0e_2;
+   SiS_Pr->SiS_PanelType0f_2 = SiS310_PanelType0f_2;
+   SiS_Pr->SiS_PanelTypeNS_1 = SiS310_PanelTypeNS_1;
+   SiS_Pr->SiS_PanelTypeNS_2 = SiS310_PanelTypeNS_2;
+
+   SiS_Pr->SiS_CHTVUPALData  = SiS310_CHTVUPALData;
+   SiS_Pr->SiS_CHTVOPALData  = SiS310_CHTVOPALData;
+   SiS_Pr->SiS_CHTVUPALMData = SiS310_CHTVUPALMData;
+   SiS_Pr->SiS_CHTVOPALMData = SiS310_CHTVOPALMData;
+   SiS_Pr->SiS_CHTVUPALNData = SiS310_CHTVUPALNData;
+   SiS_Pr->SiS_CHTVOPALNData = SiS310_CHTVOPALNData;
+   SiS_Pr->SiS_CHTVSOPALData = SiS310_CHTVSOPALData;
+
+   SiS_Pr->SiS_LVDSCRT1800x600_1     = SiS310_LVDSCRT1800x600_1;
+   SiS_Pr->SiS_LVDSCRT11024x768_1    = SiS310_LVDSCRT11024x768_1;
+   SiS_Pr->SiS_LVDSCRT11280x1024_1   = SiS310_LVDSCRT11280x1024_1;
+   SiS_Pr->SiS_LVDSCRT11400x1050_1   = SiS310_LVDSCRT11400x1050_1;
+   SiS_Pr->SiS_LVDSCRT11600x1200_1   = SiS310_LVDSCRT11600x1200_1;
+   SiS_Pr->SiS_LVDSCRT1800x600_1_H   = SiS310_LVDSCRT1800x600_1_H;
+   SiS_Pr->SiS_LVDSCRT11024x768_1_H  = SiS310_LVDSCRT11024x768_1_H;
+   SiS_Pr->SiS_LVDSCRT11280x1024_1_H = SiS310_LVDSCRT11280x1024_1_H;
+   SiS_Pr->SiS_LVDSCRT11400x1050_1_H = SiS310_LVDSCRT11400x1050_1_H;
+   SiS_Pr->SiS_LVDSCRT11600x1200_1_H = SiS310_LVDSCRT11600x1200_1_H;
+   SiS_Pr->SiS_LVDSCRT1800x600_2     = SiS310_LVDSCRT1800x600_2;
+   SiS_Pr->SiS_LVDSCRT11024x768_2    = SiS310_LVDSCRT11024x768_2;
+   SiS_Pr->SiS_LVDSCRT11280x1024_2   = SiS310_LVDSCRT11280x1024_2;
+   SiS_Pr->SiS_LVDSCRT11400x1050_2   = SiS310_LVDSCRT11400x1050_2;
+   SiS_Pr->SiS_LVDSCRT11600x1200_2   = SiS310_LVDSCRT11600x1200_2;
+   SiS_Pr->SiS_LVDSCRT1800x600_2_H   = SiS310_LVDSCRT1800x600_2_H;
+   SiS_Pr->SiS_LVDSCRT11024x768_2_H  = SiS310_LVDSCRT11024x768_2_H;
+   SiS_Pr->SiS_LVDSCRT11280x1024_2_H = SiS310_LVDSCRT11280x1024_2_H;
+   SiS_Pr->SiS_LVDSCRT11400x1050_2_H = SiS310_LVDSCRT11400x1050_2_H;
+   SiS_Pr->SiS_LVDSCRT11600x1200_2_H = SiS310_LVDSCRT11600x1200_2_H;
+   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = SiS310_LVDSCRT1XXXxXXX_1;
+   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = SiS310_LVDSCRT1XXXxXXX_1_H;
+   SiS_Pr->SiS_CHTVCRT1UNTSC         = SiS310_CHTVCRT1UNTSC;
+   SiS_Pr->SiS_CHTVCRT1ONTSC         = SiS310_CHTVCRT1ONTSC;
+   SiS_Pr->SiS_CHTVCRT1UPAL          = SiS310_CHTVCRT1UPAL;
+   SiS_Pr->SiS_CHTVCRT1OPAL          = SiS310_CHTVCRT1OPAL;
+   SiS_Pr->SiS_CHTVCRT1SOPAL         = SiS310_CHTVCRT1OPAL;
+
+   SiS_Pr->SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC;
+   SiS_Pr->SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC;
+   SiS_Pr->SiS_CHTVReg_UPAL  = SiS310_CHTVReg_UPAL;
+   SiS_Pr->SiS_CHTVReg_OPAL  = SiS310_CHTVReg_OPAL;
+   SiS_Pr->SiS_CHTVReg_UPALM = SiS310_CHTVReg_UPALM;
+   SiS_Pr->SiS_CHTVReg_OPALM = SiS310_CHTVReg_OPALM;
+   SiS_Pr->SiS_CHTVReg_UPALN = SiS310_CHTVReg_UPALN;
+   SiS_Pr->SiS_CHTVReg_OPALN = SiS310_CHTVReg_OPALN;
+   SiS_Pr->SiS_CHTVReg_SOPAL = SiS310_CHTVReg_OPAL;
 
    SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
    SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
@@ -648,28 +571,8 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_Pr->SiS_CHTVVCLKUPALM = SiS310_CHTVVCLKUPALM;
    SiS_Pr->SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM;
    SiS_Pr->SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN;
-   SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN;   
+   SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN;
    SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKOPAL;
-
-   SiS_Pr->SiS_Panel320x480   = Panel_320x480;
-   SiS_Pr->SiS_Panel640x480   = Panel_640x480;
-   SiS_Pr->SiS_Panel800x600   = Panel_800x600;
-   SiS_Pr->SiS_Panel1024x768  = Panel_1024x768;
-   SiS_Pr->SiS_Panel1280x1024 = Panel_1280x1024;
-   SiS_Pr->SiS_Panel1280x960  = Panel_1280x960;
-   SiS_Pr->SiS_Panel1600x1200 = Panel_1600x1200;
-   SiS_Pr->SiS_Panel1400x1050 = Panel_1400x1050;
-   SiS_Pr->SiS_Panel1152x768  = Panel_1152x768;
-   SiS_Pr->SiS_Panel1152x864  = Panel_1152x864;
-   SiS_Pr->SiS_Panel1280x768  = Panel_1280x768;
-   SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
-   SiS_Pr->SiS_Panel640x480_2 = Panel_640x480_2;
-   SiS_Pr->SiS_Panel640x480_3 = Panel_640x480_3;
-   SiS_Pr->SiS_PanelMax       = Panel_320x480;    /* highest value */
-   SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;    /* lowest value LVDS/LCDA */
-   SiS_Pr->SiS_PanelMin301    = Panel_1024x768;   /* lowest value 301 */
-   SiS_Pr->SiS_PanelCustom    = Panel_Custom;
-   SiS_Pr->SiS_PanelBarco1366 = 255;
 }
 #endif
 
@@ -710,7 +613,8 @@ SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*********************************************/
 
 USHORT
-SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN)
+SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
+              int Depth, BOOLEAN FSTN, int LCDwidth, int LCDheight)
 {
    USHORT ModeIndex = 0;
 
@@ -734,54 +638,58 @@ SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Dept
          else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
           break;
      case 720:
-          if(!(VBFlags & CRT1_LCDA)) {
-             if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
-             else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
-          }
+          if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
+          else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
           break;
      case 768:
-          if(!(VBFlags & CRT1_LCDA)) {
-             if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
-          }
+          if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
          break;
      case 800:
-         if(VDisplay == 600)    ModeIndex = ModeIndex_800x600[Depth];
-         else if(!(VBFlags & CRT1_LCDA)) {
-            if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
-         }
+         if(VDisplay == 600)      ModeIndex = ModeIndex_800x600[Depth];
+         else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
           break;
      case 848:
-          if(!(VBFlags & CRT1_LCDA)) {
-            if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
-         }
+         if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
          break;
      case 856:
-          if(!(VBFlags & CRT1_LCDA)) {
-            if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+         if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+         break;
+     case 960:
+         if(VGAEngine == SIS_315_VGA) {
+            if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
          }
          break;
      case 1024:
-          if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
-         else if(!(VBFlags & CRT1_LCDA)) {
-            if(VDisplay == 576)    ModeIndex = ModeIndex_1024x576[Depth];
-            else if(VGAEngine == SIS_300_VGA) {
-               if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
-             }
+          if(VDisplay == 768)      ModeIndex = ModeIndex_1024x768[Depth];
+         else if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
+         else if((!(VBFlags & CRT1_LCDA)) && (VGAEngine == SIS_300_VGA)) {
+            if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
          }
           break;
      case 1152:
-          if(!(VBFlags & CRT1_LCDA)) {
-             if(VDisplay == 864)    ModeIndex = ModeIndex_1152x864[Depth];
-             else if(VGAEngine == SIS_300_VGA) {
-               if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
-             }
+          if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
+          if((!(VBFlags & CRT1_LCDA)) && (VGAEngine == SIS_300_VGA)) {
+            if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
          }
          break;
      case 1280:
-          if(VDisplay == 1024)        ModeIndex = ModeIndex_1280x1024[Depth];
-         else if(!(VBFlags & CRT1_LCDA)) {
-             if(VDisplay == 960)      ModeIndex = ModeIndex_1280x960[Depth];
-            else if(VDisplay == 720) ModeIndex = ModeIndex_1280x720[Depth];
+          if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
+         else if(VDisplay == 800) {
+            if(VGAEngine == SIS_315_VGA) {
+               if((VBFlags & CRT1_LCDA) && (LCDwidth == 1280) && (LCDheight == 800)) {
+                  ModeIndex = ModeIndex_1280x800[Depth];
+               } else if(!(VBFlags & CRT1_LCDA)) {
+                  ModeIndex = ModeIndex_1280x800[Depth];
+               }
+            }
+         } else if(VDisplay == 720) {
+            if((VBFlags & CRT1_LCDA) && (LCDwidth == 1280) && (LCDheight == 720)) {
+               ModeIndex = ModeIndex_1280x720[Depth];
+            } else if(!(VBFlags & CRT1_LCDA)) {
+               ModeIndex = ModeIndex_1280x720[Depth];
+            }
+         } else if(!(VBFlags & CRT1_LCDA)) {
+             if(VDisplay == 960) ModeIndex = ModeIndex_1280x960[Depth];
             else if(VDisplay == 768) {
                if(VGAEngine == SIS_300_VGA) {
                   ModeIndex = ModeIndex_300_1280x768[Depth];
@@ -792,23 +700,39 @@ SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Dept
          }
           break;
      case 1360:
+          if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
           if(!(VBFlags & CRT1_LCDA)) {
-            if(VDisplay == 768)     ModeIndex = ModeIndex_1360x768[Depth];
-            else if(VGAEngine == SIS_300_VGA) {
+            if(VGAEngine == SIS_300_VGA) {
                if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
              }
          }
           break;
      case 1400:
           if(VGAEngine == SIS_315_VGA) {
-            if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
+            if(VDisplay == 1050) {
+               if((VBFlags & CRT1_LCDA) &&
+                  (((LCDwidth == 1400) && (LCDheight == 1050)) ||
+                   ((LCDwidth == 1600) && (LCDheight == 1200)))) {
+                  ModeIndex = ModeIndex_1400x1050[Depth];
+               } else if(!(VBFlags & CRT1_LCDA)) {
+                  ModeIndex = ModeIndex_1400x1050[Depth];
+               }
+            }
          }
           break;
      case 1600:
           if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
           break;
+     case 1680:
+          if(VGAEngine == SIS_315_VGA) {
+             if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
+         }
+          break;
      case 1920:
           if(!(VBFlags & CRT1_LCDA)) {
+            if(VGAEngine == SIS_315_VGA) {
+               if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
+            }
              if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
          }
           break;
@@ -851,14 +775,18 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
              break;
        case 400:
             if(CustomT != CUT_PANEL848) {
-               if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+               if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) {
+                  if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+               }
             }
              break;
        case 512:
             if(CustomT != CUT_PANEL848) {
-               if(VDisplay == 384) {
+               if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) {
                   if(LCDwidth != 1024 || LCDheight != 600) {
-                     ModeIndex = ModeIndex_512x384[Depth];
+                     if(VDisplay == 384) {
+                        ModeIndex = ModeIndex_512x384[Depth];
+                     }
                   }
                }
             }
@@ -898,6 +826,9 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
                if((VDisplay == 768) && (LCDheight == 768)) {
                   ModeIndex = ModeIndex_310_1280x768[Depth];
                }
+               if((VDisplay == 800) && (LCDheight == 800)) {
+                  ModeIndex = ModeIndex_310_1280x768[Depth];
+               }
             }
             break;
        case 1360:
@@ -940,17 +871,54 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
             if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
             else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
             break;
+       case 720:
+            if(VGAEngine == SIS_315_VGA) {
+               if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
+               else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
+            }
+            break;
+       case 768:
+            if(VGAEngine == SIS_315_VGA) {
+               if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+            }
+            break;
        case 800:
             if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
+            if(VGAEngine == SIS_315_VGA) {
+               if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
+            }
+            break;
+       case 848:
+            if(VGAEngine == SIS_315_VGA) {
+               if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
+            }
+            break;
+       case 856:
+            if(VGAEngine == SIS_315_VGA) {
+               if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+            }
+            break;
+       case 960:
+            if(VGAEngine == SIS_315_VGA) {
+               if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
+            }
             break;
        case 1024:
             if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+            if(VGAEngine == SIS_315_VGA) {
+               if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
+            }
+            break;
+       case 1152:
+            if(VGAEngine == SIS_315_VGA) {
+               if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
+            }
             break;
        case 1280:
             if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
             else if(VDisplay == 768) {
-               if((LCDheight == 768) ||
-                  ((LCDheight == 1024) && (VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)))) {
+               if((LCDheight == 768) ||  (LCDwidth == 1680) ||
+                  (VBFlags & VB_SISTMDS)) {
                   if(VGAEngine == SIS_300_VGA) {
                      ModeIndex = ModeIndex_300_1280x768[Depth];
                   } else {
@@ -958,24 +926,49 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
                   }
                }
             } else if(VDisplay == 960) {
-               if((LCDheight == 960) ||
-                  ((LCDheight == 1024) && (VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)))) {
+               if((LCDheight == 960) || (VBFlags & VB_SISTMDS)) {
                   ModeIndex = ModeIndex_1280x960[Depth];
                }
+            } else if(VGAEngine == SIS_315_VGA) {
+               if(VDisplay == 800) {
+                  if((LCDheight == 800) || (LCDwidth == 1680) ||
+                     (VBFlags & VB_SISTMDS)) {
+                     ModeIndex = ModeIndex_1280x800[Depth];
+                  }
+               } else if(VDisplay == 720) {
+                  if((LCDheight == 720) || (LCDwidth == 1680) || (LCDwidth == 1400) ||
+                     (VBFlags & VB_SISTMDS)) {
+                     ModeIndex = ModeIndex_1280x720[Depth];
+                  }
+               }
+            }
+            break;
+       case 1360:
+            if(VGAEngine == SIS_315_VGA) {
+               if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
             }
             break;
        case 1400:
             if(VGAEngine == SIS_315_VGA) {
                if(VBFlags & (VB_301B | VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
-                  if(LCDheight != 1200) {
-                     if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
+                  if((LCDwidth == 1400) || (LCDwidth == 1600) || (LCDwidth == 1680)) {
+                     ModeIndex = ModeIndex_1400x1050[Depth];
                   }
                }
             }
             break;
        case 1600:
-            if(VBFlags & (VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
-               if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+            if(VGAEngine == SIS_315_VGA) {
+               if(VBFlags & (VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
+                  if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+               }
+            }
+            break;
+       case 1680:
+            if(VGAEngine == SIS_315_VGA) {
+               if(VBFlags & (VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
+                  if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
+               }
             }
             break;
       }
@@ -1024,8 +1017,8 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
              if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
              break;
        case 512:
-            if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR525P | TV_YPBPR750P | TV_YPBPR1080I))) ||
-                (VBFlags & TV_HIVISION)                                                             ||
+            if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR750P | TV_YPBPR1080I))) ||
+                (VBFlags & TV_HIVISION)                                              ||
                 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
                if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
             }
@@ -1037,17 +1030,19 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
        case 720:
             if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
                 if(VDisplay == 480) {
-                  if((VBFlags & TV_YPBPR) || (VBFlags & (TV_NTSC | TV_PALM)))
+                  /* if((VBFlags & TV_YPBPR) || (VBFlags & (TV_NTSC | TV_PALM))) */
                       ModeIndex = ModeIndex_720x480[Depth];
                 } else if(VDisplay == 576) {
-                  if((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL))
+                  if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
+                      ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) )
                       ModeIndex = ModeIndex_720x576[Depth];
                 }
             }
              break;
        case 768:
             if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
-               if((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) {
+               if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
+                   ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
                   if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
                }
              }
@@ -1072,9 +1067,16 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
             }
             break;
        case 1280:
-            if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
-               if(VDisplay == 720)       ModeIndex = ModeIndex_1280x720[Depth];
-               else if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
+            if(VDisplay == 720) {
+               if((VBFlags & TV_HIVISION) ||
+                  ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) {
+                  ModeIndex = ModeIndex_1280x720[Depth];
+               }
+            } else if(VDisplay == 1024) {
+               if((VBFlags & TV_HIVISION) ||
+                  ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
+                  ModeIndex = ModeIndex_1280x1024[Depth];
+               }
             }
             break;
       }
@@ -1122,6 +1124,11 @@ SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int
        case 856:
                if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
                break;
+       case 960:
+               if(VGAEngine == SIS_315_VGA) {
+                  if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
+               }
+               break;
        case 1024:
                if(VDisplay == 768)      ModeIndex = ModeIndex_1024x768[Depth];
                else if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
@@ -1141,6 +1148,7 @@ SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int
                   }
                } else if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
                else if(VDisplay == 720)    ModeIndex = ModeIndex_1280x720[Depth];
+               else if(VDisplay == 800)    ModeIndex = ModeIndex_1280x800[Depth];
                else if(VDisplay == 960)    ModeIndex = ModeIndex_1280x960[Depth];
                break;
         case 1360:
@@ -1158,6 +1166,13 @@ SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int
                   }
                }
                break;
+       case 1680:
+               if(VGAEngine == SIS_315_VGA) {
+                  if(VBFlags & (VB_301B|VB_301C|VB_302B)) {
+                     if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
+                  }
+               }
+               break;
    }
 
    return ModeIndex;
@@ -1255,13 +1270,13 @@ SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR)
 void
 SiS_DisplayOn(SiS_Private *SiS_Pr)
 {
-   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x00);
+   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF);
 }
 
 void
 SiS_DisplayOff(SiS_Private *SiS_Pr)
 {
-   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x20);
+   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);
 }
 
 
@@ -1308,9 +1323,11 @@ SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    /* (SR11 is used for DDC and in enable/disablebridge) */
    SiS_Pr->SiS_SensibleSR11 = FALSE;
    SiS_Pr->SiS_MyCR63 = 0x63;
-   if(HwInfo->jChipType >= SIS_661) {
-      SiS_Pr->SiS_SensibleSR11 = TRUE;
+   if(HwInfo->jChipType >= SIS_330) {
       SiS_Pr->SiS_MyCR63 = 0x53;
+      if(HwInfo->jChipType >= SIS_661) {
+         SiS_Pr->SiS_SensibleSR11 = TRUE;
+      }
    }
 
    /* You should use the macros, not these flags directly */
@@ -1350,6 +1367,10 @@ SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
         }
       }
    }
+   if(HwInfo->jChipType == SIS_760) {
+      temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78);
+      if(temp1 & 0x30) SiS_Pr->SiS_SysFlags |= SF_760LFB;
+   }
 }
 
 /*********************************************/
@@ -1411,7 +1432,7 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 void
 SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-   ULONG   temp;
+   USHORT temp;
 
    SiS_Pr->SiS_IF_DEF_LVDS = 0;
    SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
@@ -1422,18 +1443,19 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
    SiS_Pr->SiS_ChrontelInit = 0;
 
+   /* Check for SiS30x first */
+   temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
+   if((temp == 1) || (temp == 2)) return;
+
    switch(HwInfo->jChipType) {
 #ifdef SIS300
    case SIS_540:
    case SIS_630:
    case SIS_730:
-        /* Check for SiS30x first */
-        temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
-       if((temp == 1) || (temp == 2)) return;
        temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
        temp = (temp & 0x0E) >> 1;
-       if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
-       if(temp == 3)   SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
+       if((temp >= 2) && (temp <= 5))  SiS_Pr->SiS_IF_DEF_LVDS = 1;
+       if(temp == 3)                   SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
        if((temp == 4) || (temp == 5)) {
                /* Save power status (and error check) - UNUSED */
                SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
@@ -1448,8 +1470,8 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    case SIS_330:
         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
        temp = (temp & 0x0E) >> 1;
-       if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
-       if(temp == 3)  SiS_Pr->SiS_IF_DEF_CH70xx = 2;
+       if((temp >= 2) && (temp <= 3))  SiS_Pr->SiS_IF_DEF_LVDS = 1;
+       if(temp == 3)                   SiS_Pr->SiS_IF_DEF_CH70xx = 2;
         break;
    case SIS_661:
    case SIS_741:
@@ -1457,9 +1479,9 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    case SIS_760:
         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
        temp = (temp & 0xe0) >> 5;
-       if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
-       if(temp == 3)  SiS_Pr->SiS_IF_DEF_CH70xx = 2;
-       if(temp == 4)  SiS_Pr->SiS_IF_DEF_CONEX = 1;  /* Not yet supported */
+       if((temp >= 2) && (temp <= 3))  SiS_Pr->SiS_IF_DEF_LVDS = 1;
+       if(temp == 3)                   SiS_Pr->SiS_IF_DEF_CH70xx = 2;
+       if(temp == 4)                   SiS_Pr->SiS_IF_DEF_CONEX = 1;  /* Not yet supported */
         break;
 #endif
    default:
@@ -1487,44 +1509,78 @@ SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable)
 /*        HELPER: Determine ROM usage        */
 /*********************************************/
 
+BOOLEAN
+SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+   USHORT romversoffs, romvmaj = 1, romvmin = 0;
+
+   if(HwInfo->jChipType >= SIS_661) {
+      if((ROMAddr[0x1a] == 'N') &&
+         (ROMAddr[0x1b] == 'e') &&
+         (ROMAddr[0x1c] == 'w') &&
+         (ROMAddr[0x1d] == 'V')) {
+        return TRUE;
+      }
+      romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8);
+      if(romversoffs) {
+        if((ROMAddr[romversoffs+1] == '.') || (ROMAddr[romversoffs+4] == '.')) {
+           romvmaj = ROMAddr[romversoffs] - '0';
+           romvmin = ((ROMAddr[romversoffs+2] -'0') * 10) + (ROMAddr[romversoffs+3] - '0');
+        }
+      }
+      if((romvmaj != 0) || (romvmin >= 92)) {
+        return TRUE;
+      }
+   } else if(IS_SIS650740) {
+      if((ROMAddr[0x1a] == 'N') &&
+         (ROMAddr[0x1b] == 'e') &&
+         (ROMAddr[0x1c] == 'w') &&
+         (ROMAddr[0x1d] == 'V')) {
+        return TRUE;
+      }
+   }
+   return FALSE;
+}
+
 static void
 SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
    UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+   USHORT romptr = 0;
+
+   SiS_Pr->SiS_UseROM = FALSE;
+   SiS_Pr->SiS_ROMNew = FALSE;
 
    if((ROMAddr) && (HwInfo->UseROM)) {
-      if((ROMAddr[0x00] != 0x55) || (ROMAddr[0x01] != 0xAA)) {
-         SiS_Pr->SiS_UseROM = FALSE;
-      } else if(HwInfo->jChipType == SIS_300) {
-        /* 300: We check if the code starts below 0x220 by
-        * checking the jmp instruction at the beginning
-        * of the BIOS image.
-        */
-        if((ROMAddr[3] == 0xe9) &&
-           ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
+      if(HwInfo->jChipType == SIS_300) {
+         /* 300: We check if the code starts below 0x220 by
+         * checking the jmp instruction at the beginning
+         * of the BIOS image.
+         */
+        if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
            SiS_Pr->SiS_UseROM = TRUE;
-        else
-           SiS_Pr->SiS_UseROM = FALSE;
       } else if(HwInfo->jChipType < SIS_315H) {
-#if 0
-        /* Rest of 300 series: We don't use the ROM image if
-        * the BIOS version < 2.0.0 as such old BIOSes don't
-        * have the needed data at the expected locations.
-        */
-         if(ROMAddr[0x06] < '2')  SiS_Pr->SiS_UseROM = FALSE;
-        else                     SiS_Pr->SiS_UseROM = TRUE;
-#else
-       /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
-        * the others do as well
-        */
+        /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
+         * the others do as well
+         */
         SiS_Pr->SiS_UseROM = TRUE;
-#endif
       } else {
-         /* 315/330 series stick to the standard */
+         /* 315/330 series stick to the standard(s) */
         SiS_Pr->SiS_UseROM = TRUE;
+        if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr, HwInfo))) {
+           /* Find out about LCD data table entry size */
+           if((romptr = SISGETROMW(0x0102))) {
+              if(ROMAddr[romptr + (32 * 16)] == 0xff)
+                 SiS_Pr->SiS661LCD2TableSize = 32;
+              else if(ROMAddr[romptr + (34 * 16)] == 0xff)
+                 SiS_Pr->SiS661LCD2TableSize = 34;
+              else if(ROMAddr[romptr + (36 * 16)] == 0xff)
+                 SiS_Pr->SiS661LCD2TableSize = 36;  /* 0.94 final */
+           }
+        }
       }
-   } else SiS_Pr->SiS_UseROM = FALSE;
-
+   }
 }
 
 /*********************************************/
@@ -1609,7 +1665,8 @@ SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
   SiS_Pr->SiS_VBType = 0;
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) return;
+  if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX))
+     return;
 
   flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
 
@@ -1620,7 +1677,6 @@ SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
   if(flag >= 2) {
      SiS_Pr->SiS_VBType = VB_SIS302B;
   } else if(flag == 1) {
-     SiS_Pr->SiS_VBType = VB_SIS301;
      if(rev >= 0xC0) {
                SiS_Pr->SiS_VBType = VB_SIS301C;
      } else if(rev >= 0xB0) {
@@ -1628,101 +1684,21 @@ SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
        /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
        nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
         if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
+     } else {
+        SiS_Pr->SiS_VBType = VB_SIS301;
      }
   }
   if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
-     if(rev >= 0xD0) {
-       SiS_Pr->SiS_VBType &= ~(VB_SIS301B | VB_SIS301C | VB_SIS302B | VB_NoLCD);
-       if(rev >= 0xE0) {
-          flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
-          if(flag == 0xff)
-             SiS_Pr->SiS_VBType |= VB_SIS302LV;
-          else
-             SiS_Pr->SiS_VBType |= VB_SIS302ELV;
-       } else {
-          SiS_Pr->SiS_VBType |= VB_SIS301LV;
-       }
+     if(rev >= 0xE0) {
+       flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
+       if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV;
+       else             SiS_Pr->SiS_VBType = VB_SIS301C;  /* VB_SIS302ELV; */
+     } else if(rev >= 0xD0) {
+       SiS_Pr->SiS_VBType = VB_SIS301LV;
      }
   }
 }
 
-/*********************************************/
-/*            HELPER: GetDRAMSize            */
-/*********************************************/
-
-#ifndef LINUX_XF86
-static ULONG
-GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
-{
-  ULONG   AdapterMemorySize = 0;
-#ifdef SIS315H
-  USHORT  counter;
-#endif
-
-  switch(HwInfo->jChipType) {
-#ifdef SIS315H
-  case SIS_315H:
-  case SIS_315:
-  case SIS_315PRO:
-       counter = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
-       AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
-       counter >>= 2;
-       counter &= 0x03;
-       if(counter == 0x02) {
-               AdapterMemorySize += (AdapterMemorySize / 2);      /* DDR asymetric */
-       } else if(counter != 0) {
-               AdapterMemorySize <<= 1;                           /* SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK */
-       }
-       AdapterMemorySize *= (1024*1024);
-        break;
-
-  case SIS_330:
-       counter = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
-       AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
-       counter &= 0x0c;
-       if(counter != 0) {
-               AdapterMemorySize <<= 1;
-       }
-       AdapterMemorySize *= (1024*1024);
-       break;
-
-  case SIS_550:
-  case SIS_650:
-  case SIS_740:
-       counter = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
-       counter++;
-       AdapterMemorySize = counter * 4;
-       AdapterMemorySize *= (1024*1024);
-       break;
-
-  case SIS_661:
-  case SIS_741:
-  case SIS_660:
-  case SIS_760:
-        counter = (SiS_GetReg(SiS_Pr->SiS_P3c4,0x79) & 0xf0) >> 4;
-       AdapterMemorySize = 1 << counter;
-       AdapterMemorySize *= (1024*1024);
-        break;
-#endif
-
-#ifdef SIS300
-  case SIS_300:
-  case SIS_540:
-  case SIS_630:
-  case SIS_730:
-       AdapterMemorySize = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
-       AdapterMemorySize++;
-       AdapterMemorySize *= (1024*1024);
-       break;
-#endif
-  default:
-        break;
-  }
-
-  return AdapterMemorySize;
-}
-#endif
-
 /*********************************************/
 /*           HELPER: Check RAM size          */
 /*********************************************/
@@ -1732,8 +1708,8 @@ static BOOLEAN
 SiS_CheckMemorySize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                     USHORT ModeNo, USHORT ModeIdIndex)
 {
+  USHORT AdapterMemSize = HwInfo->ulVideoMemorySize / (1024*1024);
   USHORT memorysize,modeflag;
-  ULONG  temp;
 
   if(SiS_Pr->UseCustomMode) {
      modeflag = SiS_Pr->CModeFlag;
@@ -1749,11 +1725,8 @@ SiS_CheckMemorySize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   memorysize >>= MemorySizeShift;              /* Get required memory size */
   memorysize++;
 
-  temp = GetDRAMSize(SiS_Pr, HwInfo);          /* Get adapter memory size (in MB) */
-  temp /= (1024*1024);
-
-  if(temp < memorysize) return(FALSE);
-  else return(TRUE);
+  if(AdapterMemSize < memorysize) return FALSE;
+  return TRUE;
 }
 #endif
 
@@ -1767,11 +1740,14 @@ SiS_Get310DRAMType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
    UCHAR data, temp;
 
-   if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) {
-     data = *SiS_Pr->pSiS_SoftSetting & 0x03;
+   if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) {
+     data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
    } else {
      if(HwInfo->jChipType >= SIS_661) {
         data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
+       if(SiS_Pr->SiS_ROMNew) {
+          data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
+       }
      } else if(IS_SIS550650740) {
         data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
      } else {  /* 315, 330 */
@@ -1798,10 +1774,14 @@ SiS_Get310DRAMType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 USHORT
 SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
+  UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
   USHORT index;
 
   index = SiS_Get310DRAMType(SiS_Pr, HwInfo);
   if(HwInfo->jChipType >= SIS_661) {
+     if(SiS_Pr->SiS_ROMNew) {
+        return((USHORT)(SISGETROMW((0x90 + (index * 5) + 3))));
+     }
      return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
   } else if(index >= 4) {
      index -= 4;
@@ -1827,20 +1807,17 @@ SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 
   if(SiS_Pr->SiS_ModeType >= ModeEGA) {
      if(ModeNo > 0x13) {
-        AdapterMemorySize = GetDRAMSize(SiS_Pr, HwInfo);
-        SiS_SetMemory(VideoMemoryAddress,AdapterMemorySize,0);
+        SiS_SetMemory(VideoMemoryAddress, AdapterMemorySize, 0);
      } else {
         pBuffer = (USHORT *)VideoMemoryAddress;
-        for(i=0; i<0x4000; i++)
-           pBuffer[i] = 0x0000;
+        for(i=0; i<0x4000; i++) pBuffer[i] = 0x0000;
      }
   } else {
-     pBuffer = (USHORT *)VideoMemoryAddress;
      if(SiS_Pr->SiS_ModeType < ModeCGA) {
-        for(i=0; i<0x4000; i++)
-           pBuffer[i] = 0x0720;
+        pBuffer = (USHORT *)VideoMemoryAddress;
+        for(i=0; i<0x4000; i++) pBuffer[i] = 0x0720;
      } else {
-        SiS_SetMemory(VideoMemoryAddress,0x8000,0);
+        SiS_SetMemory(VideoMemoryAddress, 0x8000, 0);
      }
   }
 }
@@ -1896,10 +1873,10 @@ SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
    UCHAR index;
 
    if(ModeNo <= 0x13) {
-       index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
+      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
    } else {
-       if(SiS_Pr->SiS_ModeType <= 0x02) index = 0x1B;    /* 02 -> ModeEGA  */
-       else index = 0x0F;
+      if(SiS_Pr->SiS_ModeType <= ModeEGA) index = 0x1B;
+      else index = 0x0F;
    }
    return index;
 }
@@ -1914,7 +1891,7 @@ SiS_DoLowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
     USHORT temp,temp1,temp2;
 
     if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
-       return(1);
+       return(TRUE);
     temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
     temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
@@ -1924,13 +1901,13 @@ SiS_DoLowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
     SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
     if((HwInfo->jChipType >= SIS_315H) ||
        (HwInfo->jChipType == SIS_300)) {
-       if(temp2 == 0x55) return(0);
-       else return(1);
+       if(temp2 == 0x55) return(FALSE);
+       else return(TRUE);
     } else {
-       if(temp2 != 0x55) return(1);
+       if(temp2 != 0x55) return(TRUE);
        else {
           SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
-          return(0);
+          return(FALSE);
        }
     }
 }
@@ -1943,6 +1920,43 @@ SiS_SetLowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
     }
 }
 
+/*********************************************/
+/*            HELPER: ENABLE CRT1            */
+/*********************************************/
+
+static void
+SiS_SetupCR5x(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(IS_SIS650) {
+        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+        if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
+        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+      } else if(IS_SIS661741660760) {
+         SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7);
+        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+        if(!SiS_Pr->SiS_ROMNew) {
+           SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
+        }
+      }
+   }
+}
+
+static void
+SiS_HandleCRT1(SiS_Private *SiS_Pr)
+{
+  SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
+#if 0
+  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
+     if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
+        (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
+        SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
+     }
+  }
+#endif
+}
+
 /*********************************************/
 /*           HELPER: GetColorDepth           */
 /*********************************************/
@@ -1977,28 +1991,22 @@ USHORT
 SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
               USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
 {
-  USHORT temp,colordepth,infoflag;
+  USHORT xres, temp, colordepth, infoflag;
 
   if(SiS_Pr->UseCustomMode) {
      infoflag = SiS_Pr->CInfoFlag;
-     temp = SiS_Pr->CHDisplay / 16;
+     xres = SiS_Pr->CHDisplay;
   } else {
      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-     temp = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeOffset;
-     temp = SiS_Pr->SiS_ScreenOffset[temp];
+     xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
   }
 
   colordepth = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex);
 
+  temp = xres / 16;
   if(infoflag & InterlaceMode) temp <<= 1;
-
   temp *= colordepth;
-
-  if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) ||
-        ModeNo == 0x3f ||
-       ModeNo == 0x42 ||
-       ModeNo == 0x45 ) ||
-      (SiS_Pr->UseCustomMode && (SiS_Pr->CHDisplay % 16)) ) {
+  if(xres % 16) {
      colordepth >>= 1;
      temp += colordepth;
   }
@@ -2103,9 +2111,15 @@ SiS_SetCRTCRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
      CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
      SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);                     /* Set CRTC(3d4) */
   }
-  if( ( (HwInfo->jChipType == SIS_630) ||
-        (HwInfo->jChipType == SIS_730) )  &&
-      (HwInfo->jChipRevision >= 0x30) ) {                 /* for 630S0 */
+  if(HwInfo->jChipType >= SIS_661) {
+     SiS_SetupCR5x(SiS_Pr, HwInfo);
+     for(i = 0x13; i <= 0x14; i++) {
+        CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
+        SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
+     }
+  } else if( ( (HwInfo->jChipType == SIS_630) ||
+               (HwInfo->jChipType == SIS_730) )  &&
+             (HwInfo->jChipRevision >= 0x30) ) {                  /* for 630S0 */
      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
            SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE);
@@ -2206,7 +2220,7 @@ SiS_SetGRCRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
 /*********************************************/
 
 static void
-SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 {
   USHORT i;
 
@@ -2216,6 +2230,11 @@ SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
   if(HwInfo->jChipType >= SIS_315H) {
      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
+     if(ModeNo <= 0x13) {
+        if(ModeNo == 0x06 || ModeNo >= 0x0e) {
+          SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20);
+       }
+     }
   }
 }
 
@@ -2279,45 +2298,6 @@ SiS_SetCRT1Sync(SiS_Private *SiS_Pr, USHORT RefreshRateTableIndex)
 /*                  CRTC/2                   */
 /*********************************************/
 
-#ifdef SIS315H
-static void
-SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                  USHORT RefreshRateTableIndex, USHORT *ResIndex,
-                  USHORT *DisplayType)
- {
-  USHORT modeflag = 0;
-
-  if(ModeNo <= 0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     *ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  } else {
-     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     *ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-  }
-
-  *ResIndex &= 0x3F;
-
-  *DisplayType = SiS_Pr->SiS_LCDResInfo;
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) *DisplayType += 32;
-  if(modeflag & HalfDCLK)                 *DisplayType += 16;
-
-  if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-        *DisplayType = 100;
-       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) *DisplayType += 2;
-        if(modeflag & HalfDCLK)                 *DisplayType += 1;
-     }
-  } else if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-        *DisplayType = 104;
-       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) *DisplayType += 2;
-        if(modeflag & HalfDCLK)                 *DisplayType += 1;
-     }
-  }
-
-}
-#endif
-
 static void
 SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                 USHORT RefreshRateTableIndex,
@@ -2325,10 +2305,6 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 {
   UCHAR  index;
   USHORT temp,i,j,modeflag;
-#ifdef SIS315H
-  USHORT ResIndex,DisplayType;
-  const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
-#endif
 
   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);           /* unlock cr0-7 */
 
@@ -2336,7 +2312,7 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
      modeflag = SiS_Pr->CModeFlag;
 
-     for(i=0,j=0;i<=07;i++,j++) {
+     for(i=0,j=0;i<=7;i++,j++) {
         SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
      }
      for(j=0x10;i<=10;i++,j++) {
@@ -2354,7 +2330,7 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
      temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
      if(modeflag & DoubleScanMode) temp |= 0x80;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,temp);
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
 
   } else {
 
@@ -2364,87 +2340,28 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
         modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
      }
 
-     if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-
-#ifdef SIS315H
-
-        SiS_GetLCDACRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, &ResIndex, &DisplayType);
-
-        switch(DisplayType) {
-        case Panel_1024x768      : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;     break;
-        case Panel_1280x1024     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1;    break;
-        case Panel_1400x1050     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1;    break;
-        case Panel_1600x1200     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1;    break;
-        case Panel_1024x768  + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1_H;   break;
-        case Panel_1280x1024 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1_H;  break;
-        case Panel_1400x1050 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1_H;  break;
-        case Panel_1600x1200 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1_H;  break;
-        case Panel_1024x768  + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2;     break;
-        case Panel_1280x1024 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2;    break;
-        case Panel_1400x1050 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2;    break;
-        case Panel_1600x1200 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2;    break;
-        case Panel_1024x768  + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2_H;   break;
-        case Panel_1280x1024 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H;  break;
-        case Panel_1400x1050 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2_H;  break;
-        case Panel_1600x1200 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2_H;  break;
-        case 100:                 LCDACRT1Ptr = Compaq1280x1024_LCDACRT1_1;         break;
-        case 101:                 LCDACRT1Ptr = Compaq1280x1024_LCDACRT1_1_H;       break;
-        case 102:                 LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2;    break;
-        case 103:                 LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H;  break;
-        case 104:                 LCDACRT1Ptr = Clevo1024x768_LCDACRT1_1;           break;
-        case 105:                 LCDACRT1Ptr = Clevo1024x768_LCDACRT1_1_H;         break;
-        case 106:                 LCDACRT1Ptr = Clevo1024x768_LCDACRT1_2;           break;
-        case 107:                 LCDACRT1Ptr = Clevo1024x768_LCDACRT1_2_H;         break;
-        default:                   LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;     break;
-        }
+     index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
 
-        for(i=0, j=0; i<=0x07; i++, j++) {
-           SiS_SetReg(SiS_Pr->SiS_P3d4,i,(LCDACRT1Ptr+ResIndex)->CR[j]);
-        }
-        for(i=0x10, j=8; i<=0x12; i++, j++) {
-           SiS_SetReg(SiS_Pr->SiS_P3d4,i,(LCDACRT1Ptr+ResIndex)->CR[j]);
-        }
-        for(i=0x15, j=11; i<=0x16; i++, j++) {
-           SiS_SetReg(SiS_Pr->SiS_P3d4,i,(LCDACRT1Ptr+ResIndex)->CR[j]);
-        }
-        for(i=0x0A, j=13; i<=0x0C; i++, j++) {
-           SiS_SetReg(SiS_Pr->SiS_P3c4,i,(LCDACRT1Ptr+ResIndex)->CR[j]);
-        }
-
-        temp = (LCDACRT1Ptr+ResIndex)->CR[16] & 0xE0;
-        SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
-
-        temp = ((LCDACRT1Ptr+ResIndex)->CR[16] & 0x01) << 5;
-        if(modeflag & DoubleScanMode) temp |= 0x80;
-        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,temp);
-
-#endif
-
-     } else {
-
-        index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-
-        for(i=0,j=0;i<=07;i++,j++) {
-          SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
-        }
-        for(j=0x10;i<=10;i++,j++) {
-          SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
-        }
-        for(j=0x15;i<=12;i++,j++) {
-          SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
-        }
-        for(j=0x0A;i<=15;i++,j++) {
-          SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
-        }
+     for(i=0,j=0;i<=7;i++,j++) {
+        SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+     }
+     for(j=0x10;i<=10;i++,j++) {
+        SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+     }
+     for(j=0x15;i<=12;i++,j++) {
+        SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+     }
+     for(j=0x0A;i<=15;i++,j++) {
+        SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+     }
 
-        temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0;
-        SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
+     temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0;
+     SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
 
-        temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5;
-        if(modeflag & DoubleScanMode)  temp |= 0x80;
-        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,temp);
+     temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5;
+     if(modeflag & DoubleScanMode)  temp |= 0x80;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
 
-     }
   }
 
   if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
@@ -2482,7 +2399,7 @@ SiS_SetCRT1Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
    DisplayUnit <<= 5;
    temp = (DisplayUnit & 0xff00) >> 8;
-   if (DisplayUnit & 0xff) temp++;
+   if(DisplayUnit & 0xff) temp++;
    temp++;
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp);
 }
@@ -2917,7 +2834,8 @@ SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 {
   USHORT modeflag;
 
-  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);  /* disable auto-threshold */
+  /* disable auto-threshold */
+  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);
 
   if(SiS_Pr->UseCustomMode) {
      modeflag = SiS_Pr->CModeFlag;
@@ -2925,30 +2843,19 @@ SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
-  if(HwInfo->jChipType >= SIS_661) {
-     SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
-     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
-     if(ModeNo > 0x13) {
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
+  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+  if(ModeNo > 0x13) {
+     if(HwInfo->jChipType >= SIS_661) {
         if(!(modeflag & HalfDCLK)) {
           SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
-          if(ModeNo != 0x38) {
-             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
-          }
+          SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
        }
-     }
-  } else {
-     if(ModeNo > 0x13) {
-        if( (!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
+     } else {
+        if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
            SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
-           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
            SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
-        } else {
-           SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
-           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
-        }
-     } else {
-        SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
-        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+       }
      }
   }
 }
@@ -2963,33 +2870,29 @@ SiS_SetVCLKState(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                  USHORT ModeNo, USHORT RefreshRateTableIndex,
                  USHORT ModeIdIndex)
 {
-  USHORT data, data2=0;
-  USHORT VCLK, index=0;
+  USHORT data=0, VCLK=0, index=0;
 
-  if(ModeNo <= 0x13) VCLK = 0;
-  else {
+  if(ModeNo > 0x13) {
      if(SiS_Pr->UseCustomMode) {
         VCLK = SiS_Pr->CSRClock;
      } else {
         index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,
-                      RefreshRateTableIndex,HwInfo);
+                             RefreshRateTableIndex,HwInfo);
         VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
      }
   }
 
-  if(HwInfo->jChipType < SIS_315H) {           /* 300 series */
+  if(HwInfo->jChipType < SIS_315H) {
 
-     data2 = 0x00;
-     if(VCLK > 150) data2 |= 0x80;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data2);
+     if(VCLK > 150) data |= 0x80;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
 
-     data2 = 0x00;
-     if(VCLK >= 150) data2 |= 0x08;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
+     data = 0x00;
+     if(VCLK >= 150) data |= 0x08;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
 
-  } else {                                     /* 315 series */
+  } else {
 
-     data = 0;
      if(VCLK >= 166) data |= 0x0c;
      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
 
@@ -2998,23 +2901,31 @@ SiS_SetVCLKState(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
      }
   }
 
-  data2 = 0x03;
-  if((VCLK >= 135) && (VCLK < 160))      data2 = 0x02;
-  else if((VCLK >= 160) && (VCLK < 260)) data2 = 0x01;
-  else if(VCLK >= 260)                   data2 = 0x00;
+  /* DAC speed */
+  if(HwInfo->jChipType >= SIS_661) {
 
-  if(HwInfo->jChipType == SIS_540) {
-     if((VCLK == 203) || (VCLK < 234)) data2 = 0x02;
-  }
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10);
 
-  if(HwInfo->jChipType < SIS_315H) {
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data2);        /* DAC speed */
   } else {
-     if(HwInfo->jChipType > SIS_315PRO) {
-        /* This "if" is done in 330 and 650/LVDS/301LV BIOSes; Not in 315 BIOS */
-        if(ModeNo > 0x13) data2 &= 0xfc;
+
+     data = 0x03;
+     if((VCLK >= 135) && (VCLK < 160))      data = 0x02;
+     else if((VCLK >= 160) && (VCLK < 260)) data = 0x01;
+     else if(VCLK >= 260)                   data = 0x00;
+
+     if(HwInfo->jChipType == SIS_540) {
+        if((VCLK == 203) || (VCLK < 234))   data = 0x02;
+     }
+
+     if(HwInfo->jChipType < SIS_315H) {
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data);
+     } else {
+        if(HwInfo->jChipType > SIS_315PRO) {
+           if(ModeNo > 0x13) data &= 0xfc;
+        }
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data);
      }
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data2);        /* DAC speed */
+
   }
 }
 
@@ -3022,75 +2933,51 @@ static void
 SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                     USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
 {
-  USHORT data,data2;
-  USHORT infoflag=0,modeflag;
+  USHORT data,infoflag=0,modeflag;
   USHORT resindex,xres;
 #ifdef SIS315H
-  USHORT data3;
+  USHORT data2,data3;
   ULONG  longdata;
-#if 0
-  resinfo = 0;
-#endif
+  UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
 #endif
 
   if(SiS_Pr->UseCustomMode) {
      modeflag = SiS_Pr->CModeFlag;
      infoflag = SiS_Pr->CInfoFlag;
+     xres = SiS_Pr->CHDisplay;
   } else {
+     resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
      if(ModeNo > 0x13) {
        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
        infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-#ifdef SIS315H
-#if 0
-       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-#endif
-#endif
+       xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
      } else {
        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+       xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
      }
   }
 
   /* Disable DPMS */
   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F);
 
-  if(ModeNo > 0x13) data = infoflag;
-  else data = 0;
-
-  data2 = 0;
+  data = 0;
   if(ModeNo > 0x13) {
-     if(SiS_Pr->SiS_ModeType > 0x02) {
-        data2 |= 0x02;
-        data2 |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
-     }
-  }
-
-#ifdef TWDEBUG
-  xf86DrvMsg(0, X_INFO, "Debug: Mode infoflag = %x, Chiptype %d\n",
-       data, HwInfo->jChipType);
-#endif
-
-  if(data & InterlaceMode) data2 |= 0x20;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data2);
-
-  if(SiS_Pr->UseCustomMode) {
-     xres = SiS_Pr->CHDisplay;
-  } else {
-     resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
-     if(ModeNo <= 0x13) {
-       xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
-     } else {
-       xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+     if(SiS_Pr->SiS_ModeType > ModeEGA) {
+        data |= 0x02;
+        data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
      }
+     if(infoflag & InterlaceMode) data |= 0x20;
   }
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data);
 
   if(HwInfo->jChipType != SIS_300) {
-     data = 0x0000;
+     data = 0;
      if(infoflag & InterlaceMode) {
-        if(xres <= 800) data = 0x0020;
+        if(xres <= 800)       data = 0x0020;
         else if(xres <= 1024) data = 0x0035;
-        else data = 0x0048;
+        else                  data = 0x0048;
      }
-     SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,(data & 0x00FF));
+     SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,(data & 0xFF));
      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,(data >> 8));
   }
 
@@ -3098,18 +2985,12 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
   }
 
+  data = 0;
+  if(modeflag & LineCompareOff) data = 0x08;
   if(HwInfo->jChipType == SIS_300) {
-     if(modeflag & LineCompareOff) {
-        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x08);
-     } else {
-        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xF7);
-     }
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data);
   } else {
-     if(modeflag & LineCompareOff) {
-        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08);
-     } else {
-        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
-     }
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
      if(SiS_Pr->SiS_ModeType == ModeEGA) {
         if(ModeNo > 0x13) {
           SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40);
@@ -3117,9 +2998,13 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
      }
   }
 
+  if(HwInfo->jChipType >= SIS_661) {
+     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
+  }
+
 #ifdef SIS315H
-  /* 315 BIOS sets SR17 at this point */
   if(HwInfo->jChipType == SIS_315PRO) {
+
      data = SiS_Get310DRAMType(SiS_Pr, HwInfo);
      data = SiS_Pr->SiS_SR15[2][data];
      if(SiS_Pr->SiS_ModeType == ModeText) {
@@ -3138,12 +3023,18 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
        }
      }
      SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
-  }
 
-  /* 330 BIOS sets SR17 at this point */
-  if(HwInfo->jChipType == SIS_330) {
+  } else if( (HwInfo->jChipType == SIS_330) ||
+             ((HwInfo->jChipType == SIS_760) && (SiS_Pr->SiS_SysFlags & SF_760LFB))) {
+
      data = SiS_Get310DRAMType(SiS_Pr, HwInfo);
-     data = SiS_Pr->SiS_SR15[2][data];
+     if(HwInfo->jChipType == SIS_330) {
+        data = SiS_Pr->SiS_SR15[2][data];
+     } else {
+        if(SiS_Pr->SiS_ROMNew)             data = ROMAddr[0xf6];
+        else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data];
+       else                        data = 0xba;
+     }
      if(SiS_Pr->SiS_ModeType <= ModeEGA) {
         data &= 0xc7;
      } else {
@@ -3156,31 +3047,38 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
        }
 
        data3 = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex) >> 1;
-       if(!data3) data3++;
-
-       data2 *= data3;
+       if(data3) data2 *= data3;
 
        longdata = SiS_GetMCLK(SiS_Pr, HwInfo) * 1024;
 
        data2 = longdata / data2;
 
-       if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
-           if(data2 >= 0x19c)      data = 0xba;
-          else if(data2 >= 0x140) data = 0x7a;
-          else if(data2 >= 0x101) data = 0x3a;
-          else if(data2 >= 0xf5)  data = 0x32;
-          else if(data2 >= 0xe2)  data = 0x2a;
-          else if(data2 >= 0xc4)  data = 0x22;
-          else if(data2 >= 0xac)  data = 0x1a;
-          else if(data2 >= 0x9e)  data = 0x12;
-          else if(data2 >= 0x8e)  data = 0x0a;
+       if(HwInfo->jChipType == SIS_330) {
+          if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
+              if     (data2 >= 0x19c) data = 0xba;
+             else if(data2 >= 0x140) data = 0x7a;
+             else if(data2 >= 0x101) data = 0x3a;
+             else if(data2 >= 0xf5)  data = 0x32;
+             else if(data2 >= 0xe2)  data = 0x2a;
+             else if(data2 >= 0xc4)  data = 0x22;
+             else if(data2 >= 0xac)  data = 0x1a;
+             else if(data2 >= 0x9e)  data = 0x12;
+             else if(data2 >= 0x8e)  data = 0x0a;
+             else                    data = 0x02;
+          } else {
+             if(data2 >= 0x127)      data = 0xba;
+             else                    data = 0x7a;
+          }
+       } else {  /* 760+LFB */
+          if     (data2 >= 0x190) data = 0xba;
+          else if(data2 >= 0xff)  data = 0x7a;
+          else if(data2 >= 0xd3)  data = 0x3a;
+          else if(data2 >= 0xa9)  data = 0x1a;
+          else if(data2 >= 0x93)  data = 0x0a;
           else                    data = 0x02;
-        } else {
-          if(data2 >= 0x127)      data = 0xba;
-          else                    data = 0x7a;
-        }
-      }
-      SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
+       }
+     }
+     SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
   }
 #endif
 
@@ -3202,46 +3100,6 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
      } else {
         SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c);
      }
-#if 0   /* What is SR0E[D5:6]? */
-     if(HwInfo->jChipType >= SIS_661) {
-        data = 0;
-        if((ModeNo == 6) || ((ModeNo >= 0x0e) && (ModeNo <= 0x13))) {
-          data |= 0x20;
-       }
-       if(SiS_Pr->SiS_ModeType != ModeVGA) {
-          if(SiS_Pr->UseCustomMode) {
-              if((xres >= 640) && (SiS_Pr->CVDisplay >= 480)) {
-                data |= 0x40;
-             }
-             if((xres > 1280) && (SiS_Pr->CVDisplay > 1024)) {
-                data |= 0x60;
-             }
-          }
-       } else if(ModeNo > 0x13) {   /* These are in the CRT1 table, and set by CRT1CRTC */
-          if(resinfo >= SIS_RI_640x480) {
-             if(resinfo <= SIS_RI_2048x1536) {
-                data |= 0x40;
-                if(resinfo > SIS_RI_1280x1024) {
-                   data |= 0x60;
-                   if(resinfo != SIS_RI_1600x1200) {
-                      data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x0e);
-                      data += 0x60;
-                      SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e);
-                      data = 0;
-                   }
-                }
-             }
-             if(resinfo == SIS_RI_1152x864) {
-                data = 0x40;
-             }
-             if(resinfo == SIS_RI_1400x1050) { /* TW */
-                data = 0x60;
-             }
-          }
-       }
-       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0e,data);
-     }
-#endif
   }
 #endif
 }
@@ -3416,7 +3274,7 @@ SiS_SetCRT1Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   SiS_SetCRTCRegs(SiS_Pr, HwInfo, StandTableIndex);
   SiS_SetATTRegs(SiS_Pr, StandTableIndex, HwInfo);
   SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
-  SiS_ClearExt1Regs(SiS_Pr,HwInfo);
+  SiS_ClearExt1Regs(SiS_Pr, HwInfo, ModeNo);
   SiS_ResetCRT1VCLK(SiS_Pr, HwInfo);
 
   SiS_Pr->SiS_SelectCRT2Rate = 0;
@@ -3482,21 +3340,28 @@ SiS_SetCRT1Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 }
 
 /*********************************************/
-/*            HELPER: ENABLE CRT1            */
+/*         HELPER: RESET VIDEO BRIDGE        */
 /*********************************************/
 
 static void
-SiS_HandleCRT1(SiS_Private *SiS_Pr)
+SiS_ResetVB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
-#if 0
-  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
-     if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
-        (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
-        SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
-     }
-  }
-#endif
+   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+   USHORT temp;
+
+   if(SiS_Pr->SiS_UseROM) {
+      if(HwInfo->jChipType < SIS_330) {
+         temp = ROMAddr[VB310Data_1_2_Offset] | 0x40;
+        if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
+         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+      } else if(HwInfo->jChipType >= SIS_661) {
+         temp = ROMAddr[0x7e];
+         if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80];
+         if(HwInfo->jChipType >= SIS_660)                  temp |= 0x40;
+         else if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x7b) >= 100) temp |= 0x40;
+         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+      }
+   }
 }
 
 /*********************************************/
@@ -3585,13 +3450,12 @@ BOOLEAN
 SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
 #endif
 {
-   ULONG   temp;
    USHORT  ModeIdIndex;
-   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
    SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
    unsigned char backupreg=0;
 #ifndef LINUX_XF86
    USHORT  KeepLockReg;
+   ULONG   temp;
 
    SiS_Pr->UseCustomMode = FALSE;
    SiS_Pr->CRT1UsesCustomMode = FALSE;
@@ -3605,7 +3469,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
    SiSRegInit(SiS_Pr, BaseAddr);
    SiS_GetSysFlags(SiS_Pr, HwInfo);
 
-#ifdef LINUX_XF86
+#if defined(LINUX_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
    if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
    else
 #endif
@@ -3615,20 +3479,13 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
    SiSSetLVDSetc(SiS_Pr, HwInfo);
    SiSDetermineROMUsage(SiS_Pr, HwInfo);
 
-   if(!SiS_Pr->UseCustomMode) {
-      ModeNo = ((ModeNo & 0x80) << 8) | (ModeNo & 0x7f);
-   }
+   SiS_Pr->SiS_flag_clearbuffer = 0;
 
-#ifdef LINUX_XF86
-   /* We never clear the buffer in X */
-   ModeNo |= 0x8000;
+   if(!SiS_Pr->UseCustomMode) {
+#ifndef LINUX_XF86
+      if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
 #endif
-
-   if(ModeNo & 0x8000) {
-       ModeNo &= 0x7fff;
-       SiS_Pr->SiS_flag_clearbuffer = 0;
-   } else {
-       SiS_Pr->SiS_flag_clearbuffer = 1;
+      ModeNo &= 0x7f;
    }
 
 #ifndef LINUX_XF86
@@ -3650,23 +3507,9 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
 
    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
       if(HwInfo->jChipType >= SIS_315H) {
-         SiS_UnLockCRT2(SiS_Pr,HwInfo);
-        if(ROMAddr && SiS_Pr->SiS_UseROM) {
-           if(HwInfo->jChipType < SIS_330) {
-               temp = ROMAddr[VB310Data_1_2_Offset];
-              temp |= 0x40;
-              SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
-            }
-           if(HwInfo->jChipType > SIS_330) {
-              temp = ROMAddr[0x7e];
-              if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x7b) >= 100) temp |= 0x40;
-              SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
-           }
-        }
+         SiS_ResetVB(SiS_Pr, HwInfo);
         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
-
         SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
-
          backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
       } else {
          backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
@@ -3687,27 +3530,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
 #endif
 
    if(HwInfo->jChipType >= SIS_315H) {
-#if 0
-      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
-         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-            if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
-         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
-            SiS_Pr->SiS_SetFlag |= SetDOSMode;
-         }
-      }
-#endif
-
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-         if(IS_SIS650) {
-           SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
-           if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
-           SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
-        } else if(IS_SIS661741660760) {
-           SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
-           SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
-           SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
-        }
-      }
+      SiS_SetupCR5x(SiS_Pr, HwInfo);
    }
 
    if(SiS_Pr->UseCustomMode) {
@@ -3751,7 +3574,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
 
    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
       if(HwInfo->jChipType >= SIS_315H) {
-         if(HwInfo->jChipType < SIS_661) {
+         if(!SiS_Pr->SiS_ROMNew) {
            if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
               SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
            } else {
@@ -3840,9 +3663,7 @@ BOOLEAN
 SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
                DisplayModePtr mode, BOOLEAN IsCustom)
 {
-   ULONG   temp;
    USHORT  ModeIdIndex;
-   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
    SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
    UShort  ModeNo   = 0;
    unsigned char backupreg=0;
@@ -3879,7 +3700,11 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
    SiSRegInit(SiS_Pr, BaseAddr);
    SiSInitPtr(SiS_Pr, HwInfo);
    SiS_GetSysFlags(SiS_Pr, HwInfo);
+#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
    SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+#else
+   SiS_Pr->SiS_VGAINFO = 0x11;
+#endif
    SiSInitPCIetc(SiS_Pr, HwInfo);
    SiSSetLVDSetc(SiS_Pr, HwInfo);
    SiSDetermineROMUsage(SiS_Pr, HwInfo);
@@ -3941,23 +3766,9 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
 
    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
       if(HwInfo->jChipType >= SIS_315H) {
-         SiS_UnLockCRT2(SiS_Pr,HwInfo);
-         if(ROMAddr && SiS_Pr->SiS_UseROM) {
-           if(HwInfo->jChipType < SIS_330) {
-               temp = ROMAddr[VB310Data_1_2_Offset];
-              temp |= 0x40;
-               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
-            }
-           if(HwInfo->jChipType > SIS_330) {
-              temp = ROMAddr[0x7e];
-              if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x7b) >= 100) temp |= 0x40;
-              SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
-           }
-        }
+        SiS_ResetVB(SiS_Pr, HwInfo);
         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
-
         SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
-
          backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
       } else {
          backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
@@ -3999,7 +3810,7 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
 
    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
       if(HwInfo->jChipType >= SIS_315H) {
-         if(HwInfo->jChipType < SIS_661) {
+         if(!SiS_Pr->SiS_ROMNew) {
            if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
               SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
            } else {
@@ -4069,7 +3880,11 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
    SiSInitPtr(SiS_Pr, HwInfo);
    SiSRegInit(SiS_Pr, BaseAddr);
    SiS_GetSysFlags(SiS_Pr, HwInfo);
+#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
    SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+#else
+   SiS_Pr->SiS_VGAINFO = 0x11;
+#endif
    SiSInitPCIetc(SiS_Pr, HwInfo);
    SiSSetLVDSetc(SiS_Pr, HwInfo);
    SiSDetermineROMUsage(SiS_Pr, HwInfo);
@@ -4107,27 +3922,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
    SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
 
    if(HwInfo->jChipType >= SIS_315H) {
-#if 0
-      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
-         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-            if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
-         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
-            SiS_Pr->SiS_SetFlag |= SetDOSMode;
-         }
-      }
-#endif
-
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-         if(IS_SIS650) {
-           SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
-           if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
-           SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
-        } else if(IS_SIS661741660760) {
-           SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
-           SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
-           SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
-        }
-      }
+      SiS_SetupCR5x(SiS_Pr, HwInfo);
    }
 
    /* Set mode on CRT1 */
@@ -4296,12 +4091,188 @@ SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 }
 #endif
 
+#ifndef GETBITSTR
+#define BITMASK(h,l)           (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
+#define GENMASK(mask)          BITMASK(1?mask,0?mask)
+#define GETBITS(var,mask)      (((var) & GENMASK(mask)) >> (0?mask))
+#define GETBITSTR(val,from,to)  ((GETBITS(val,from)) << (0?to))
+#endif
+
+static void
+SiS_CalcCRRegisters(SiS_Private *SiS_Pr, int depth)
+{
+   SiS_Pr->CCRT1CRTC[0]  =  ((SiS_Pr->CHTotal >> 3) - 5) & 0xff;               /* CR0 */
+   SiS_Pr->CCRT1CRTC[1]  =  (SiS_Pr->CHDisplay >> 3) - 1;                      /* CR1 */
+   SiS_Pr->CCRT1CRTC[2]  =  (SiS_Pr->CHBlankStart >> 3) - 1;                   /* CR2 */
+   SiS_Pr->CCRT1CRTC[3]  =  (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;   /* CR3 */
+   SiS_Pr->CCRT1CRTC[4]  =  (SiS_Pr->CHSyncStart >> 3) + 3;                    /* CR4 */
+   SiS_Pr->CCRT1CRTC[5]  =  ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |  /* CR5 */
+                                   (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
+
+   SiS_Pr->CCRT1CRTC[6]  =  (SiS_Pr->CVTotal - 2) & 0xFF;                      /* CR6 */
+   SiS_Pr->CCRT1CRTC[7]  =  (((SiS_Pr->CVTotal - 2) & 0x100) >> 8)             /* CR7 */
+                         | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
+                         | ((SiS_Pr->CVSyncStart & 0x100) >> 6)
+                         | (((SiS_Pr->CVBlankStart - 1) & 0x100) >> 5)
+                         | 0x10
+                         | (((SiS_Pr->CVTotal - 2) & 0x200)   >> 4)
+                         | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
+                         | ((SiS_Pr->CVSyncStart & 0x200) >> 2);
+
+   SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5);         /* CR9 */
+
+   if(depth != 8) {
+      if(SiS_Pr->CHDisplay >= 1600)      SiS_Pr->CCRT1CRTC[16] |= 0x60;                /* SRE */
+      else if(SiS_Pr->CHDisplay >= 640)  SiS_Pr->CCRT1CRTC[16] |= 0x40;
+   }
+
+#if 0
+   if (mode->VScan >= 32)
+       regp->CRTC[9] |= 0x1F;
+   else if (mode->VScan > 1)
+       regp->CRTC[9] |= mode->VScan - 1;
+#endif
+
+   SiS_Pr->CCRT1CRTC[8] =  (SiS_Pr->CVSyncStart     ) & 0xFF;                  /* CR10 */
+   SiS_Pr->CCRT1CRTC[9] =  ((SiS_Pr->CVSyncEnd      ) & 0x0F) | 0x80;          /* CR11 */
+   SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay    - 1) & 0xFF;                  /* CR12 */
+   SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF;                  /* CR15 */
+   SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd   - 1) & 0xFF;                  /* CR16 */
+
+   SiS_Pr->CCRT1CRTC[13] =                                                     /* SRA */
+                        GETBITSTR((SiS_Pr->CVTotal     -2), 10:10, 0:0) |
+                        GETBITSTR((SiS_Pr->CVDisplay   -1), 10:10, 1:1) |
+                        GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
+                        GETBITSTR((SiS_Pr->CVSyncStart   ), 10:10, 3:3) |
+                        GETBITSTR((SiS_Pr->CVBlankEnd  -1),   8:8, 4:4) |
+                        GETBITSTR((SiS_Pr->CVSyncEnd     ),   4:4, 5:5) ;
+
+   SiS_Pr->CCRT1CRTC[14] =                                                     /* SRB */
+                        GETBITSTR((SiS_Pr->CHTotal      >> 3) - 5, 9:8, 1:0) |
+                        GETBITSTR((SiS_Pr->CHDisplay    >> 3) - 1, 9:8, 3:2) |
+                        GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
+                        GETBITSTR((SiS_Pr->CHSyncStart  >> 3) + 3, 9:8, 7:6) ;
+
+
+   SiS_Pr->CCRT1CRTC[15] =                                                     /* SRC */
+                        GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
+                        GETBITSTR((SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ;
+}
+
+void
+SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+   USHORT modeflag, tempax, tempbx, VGAHDE = SiS_Pr->SiS_VGAHDE;
+   int i,j;
+
+   /* 1:1 data: use data set by setcrt1crtc() */
+   if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
+
+   if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+   } else if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
+   } else {
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+   }
+
+   if(modeflag & HalfDCLK) VGAHDE >>= 1;
+
+   SiS_Pr->CHDisplay = VGAHDE;
+   SiS_Pr->CHBlankStart = VGAHDE;
+
+   SiS_Pr->CVDisplay = SiS_Pr->SiS_VGAVDE;
+   SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE;
+
+   tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
+   tempax = SiS_Pr->SiS_VGAHDE;  /* not /2 ! */
+   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+      tempax = SiS_Pr->PanelXRes;
+   }
+   tempbx += tempax;
+   if(modeflag & HalfDCLK) tempbx -= VGAHDE;
+   SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx;
+
+   tempax = VGAHDE;
+   tempbx = SiS_Pr->CHTotal;
+   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+      tempbx = SiS_Pr->PanelXRes;
+      if(modeflag & HalfDCLK) tempbx >>= 1;
+      tempax += ((tempbx - tempax) >> 1);
+   }
+
+   tempax += SiS_Pr->PanelHRS;
+   SiS_Pr->CHSyncStart = tempax;
+   tempax += SiS_Pr->PanelHRE;
+   SiS_Pr->CHSyncEnd = tempax;
+
+   tempbx = SiS_Pr->PanelVT - SiS_Pr->PanelYRes;
+   tempax = SiS_Pr->SiS_VGAVDE;
+   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+      tempax = SiS_Pr->PanelYRes;
+   }
+   SiS_Pr->CVTotal = SiS_Pr->CVBlankEnd = tempbx + tempax;
+
+   tempax = SiS_Pr->SiS_VGAVDE;
+   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+      tempax += (SiS_Pr->PanelYRes - tempax) >> 1;
+   }
+   tempax += SiS_Pr->PanelVRS;
+   SiS_Pr->CVSyncStart = tempax;
+   tempax += SiS_Pr->PanelVRE;
+   SiS_Pr->CVSyncEnd = tempax;
+
+   SiS_CalcCRRegisters(SiS_Pr, 8);
+   SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
+
+   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
+
+   for(i=0,j=0;i<=7;i++,j++) {
+      SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+   }
+   for(j=0x10;i<=10;i++,j++) {
+      SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+   }
+   for(j=0x15;i<=12;i++,j++) {
+      SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+   }
+   for(j=0x0A;i<=15;i++,j++) {
+      SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
+   }
+
+   tempax = SiS_Pr->CCRT1CRTC[16] & 0xE0;
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1F,tempax);
+
+   tempax = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
+   if(modeflag & DoubleScanMode) tempax |= 0x80;
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax);
+
+#ifdef TWDEBUG
+   xf86DrvMsg(0, X_INFO, "%d %d %d %d  %d %d %d %d  (%d %d %d %d)\n",
+               SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
+       SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
+       SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
+
+   xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
+       SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
+       SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
+       SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
+       SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
+   xf86DrvMsg(0, X_INFO, "   0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
+       SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
+       SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
+       SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
+       SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
+   xf86DrvMsg(0, X_INFO, "   0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
+#endif
+}
 
 /* ================ XFREE86 ================= */
 
 /* Helper functions */
 
 #ifdef LINUX_XF86
+
 USHORT
 SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
 {
@@ -4382,73 +4353,16 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
 
    pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
 
-   pSiS->SiS_Pr->CCRT1CRTC[0]  =  ((pSiS->SiS_Pr->CHTotal >> 3) - 5) & 0xff;
-   pSiS->SiS_Pr->CCRT1CRTC[1]  =  (pSiS->SiS_Pr->CHDisplay >> 3) - 1;
-   pSiS->SiS_Pr->CCRT1CRTC[2]  =  (pSiS->SiS_Pr->CHBlankStart >> 3) - 1;
-   pSiS->SiS_Pr->CCRT1CRTC[3]  =  (((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
-   pSiS->SiS_Pr->CCRT1CRTC[4]  =  (pSiS->SiS_Pr->CHSyncStart >> 3) + 3;
-   pSiS->SiS_Pr->CCRT1CRTC[5]  =  ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |
-                                         (((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
-
-   pSiS->SiS_Pr->CCRT1CRTC[6]  =  (pSiS->SiS_Pr->CVTotal - 2) & 0xFF;
-   pSiS->SiS_Pr->CCRT1CRTC[7]  =  (((pSiS->SiS_Pr->CVTotal - 2) & 0x100) >> 8)
-                               | (((pSiS->SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
-                               | ((pSiS->SiS_Pr->CVSyncStart & 0x100) >> 6)
-                               | (((pSiS->SiS_Pr->CVBlankStart - 1) & 0x100) >> 5)
-                               | 0x10
-                               | (((pSiS->SiS_Pr->CVTotal - 2) & 0x200)   >> 4)
-                               | (((pSiS->SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
-                               | ((pSiS->SiS_Pr->CVSyncStart & 0x200) >> 2);
-
-   pSiS->SiS_Pr->CCRT1CRTC[16] = ((((pSiS->SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5);     /* cr9 */
-
-#if 0
-   if (mode->VScan >= 32)
-       regp->CRTC[9] |= 0x1F;
-   else if (mode->VScan > 1)
-       regp->CRTC[9] |= mode->VScan - 1;
-#endif
-
-   pSiS->SiS_Pr->CCRT1CRTC[8] =  (pSiS->SiS_Pr->CVSyncStart     ) & 0xFF;              /* cr10 */
-   pSiS->SiS_Pr->CCRT1CRTC[9] =  ((pSiS->SiS_Pr->CVSyncEnd      ) & 0x0F) | 0x80;      /* cr11 */
-   pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay    - 1) & 0xFF;              /* cr12 */
-   pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF;              /* cr15 */
-   pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd   - 1) & 0xFF;              /* cr16 */
-
-   pSiS->SiS_Pr->CCRT1CRTC[13] =
-                        GETBITSTR((pSiS->SiS_Pr->CVTotal     -2), 10:10, 0:0) |
-                        GETBITSTR((pSiS->SiS_Pr->CVDisplay   -1), 10:10, 1:1) |
-                        GETBITSTR((pSiS->SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
-                        GETBITSTR((pSiS->SiS_Pr->CVSyncStart   ), 10:10, 3:3) |
-                        GETBITSTR((pSiS->SiS_Pr->CVBlankEnd  -1),   8:8, 4:4) |
-                        GETBITSTR((pSiS->SiS_Pr->CVSyncEnd     ),   4:4, 5:5) ;
-
-   pSiS->SiS_Pr->CCRT1CRTC[14] =
-                        GETBITSTR((pSiS->SiS_Pr->CHTotal      >> 3) - 5, 9:8, 1:0) |
-                        GETBITSTR((pSiS->SiS_Pr->CHDisplay    >> 3) - 1, 9:8, 3:2) |
-                        GETBITSTR((pSiS->SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
-                        GETBITSTR((pSiS->SiS_Pr->CHSyncStart  >> 3) + 3, 9:8, 7:6) ;
-
-
-   pSiS->SiS_Pr->CCRT1CRTC[15] =
-                        GETBITSTR((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
-                        GETBITSTR((pSiS->SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ;
+   SiS_CalcCRRegisters(pSiS->SiS_Pr, depth);
 
    switch(depth) {
-   case 8:
-       pSiS->SiS_Pr->CModeFlag |= 0x223b;
-       break;
-   case 16:
-       pSiS->SiS_Pr->CModeFlag |= 0x227d;
-       break;
-   case 32:
-       pSiS->SiS_Pr->CModeFlag |= 0x22ff;
-       break;          
-   default: 
-       return 0;       
-   }   
-   
-   if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) 
+   case 8:  pSiS->SiS_Pr->CModeFlag |= 0x223b; break;
+   case 16: pSiS->SiS_Pr->CModeFlag |= 0x227d; break;
+   case 32: pSiS->SiS_Pr->CModeFlag |= 0x22ff; break;
+   default: return 0;
+   }
+
+   if(pSiS->SiS_Pr->CFlags & V_DBLSCAN)
       pSiS->SiS_Pr->CModeFlag |= DoubleScanMode;
 
    if((pSiS->SiS_Pr->CVDisplay >= 1024)        ||
@@ -4472,33 +4386,23 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
 
    pSiS->SiS_Pr->UseCustomMode = TRUE;
 #ifdef TWDEBUG
-   xf86DrvMsg(0, X_INFO, "Custom mode %dx%d:\n", 
+   xf86DrvMsg(0, X_INFO, "Custom mode %dx%d:\n",
        pSiS->SiS_Pr->CHDisplay,pSiS->SiS_Pr->CVDisplay);
    xf86DrvMsg(0, X_INFO, "Modeflag %04x, Infoflag %04x\n",
        pSiS->SiS_Pr->CModeFlag, pSiS->SiS_Pr->CInfoFlag);
    xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
-       pSiS->SiS_Pr->CCRT1CRTC[0],
-       pSiS->SiS_Pr->CCRT1CRTC[1],
-       pSiS->SiS_Pr->CCRT1CRTC[2],
-       pSiS->SiS_Pr->CCRT1CRTC[3],
-       pSiS->SiS_Pr->CCRT1CRTC[4],
-       pSiS->SiS_Pr->CCRT1CRTC[5],
-       pSiS->SiS_Pr->CCRT1CRTC[6],
-       pSiS->SiS_Pr->CCRT1CRTC[7]);
+       pSiS->SiS_Pr->CCRT1CRTC[0], pSiS->SiS_Pr->CCRT1CRTC[1],
+       pSiS->SiS_Pr->CCRT1CRTC[2], pSiS->SiS_Pr->CCRT1CRTC[3],
+       pSiS->SiS_Pr->CCRT1CRTC[4], pSiS->SiS_Pr->CCRT1CRTC[5],
+       pSiS->SiS_Pr->CCRT1CRTC[6], pSiS->SiS_Pr->CCRT1CRTC[7]);
    xf86DrvMsg(0, X_INFO, "  0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
-       pSiS->SiS_Pr->CCRT1CRTC[8],
-       pSiS->SiS_Pr->CCRT1CRTC[9],
-       pSiS->SiS_Pr->CCRT1CRTC[10],
-       pSiS->SiS_Pr->CCRT1CRTC[11],
-       pSiS->SiS_Pr->CCRT1CRTC[12],
-       pSiS->SiS_Pr->CCRT1CRTC[13],
-       pSiS->SiS_Pr->CCRT1CRTC[14],
-       pSiS->SiS_Pr->CCRT1CRTC[15]);
+       pSiS->SiS_Pr->CCRT1CRTC[8], pSiS->SiS_Pr->CCRT1CRTC[9],
+       pSiS->SiS_Pr->CCRT1CRTC[10], pSiS->SiS_Pr->CCRT1CRTC[11],
+       pSiS->SiS_Pr->CCRT1CRTC[12], pSiS->SiS_Pr->CCRT1CRTC[13],
+       pSiS->SiS_Pr->CCRT1CRTC[14], pSiS->SiS_Pr->CCRT1CRTC[15]);
    xf86DrvMsg(0, X_INFO, "  0x%02x}},\n", pSiS->SiS_Pr->CCRT1CRTC[16]);
    xf86DrvMsg(0, X_INFO, "Clock: 0x%02x, 0x%02x, %d\n",
-       pSiS->SiS_Pr->CSR2B,
-       pSiS->SiS_Pr->CSR2C,
-       pSiS->SiS_Pr->CSRClock);
+       pSiS->SiS_Pr->CSR2B, pSiS->SiS_Pr->CSR2C, pSiS->SiS_Pr->CSRClock);
 #endif
    return 1;
 }
@@ -4615,7 +4519,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfo
       /* Horizontal display enable end */
       HDE = (cr_data & 0xff) |
             ((unsigned short) (sr_data & 0x0C) << 6);
-      E = HDE + 1;
+      E = HDE + 1;  /* 0x80 0x64 */
 
       cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[4];
        /* inSISIDXREG(SISCR, 0x04, cr_data); */
@@ -4623,7 +4527,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfo
       /* Horizontal retrace (=sync) start */
       HRS = (cr_data & 0xff) |
             ((unsigned short) (sr_data & 0xC0) << 2);
-      F = HRS - E - 3;
+      F = HRS - E - 3;  /* 0x06 0x06 */
 
       cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[2];
        /* inSISIDXREG(SISCR, 0x02, cr_data); */
@@ -4653,7 +4557,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfo
       B = (temp > 0) ? temp : (temp + 256);
 
       temp = HRE - ((E + F + 3) & 63);
-      C = (temp > 0) ? temp : (temp + 64);
+      C = (temp > 0) ? temp : (temp + 64); /* 0x0b 0x0b */
 
       D = B - F - C;
 
@@ -5159,10 +5063,7 @@ sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 int
 sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                         unsigned char modeno, unsigned char rateindex,
-                        ULONG *left_margin, ULONG *right_margin, 
-                        ULONG *upper_margin, ULONG *lower_margin,
-                        ULONG *hsync_len, ULONG *vsync_len,
-                        ULONG *sync, ULONG *vmode)
+                        struct fb_var_screeninfo *var)
 {
     USHORT ModeNo = modeno;
     USHORT ModeIdIndex = 0, index = 0;
@@ -5185,7 +5086,7 @@ sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
        return 0;
 #endif
     }
-    
+
     if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return 0;
 
     RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
@@ -5250,15 +5151,15 @@ sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
         /* Terrible hack, but the correct CRTC data for
          * these modes only produces a black screen...
          */
-       *left_margin = (400 - 376);
-       *right_margin = (328 - 320);
-       *hsync_len = (376 - 328);
+       var->left_margin = (400 - 376);
+       var->right_margin = (328 - 320);
+       var->hsync_len = (376 - 328);
 
     } else {
 
-       *left_margin = D * 8;
-       *right_margin = F * 8;
-       *hsync_len = C * 8;
+       var->left_margin = D * 8;
+       var->right_margin = F * 8;
+       var->hsync_len = C * 8;
 
     }
 
@@ -5320,47 +5221,47 @@ sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 
     D = B - F - C;
       
-    *upper_margin = D;
-    *lower_margin = F;
-    *vsync_len = C;
+    var->upper_margin = D;
+    var->lower_margin = F;
+    var->vsync_len = C;
 
     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
-       *sync &= ~FB_SYNC_VERT_HIGH_ACT;
+       var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
     else
-       *sync |= FB_SYNC_VERT_HIGH_ACT;
+       var->sync |= FB_SYNC_VERT_HIGH_ACT;
 
     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)       
-       *sync &= ~FB_SYNC_HOR_HIGH_ACT;
+       var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
     else
-       *sync |= FB_SYNC_HOR_HIGH_ACT;
+       var->sync |= FB_SYNC_HOR_HIGH_ACT;
                
-    *vmode = FB_VMODE_NONINTERLACED;
+    var->vmode = FB_VMODE_NONINTERLACED;
     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
-       *vmode = FB_VMODE_INTERLACED;
+       var->vmode = FB_VMODE_INTERLACED;
     else {
-      j = 0;
-      while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
+       j = 0;
+       while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
           if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
                          SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID) {
               if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
-                 *vmode = FB_VMODE_DOUBLE;
+                 var->vmode = FB_VMODE_DOUBLE;
               }
              break;
           }
          j++;
-      }
+       }
     }       
 
-    if((*vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+    if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
 #if 0  /* Do this? */
-       *upper_margin <<= 1;
-       *lower_margin <<= 1;
-       *vsync_len <<= 1;
+       var->upper_margin <<= 1;
+       var->lower_margin <<= 1;
+       var->vsync_len <<= 1;
 #endif
-    } else if((*vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-       *upper_margin >>= 1;
-       *lower_margin >>= 1;
-       *vsync_len >>= 1;
+    } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+       var->upper_margin >>= 1;
+       var->lower_margin >>= 1;
+       var->vsync_len >>= 1;
     }
 
     return 1;       
index bcee315..05d1881 100644 (file)
@@ -1,4 +1,5 @@
 /* $XFree86$ */
+/* $XdotOrg$ */
 /*
  * Data and prototypes for init.c
  *
  * * 2) Redistributions in binary form must reproduce the above copyright
  * *    notice, this list of conditions and the following disclaimer in the
  * *    documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * *    must display the following acknowledgement: "This product includes
- * *    software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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,
@@ -101,6 +99,7 @@ const USHORT  ModeIndex_800x480[]      = {0x70, 0x7a, 0x00, 0x76};
 const USHORT  ModeIndex_800x600[]      = {0x30, 0x47, 0x00, 0x63};
 const USHORT  ModeIndex_848x480[]      = {0x39, 0x3b, 0x00, 0x3e};
 const USHORT  ModeIndex_856x480[]      = {0x3f, 0x42, 0x00, 0x45};
+const USHORT  ModeIndex_960x540[]      = {0x1d, 0x1e, 0x00, 0x1f};  /* 315 series only */
 const USHORT  ModeIndex_1024x768[]     = {0x38, 0x4a, 0x00, 0x64};
 const USHORT  ModeIndex_1024x576[]     = {0x71, 0x74, 0x00, 0x77};
 const USHORT  ModeIndex_1024x600[]     = {0x20, 0x21, 0x00, 0x22};  /* 300 series only */
@@ -111,10 +110,13 @@ const USHORT  ModeIndex_1152x864[]     = {0x29, 0x2a, 0x00, 0x2b};
 const USHORT  ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b};
 const USHORT  ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25};
 const USHORT  ModeIndex_1280x720[]     = {0x79, 0x75, 0x00, 0x78};
+const USHORT  ModeIndex_1280x800[]     = {0x14, 0x15, 0x00, 0x16};
 const USHORT  ModeIndex_1360x768[]     = {0x48, 0x4b, 0x00, 0x4e};
 const USHORT  ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72};  /* 300 series, BARCO only */
 const USHORT  ModeIndex_1400x1050[]    = {0x26, 0x27, 0x00, 0x28};  /* 315 series only */
+const USHORT  ModeIndex_1680x1050[]    = {0x17, 0x18, 0x00, 0x19};  /* 315 series only */
 const USHORT  ModeIndex_1600x1200[]    = {0x3c, 0x3d, 0x00, 0x66};
+const USHORT  ModeIndex_1920x1080[]    = {0x2c, 0x2d, 0x00, 0x73};  /* 315 series only */
 const USHORT  ModeIndex_1920x1440[]    = {0x68, 0x69, 0x00, 0x6b};
 const USHORT  ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
 const USHORT  ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
@@ -253,9 +255,14 @@ static const SiS_ModeResInfoStruct SiS_ModeResInfo[] =
        { 1024, 600, 8,16},   /* 0x19 */
        { 1152, 768, 8,16},   /* 0x1a */
        {  768, 576, 8,16},   /* 0x1b */
-       { 1360,1024, 8,16}    /* 0x1c */
+       { 1360,1024, 8,16},   /* 0x1c */
+       { 1680,1050, 8,16},   /* 0x1d */
+       { 1280, 800, 8,16},   /* 0x1e */
+       { 1920,1080, 8,16},   /* 0x1f */
+       {  960, 540, 8,16}    /* 0x20 */
 };
 
+#if defined(SIS300) || defined(SIS315H)
 static SiS_StandTableStruct SiS_StandTable[]=
 {
 /* 0x00: MD_0_200 */
@@ -694,6 +701,7 @@ static SiS_StandTableStruct SiS_StandTable[]=
    0xff}
  }
 };
+#endif
 
 /**************************************************************/
 /* SIS VIDEO BRIDGE ----------------------------------------- */
@@ -839,7 +847,8 @@ static const SiS_TVDataStruct  SiS_ExtPALData[] =
  {   36,  25,1060, 648,1270, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},  /* 800x600, 400x300 - better */
  {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},  /* 720x576 */
  {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20},  /* 1024x768 */
- {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}   /* 1024x768 (for NTSC equ) */
+ {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20},  /* 1024x768 (for NTSC equ) */
+ {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a}   /* 720x480 test */
 };
 
 static const SiS_TVDataStruct  SiS_StNTSCData[] =
@@ -921,6 +930,22 @@ static const SiS_TVDataStruct  SiS_St750pData[] =
 
 static const SiS_TVDataStruct  SiS_Ext750pData[] =
 {
+#if 1
+ {  143,  65, 0x35a,0x1bb,0x4f6,0x1b8,0x0ab,  0, 0x0ab, 0x00,0x00,0x00,0x00},
+ {   88,  35, 0x35a,0x189,0x4f6,0x1b8,0x0ab,  0, 0x0ab, 0x00,0x00,0x00,0x00},
+ {   18,   5, 0x339,0x1ae,0x500,0x2d0,0x05c,  0, 0x05c, 0x00,0x00,0x00,0x00},
+ {  143,  70, 0x39c,0x189,0x4f6,0x1b8,0x05c,  0, 0x05c, 0x00,0x00,0x00,0x00},
+ {   99,  32, 0x320,0x1fe,0x500,0x2d0,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 640x480  */
+ {    5,   4, 0x5d8,0x29e,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 800x600  */
+#if 0
+ {    2,   1, 0x35a,0x1f7,0x4f6,0x1e0,    0,128,     0, 0x00,0x00,0x00,0x00},  /* 720x480  */
+#endif
+ {   99,  32, 0x320,0x1fe,0x500,0x2d0,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 720x480 test WORKS */
+ {   68,  64, 0x55f,0x346,0x500,0x2a8,0x27e,  0,     0, 0x00,0x00,0x00,0x00},  /* 1024x768 */
+ {    5,   2, 0x3a7,0x226,0x500,0x2a8,    0,128,     0, 0x00,0x00,0x00,0x00},  /* 720x576  */
+ {   25,  24, 0x5d8,0x2f3,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00}   /* 1280x720 WORKS */
+#endif
+#if 0
  {    3,   1, 0x3a7,0x1d6,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},
  {   24,   7, 0x3a7,0x1a4,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},
  {    3,   1, 0x3a7,0x1d6,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},
@@ -929,63 +954,105 @@ static const SiS_TVDataStruct  SiS_Ext750pData[] =
  {    5,   4, 0x5d8,0x29e,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 800x600   */
  {    2,   1, 0x35a,0x1f7,0x4f6,0x1e0,    0,128,     0, 0x00,0x00,0x00,0x00},  /* 720x480   */
  {   68,  64, 0x55f,0x346,0x500,0x2a8,0x27e,  0,     0, 0x00,0x00,0x00,0x00},  /* 1024x768  */
+ {   25,  24, 0x5d8,0x2f3,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00}   /* 1280x720  */
+#endif
+#if 0
+ {  136,  35, 0x339,0x181,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* TEST (0.93) BAD */
+ {   17,   6, 0x339,0x203,0x460,0x2a8,   50,  0,    50, 0x00,0x00,0x00,0x00},
+ {  136,  35, 0x339,0x181,0x460,0x2a8,   50,  0,    50, 0x00,0x00,0x00,0x00},
+ {   17,   6, 0x339,0x203,0x460,0x2a8,   50,  0,    50, 0x00,0x00,0x00,0x00},
+ {   85,  46, 0x3f4,0x27b,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 640x480   */
+ {   17,  16, 0x55f,0x323,0x460,0x2a8,0x2b6,  0,     0, 0x00,0x00,0x00,0x00},  /* 800x600   */
+ {  136,  35, 0x339,0x181,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 720x480   */
+ {  187,  74, 0x39d,0x203,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 1024x768  */
+ {   25,  24, 0x5d8,0x2f3,0x460,0x2a8,   50,  0,    50, 0x00,0x00,0x00,0x00}   /* 1280x720  */
+#endif
 };
 
-static const SiS_LCDDataStruct  SiS_LCD1280x960Data[] =
+static const SiS_LCDDataStruct  SiS_LCD1280x720Data[] =
 {
-       {    9,   2, 800, 500,1800,1000},
-       {    9,   2, 800, 500,1800,1000},
-       {    4,   1, 900, 500,1800,1000},
-       {    4,   1, 900, 500,1800,1000},
-       {    9,   2, 800, 500,1800,1000},
-       {   30,  11,1056, 625,1800,1000},
-       {    5,   3,1350, 800,1800,1000},
-       {    1,   1,1576,1050,1576,1050},
-       {    1,   1,1800,1000,1800,1000}
+       {  14,    5,  864,  432, 1344,  806 }, /* 640x400 */
+       {  16,    5,  864,  378, 1344,  806 },
+       {  14,    5,  864,  432, 1344,  806 },
+       {  16,    5,  864,  378, 1344,  806 },
+       {  24,   11,  924,  523, 1344,  806 }, /* 640x480 */
+       {   7,    5, 1152,  664, 1344,  806 }, /* 800x600 */
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   1,    1, 1344,  806, 1344,  806 }  /* 1280x720 */
 };
 
-/* 1280x768 panel data from Fujitsu 7911 (VL-17WDX8).
- * Other 1280x768 panels (with clock != 81000, HTxVT != 1688x802)
- * will be treated as custom panels.
+/* About 1280x768: For TMDS, Panel_1280x768 will only be set if
+ * the panel is a Fujitsu 7911 (VL-17WDX8) (with clock 81, 1688x802)
+ * Other TMDS panels of this resolution will be treated as custom.
+ * For LVDS, we know two types. Data follows:
  */
 
-static const SiS_LCDDataStruct  SiS_StLCD1280x768Data[] =
+static const SiS_LCDDataStruct  SiS_StLCD1280x768_2Data[] =
+{
+       {  64,   21,  858,  434, 1408,  806 }, /* 640x400 */
+       {  32,    9,  858,  372, 1408,  806 },
+       {  64,   21,  858,  434, 1408,  806 },
+       {  32,    9,  858,  372, 1408,  806 },
+       { 143,   68, 1024,  527, 1408,  806 }, /* 640x480 */
+       {  64,   51, 1364,  663, 1408,  806 }, /* 800x600 */
+       {  88,   81, 1296,  806, 1408,  806 }, /* 1024x768 */
+       {   0,    0,    0,    0,    0,    0 },
+       {   1,    1, 1408,  806, 1408,  806 }  /* 1280x768 */
+};
+
+static const SiS_LCDDataStruct  SiS_ExtLCD1280x768_2Data[] =
+{
+       {  64,   25, 1056,  422, 1408,  806 }, /*, 664 */
+       { 128,   39,  884,  396, 1408,  806 }, /*, 640 */
+       {  64,   25, 1056,  422, 1408,  806 }, /*, 664 */
+       { 128,   39,  884,  396, 1408,  806 }, /*, 640 */
+       {  32,   15, 1056,  513, 1408,  806 }, /*, 664 */
+       { 176,  125, 1280,  640, 1408,  806 }, /*, 768 */
+       {  88,   81, 1296,  806, 1408,  806 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   1,    1, 1408,  806, 1408,  806 }
+};
+
+static const SiS_LCDDataStruct  SiS_LCD1280x768_3Data[] =
 {
-       { 211,  100, 2100,  408, 1688,  802 }, /* These values are *wrong* */
-       { 211,   64, 1536,  358, 1688,  802 }, /* (which is why they aren't used yet) */
-       { 211,  100, 2100,  408, 1688,  802 },
-       { 211,   64, 1536,  358, 1688,  802 },
-       { 211,   48,  840,  488, 1688,  802 },
-       { 211,   72, 1008,  609, 1688,  802 },
-       { 211,  128, 1400,  776, 1688,  802 },
-       { 211,  205, 1680, 1041, 1688,  802 },
-       { 1,      1, 1688,  802, 1688,  802 }  /* That's the only one that is correct */
+       {  64,   25, 1056,  422, 1664,  798 },                  /* 640x400 */
+       { 128,   39,  884,  396, 1408,  806 }, /* ,640 */
+       {  64,   25, 1056,  422, 1664,  798 },                  /* 640x400 */
+       { 128,   39,  884,  396, 1408,  806 }, /* ,640 */
+       {  32,   15, 1056,  513, 1408,  806 }, /* ,664 */       /* 640x480 */
+       { 176,  125, 1280,  640, 1408,  806 }, /* ,768 */       /* 800x600 */
+       {  64,   61, 1342,  806, 1408,  806 },                  /* 1024x768 */
+       {   0,    0,    0,    0,    0,    0 },
+       {   1,    1, 1408,  806, 1408,  806 }                   /* 1280x768 */
 };
 
-static const SiS_LCDDataStruct  SiS_ExtLCD1280x768Data[] =
+static const SiS_LCDDataStruct  SiS_LCD1280x800Data[] =
 {
-       { 211,  100, 2100,  408, 1688,  802 }, /* These values are *wrong* */
-       { 211,   64, 1536,  358, 1688,  802 }, /* (which is why they aren't used yet) */
-       { 211,  100, 2100,  408, 1688,  802 },
-       { 211,   64, 1536,  358, 1688,  802 },
-       { 211,   48,  840,  488, 1688,  802 },
-       { 211,   72, 1008,  609, 1688,  802 },
-       { 211,  128, 1400,  776, 1688,  802 },
-       { 211,  205, 1680, 1041, 1688,  802 },
-       { 1,      1, 1688,  802, 1688,  802 }  /* That's the only one that is correct */
+       { 128,   51, 1122,  412, 1408,  816 }, /* 640x400 */
+       { 128,   49, 1232,  361, 1408,  816 },
+       { 128,   51, 1122,  412, 1408,  816 },
+       { 128,   49, 1232,  361, 1408,  816 },
+       {   8,    3,  880,  491, 1408,  816 }, /* 640x480 */
+       {  11,    6, 1024,  612, 1408,  816 }, /* 800x600 */
+       {  22,   21, 1400,  784, 1408,  816 }, /* 1024x768 */
+       {   0,    0,    0,    0,    0,    0 },
+       {   1,    1, 1408,  816, 1408,  816 }  /* 1280x800 */
 };
 
-static const SiS_LCDDataStruct  SiS_NoScaleData1280x768[] =
+static const SiS_LCDDataStruct  SiS_LCD1280x960Data[] =
 {
-        { 1, 1, 1688,  802, 1688,  802},
-       { 1, 1, 1688,  802, 1688,  802},
-       { 1, 1, 1688,  802, 1688,  802},
-       { 1, 1, 1688,  802, 1688,  802},
-       { 1, 1, 1688,  802, 1688,  802},
-       { 1, 1, 1688,  802, 1688,  802},
-       { 1, 1, 1688,  802, 1688,  802},
-       { 1, 1, 1688,  802, 1688,  802},
-       { 1, 1, 1688,  802, 1688,  802}
+       {    9,   2,  800,  500, 1800, 1000 },
+       {    9,   2,  800,  500, 1800, 1000 },
+       {    4,   1,  900,  500, 1800, 1000 },
+       {    4,   1,  900,  500, 1800, 1000 },
+       {    9,   2,  800,  500, 1800, 1000 },
+       {   30,  11, 1056,  625, 1800, 1000 },
+       {    5,   3, 1350,  800, 1800, 1000 },
+       {    1,   1, 1576, 1050, 1576, 1050 },
+       {    1,   1, 1800, 1000, 1800, 1000 }
 };
 
 static const SiS_LCDDataStruct  SiS_StLCD1400x1050Data[] =
@@ -1003,28 +1070,37 @@ static const SiS_LCDDataStruct  SiS_StLCD1400x1050Data[] =
 
 static const SiS_LCDDataStruct  SiS_ExtLCD1400x1050Data[] =
 {
-       { 211,  100, 2100,  408, 1688, 1066 },
+/*     { 211,   60, 1260,  410, 1688, 1066 },    640x400 (6330) */
+       { 211,  100, 2100,  408, 1688, 1066 }, /* 640x400 (6325) WORKS */
        { 211,   64, 1536,  358, 1688, 1066 },
        { 211,  100, 2100,  408, 1688, 1066 },
        { 211,   64, 1536,  358, 1688, 1066 },
-       { 211,   48,  840,  488, 1688, 1066 },
-       { 211,   72, 1008,  609, 1688, 1066 },
-       { 211,  128, 1400,  776, 1688, 1066 },
-       { 211,  205, 1680, 1041, 1688, 1066 },
-       {   1,    1, 1688, 1066, 1688, 1066 }
-};
-
-static const SiS_LCDDataStruct  SiS_NoScaleData1400x1050[] =
-{
-       { 1, 1, 1688, 1066, 1688, 1066 },
-       { 1, 1, 1688, 1066, 1688, 1066 },
-       { 1, 1, 1688, 1066, 1688, 1066 },
-       { 1, 1, 1688, 1066, 1688, 1066 },
-       { 1, 1, 1688, 1066, 1688, 1066 },
-       { 1, 1, 1688, 1066, 1688, 1066 },
-       { 1, 1, 1688, 1066, 1688, 1066 },
-       { 1, 1, 1688, 1066, 1688, 1066 },
-       { 1, 1, 1688, 1066, 1688, 1066 }
+/*     { 211,   80, 1400,  490, 1688, 1066 },    640x480 (6330) */
+       { 211,   48,  840,  488, 1688, 1066 }, /* 640x480 (6325) WORKS */
+/*     { 211,  117, 1638,  613, 1688, 1066 },    800x600 (6330) */
+       { 211,   72, 1008,  609, 1688, 1066 }, /* 800x600 (6325) WORKS */
+       { 211,  128, 1400,  776, 1688, 1066 }, /* 1024x768 */
+       { 211,  205, 1680, 1041, 1688, 1066 }, /* 1280x1024 - not used (always unscaled) */
+       {   1,    1, 1688, 1066, 1688, 1066 }, /* 1400x1050 */
+       {   0,    0,    0,    0,    0,    0 }, /* kludge */
+       { 211,  120, 1400,  730, 1688, 1066 }  /* 1280x720 */
+};
+
+static const SiS_LCDDataStruct  SiS_LCD1680x1050Data[] =
+{
+       {  95,   24, 1260,  410, 1900, 1066 }, /*  0 640x400 */
+       {  10,    3, 1710,  362, 1900, 1066 },
+       {  95,   24, 1260,  410, 1900, 1066 },
+       {  10,    3, 1710,  362, 1900, 1066 },
+       {  95,   32, 1400,  490, 1900, 1066 }, /*  4 640x480 */
+       {  95,   42, 1470,  610, 1900, 1066 }, /*  5 800x600 */
+       {  95,   64, 1750,  784, 1900, 1066 }, /*  6 1024x768 */
+       {  95,   94, 1900, 1055, 1900, 1066 }, /*  7 1280x1024 */
+       {  41,   31, 1900,  806, 1900, 1066 }, /*  8 1280x768 */
+       {  95,   69, 1800,  817, 1900, 1066 }, /*  9 1280x800 patch */
+       {  13,    9, 1900,  739, 1900, 1066 }, /* 10 1280x720 */
+       {  95,   94, 1880, 1066, 1900, 1066 }, /* 11 1400x1050 patch */
+       {   1,    1, 1900, 1066, 1900, 1066 }  /* 12 1680x1050 */
 };
 
 static const SiS_LCDDataStruct  SiS_StLCD1600x1200Data[] =
@@ -1037,440 +1113,59 @@ static const SiS_LCDDataStruct  SiS_StLCD1600x1200Data[] =
        { 4,  1,1080, 625, 2160, 1250 },
        { 5,  2,1350, 800, 2160, 1250 },
        {135,88,1600,1100, 2160, 1250 },
-       {135,88,1600,1100, 2160, 1250 },
+       {72, 49,1680,1092, 2160, 1250 },
        { 1,  1,2160,1250, 2160, 1250 }
 };
 
 static const SiS_LCDDataStruct  SiS_ExtLCD1600x1200Data[] =
 {
-       {27, 4, 800, 500, 2160, 1250 },
+       {72,11, 990, 422, 2160, 1250 }, /* 640x400 (6330) WORKS */
+/*     {27, 4, 800, 500, 2160, 1250 },    640x400 (6235) */
        {27, 4, 800, 500, 2160, 1250 },
        { 6, 1, 900, 500, 2160, 1250 },
        { 6, 1, 900, 500, 2160, 1250 },
-       {27, 1, 800, 500, 2160, 1250 },
+       {45, 8, 960, 505, 2160, 1250 }, /* 640x480 (6330) WORKS */
+/*     {27, 1, 800, 500, 2160, 1250 },    640x480 (6325) */
        { 4, 1,1080, 625, 2160, 1250 },
        { 5, 2,1350, 800, 2160, 1250 },
-       {27,16,1500,1064, 2160, 1250 },
-       {27,16,1500,1064, 2160, 1250 },
+       {27,16,1500,1064, 2160, 1250 }, /* 1280x1024 */
+       {72,49,1680,1092, 2160, 1250 }, /* 1400x1050 (6330, was not supported on 6325) */
        { 1, 1,2160,1250, 2160, 1250 }
 };
 
-static const SiS_LCDDataStruct  SiS_NoScaleData1600x1200[] =
-{
-        {1,  1, 2160, 1250, 2048, 1250},
-       {1,  1, 2160, 1250, 2048, 1250},
-       {1,  1, 2160, 1250, 2048, 1250},
-       {1,  1, 2160, 1250, 2048, 1250},
-       {1,  1, 2160, 1250, 2048, 1250},
-       {1,  1, 2160, 1250, 2048, 1250},
-       {1,  1, 2160, 1250, 2048, 1250},
-       {1,  1, 2160, 1250, 2048, 1250},
-       {1,  1, 2160, 1250, 2048, 1250},
-       {1,  1, 2160, 1250, 2048, 1250},
-};
-
 static const SiS_LCDDataStruct  SiS_NoScaleData[] =
 {
-       { 1, 1, 800, 449, 800, 449 },
+       { 1, 1, 800, 449, 800, 449 },  /* 0x00: 320x200, 640x400 */
        { 1, 1, 800, 449, 800, 449 },
        { 1, 1, 900, 449, 900, 449 },
        { 1, 1, 900, 449, 900, 449 },
-       { 1, 1, 800, 525, 800, 525 },
-       { 1, 1,1056, 628,1056, 628 },
-       { 1, 1,1344, 806,1344, 806 },
-       { 1, 1,1688,1066,1688,1066 },
-        { 1, 1,1688, 802,1688, 802 },  /* 1280x768: 802 was 806 in both cases */
-        { 1, 1,2160,1250,2160,1250 },  /* 1600x1200 */
-       { 1, 1,1800,1000,1800,1000 }   /* 1280x960 */
-};
-
-/* *** LCDA *** */
-
-static const SiS_LVDSDataStruct  SiS_LCDA1024x768Data_1[]=
-{
-       {  960, 438,1344, 806},
-       {  960, 388,1344, 806},
-       { 1040, 438,1344, 806},
-       { 1040, 388,1344, 806},
-       {  960, 518,1344, 806},   /* 640x480 */
-       { 1120, 638,1344, 806},   /* 800x600 */
-       { 1344, 806,1344, 806},   /* 1024x768 */
-#if 0
-       { 840, 438,1344, 806},
-       { 840, 409,1344, 806},
-       { 840, 438,1344, 806},
-       { 840, 409,1344, 806},
-       { 840, 518,1344, 806},   /* 640x480 */
-       {1050, 638,1344, 806},   /* 800x600 */
-       {1344, 806,1344, 806},   /* 1024x768 */
-#endif
-};
-
-static const SiS_LVDSDataStruct  SiS_LCDA1024x768Data_2[]=
-{
-       {1344, 806,1344, 806},
-       {1344, 806,1344, 806},
-       {1344, 806,1344, 806},
-       {1344, 806,1344, 806},
-       {1344, 806,1344, 806},
-       {1344, 806,1344, 806},
-       {1344, 806,1344, 806},
-};
-
-static const SiS_LVDSDataStruct  SiS_LCDA1280x1024Data_1[]=
-{ /* Acer, Compaq */
-       {1048, 442,1688,1066},
-       {1048, 392,1688,1066},
-       {1128, 442,1688,1066},
-       {1128, 392,1688,1066},
-       {1048, 522,1688,1066},
-       {1208, 642,1688,1066},
-       {1432, 810,1688,1066},
-       {1688,1066,1688,1066}
-};
-
-static const SiS_LVDSDataStruct  SiS_LCDA1280x1024Data_2[]=
-{ /* Corrected (illegal in Acer, correct in Compaq) */
-       {1688,1066,1688,1066},
-       {1688,1066,1688,1066},
-       {1688,1066,1688,1066},
-       {1688,1066,1688,1066},
-       {1688,1066,1688,1066},
-       {1688,1066,1688,1066},
-       {1688,1066,1688,1066},
-       {1688,1066,1688,1066}
-};
-
-static const SiS_LVDSDataStruct  SiS_LCDA1400x1050Data_1[]=
-{ /* Clevo */
-        { 928, 416, 1688,1066},
-       { 928, 366, 1688,1066},
-       {1008, 416, 1688,1066},
-       {1008, 366, 1688,1066},
-       {1200, 530, 1688,1066},
-       {1088, 616, 1688,1066},
-       {1312, 784, 1688,1066},
-       {1568,1040, 1688,1066},
-       {1688,1066, 1688,1066}
-};
-
-static const SiS_LVDSDataStruct  SiS_LCDA1400x1050Data_2[]=
-{ /* Clevo */
-       {1688,1066, 1688,1066},
-       {1688,1066, 1688,1066},
-       {1688,1066, 1688,1066},
-       {1688,1066, 1688,1066},
-       {1688,1066, 1688,1066},
-       {1688,1066, 1688,1066},
-       {1688,1066, 1688,1066},
-       {1688,1066, 1688,1066},
-       {1688,1066, 1688,1066}
-};
-
-static const SiS_LVDSDataStruct  SiS_LCDA1600x1200Data_1[]=
-{ /* Clevo (Temporary data)  */
-       {1200, 450, 2048,1250},
-       {1200, 400, 2048,1250},
-       {1280, 450, 2048,1250},
-       {1280, 400, 2048,1250},
-       {1200, 530, 2048,1250},
-       {1360, 650, 2048,1250},
-       {1584, 818, 2048,1250},
-       {1688,1066, 2048,1250},
-       {1688,1066, 2048,1250},
-       {2048,1250, 2048,1250}   /* this should be correct */
-#if 0
-       {2160,1250, 2048,1250}   /* ? */
-#endif
-};
-
-static const SiS_LVDSDataStruct  SiS_LCDA1600x1200Data_2[]=
-{ /* Clevo (Temporary data. Seems invalid.) */
-       {2160,1250, 2160,1250},
-       {2160,1250, 2160,1250},
-       {2160,1250, 2160,1250},
-       {2160,1250, 2160,1250},
-       {2160,1250, 2160,1250},
-       {2160,1250, 2160,1250},
-       {2160,1250, 2160,1250},
-       {2160,1250, 2160,1250},
-       {2160,1250, 2160,1250},
-       {2160,1250, 2160,1250}
-};
-
-/* LVDS SKEW for LCDA */
-
-static const SiS_LVDSDesStruct SiS_PanelType1076_1[]=
-{  /* 1024x768 */
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},   /* 805; was 0, 0 -> top line cut away (26/09/03) */
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1076_2[]=
-{  /* 1024x768; not expanded */
-       { 1184, 622 },
-       { 1184, 597 },
-       { 1184, 622 },
-       { 1184, 597 },
-       { 1152, 650 },  /* 622 */
-       { 1232, 722 },
-       {    0, 0   },  /* 805; was 0, 0 -> top line cut away (26/09/03) */
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1210_1[]=
-{  /* 1280x1024 */
-       { 0 ,    0},
-       { 0 ,    0},
-       { 0 ,    0},
-       { 0 ,    0},
-       { 0 ,    0},
-       { 0 ,    0},
-       { 0 ,    0},
-       { 0 , 1065},  /* Acer */
-       { 0 ,    0}
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1210_2[]=
-{  /* 1280x1024; not expanded */
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0}
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1296_1[]=
-{  /* 1400x1050 */
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 1065}   /* Was 0,0 */
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1296_2[]=
-{  /* 1400x1050; not expanded */
-       { 1308, 741 },
-       { 1308, 716 },
-       { 1308, 741 },
-       { 1308, 716 },
-       { 1308, 781 },
-       { 1388, 841 },
-       { 1500, 925 },
-       { 1628,1053 },
-       {    0,1065 }
-#if 0
-       { 808 , 740},
-       { 0   , 715},
-       { 632 , 740},
-       { 632 , 715},
-       { 1307, 780},
-       { 1387,1157},
-       { 1499, 924},
-       { 1627,1052},
-       { 0 , 0}
-#endif
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1600_1[]=
-{  /* 1600x1200 */
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0}
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1600_2[]=
-{  /* 1600x1200; not expanded */
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0}
-};
-
-#ifdef SIS315H
-
-/* LCDA CRT1 custom data */
-
-static const SiS_LCDACRT1DataStruct  Compaq1280x1024_LCDACRT1_1[]=
-{
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
-   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
-   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
-   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
-   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x08,0x3e,
-   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x06,
-   0x00}},
- {{0x92,0x63,0x63,0x96,0x6c,0x1a,0x80,0xf0,
-   0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x06,
-   0x01}},
- {{0xae,0x7f,0x7f,0x92,0x88,0x96,0x28,0xf5,
-   0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x02,
-   0x01}},
- {{0xce,0x9f,0x9f,0x92,0xa8,0x16,0x28,0x5a,
-   0x00,0x84,0xff,0xff,0x29,0x01,0x00,0x07,
-   0x01}}
+       { 1, 1, 800, 525, 800, 525 },  /* 0x04: 320x240, 640x480  */
+       { 1, 1,1056, 628,1056, 628 },  /* 0x05: 400x300, 800x600  */
+       { 1, 1,1344, 806,1344, 806 },  /* 0x06: 512x384, 1024x768 */
+       { 1, 1,1688,1066,1688,1066 },  /* 0x07: 1280x1024 */
+        { 1, 1,1688, 802,1688, 802 },  /* 0x08: 1280x768: Fujitsu, TMDS only */
+        { 1, 1,2160,1250,2160,1250 },  /* 0x09: 1600x1200 */
+       { 1, 1,1800,1000,1800,1000 },  /* 0x0a: 1280x960  */
+       { 1, 1,1688,1066,1688,1066 },  /* 0x0b: 1400x1050 */
+       { 1, 1,1650, 750,1650, 750 },  /* 0x0c: 1280x720 (TMDS, projector)  */
+       { 1, 1,1656, 841,1656, 841 },  /* 0x0d: 1280x800 (was: 1408, 816) */
+       { 1, 1,1900,1066,1900,1066 },  /* 0x0e: 1680x1050 (LVDS) */
+       { 1, 1,1408, 806,1408, 806 },  /* 0x0f: 1280x768_2 */
+       { 1, 1,1664, 798,1664, 798 },  /* 0x10: 1280x768_3 */
+       { 1, 1,1688, 802,1688, 802 },  /* 0x11: 1280x768: Std, TMDS only */
+       { 1, 1,1344, 806,1344, 806 },  /* 0x12: 1280x720 (LVDS)  */
+       { 1, 1, 896, 497, 896, 497 },  /* 0x13: 720x480 */
+       { 1, 1, 912, 597, 912, 597 },  /* 0x14: 720x576 */
+       { 1, 1, 912, 597, 912, 597 },  /* 0x15: 768x576 */
+       { 1, 1,1056, 497,1056, 497 },  /* 0x16: 848x480 */
+       { 1, 1,1064, 497,1064, 497 },  /* 0x17: 856x480 */
+       { 1, 1,1056, 497,1056, 497 },  /* 0x18: 800x480 */
+       { 1, 1,1328, 739,1328, 739 },  /* 0x19: 1024x576 */
+       { 1, 1,1680, 892,1680, 892 },  /* 0x1a: 1152x864 */
+       { 1, 1,1808, 808,1808, 808 },  /* 0x1b: 1360x768 */
+       { 1, 1,1104, 563,1104, 563 }   /* 0x1c: 960x540 */
 };
 
-static const SiS_LCDACRT1DataStruct  Compaq1280x1024_LCDACRT1_1_H[]=
-{
- {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
-   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x3c,0x4f,0x4f,0x82,0x58,0x06,0x86,0xd1,
-   0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06,
-   0x01}},
- {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
-   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x3c,0x4f,0x4f,0x82,0x58,0x06,0x86,0xd1,
-   0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06,
-   0x01}},
- {{0x56,0x27,0x27,0x9a,0x30,0x1e,0x08,0x3e,
-   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x05,
-   0x00}},
- {{0x60,0x31,0x31,0x84,0x3a,0x88,0x80,0xf0,
-   0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x01,
-   0x01}},
- {{0x6e,0x3f,0x3f,0x92,0x48,0x96,0x28,0xf5,
-   0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x01,
-   0x01}}
-};
-
-static const SiS_LCDACRT1DataStruct  Clevo1024x768_LCDACRT1_1[]=
-{
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
-   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
-   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x04,0x3e,
-   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
-   0x00}},
- {{0x87,0x63,0x63,0x8B,0x69,0x1A,0x7c,0xf0,
-   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x26,
-   0x01}},
- {{0xA3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x02,
-   0x01}}
-};
-
-static const SiS_LCDACRT1DataStruct  Clevo1024x768_LCDACRT1_1_H[]=
-{
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
-   0x00}},
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
-   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
-   0x00}},
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
-   0x00}},
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
-   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
-   0x00}},
- {{0x4b,0x27,0x27,0x8f,0x32,0x1b,0x04,0x3e,
-   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x45,
-   0x00}},
- {{0x55,0x31,0x31,0x99,0x46,0x1d,0x7c,0xf0,
-   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55,
-   0x01}},
- {{0x63,0x3F,0x3F,0x87,0x4A,0x93,0x24,0xF5,
-   0x02,0x88,0xFF,0xFF,0x25,0x10,0x00,0x01,
-   0x01}}
-};
-
-static const SiS_LCDACRT1DataStruct  Clevo1024x768_LCDACRT1_2[]=
-{
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x63,0x63,0x87,0x78,0x89,0x24,0xf1,
-   0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x02,
-   0x01}},
- {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
-   0x01}}
-};
-
-static const SiS_LCDACRT1DataStruct  Clevo1024x768_LCDACRT1_2_H[]=
-{
- {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x57,0x8e,0x8f,0x8f,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x3e,0x85,0x5d,0x5d,0x25,0x10,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x57,0x8e,0x8f,0x8f,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x3e,0x85,0x5d,0x5d,0x25,0x10,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x7f,0x86,0xdf,0xdf,0x25,0x10,0x00,0x01,
-   0x00 }},
- {{0x71,0x31,0x31,0x95,0x46,0x97,0x24,0xf1,
-   0xbb,0x82,0x57,0x57,0x25,0x10,0x00,0x01,
-   0x01 }},
- {{0x63,0x3f,0x3f,0x87,0x46,0x97,0x24,0xf5,
-   0x0f,0x86,0xff,0xff,0x25,0x30,0x00,0x01,
-   0x01 }}
-};
-
-#endif  /* 315 */
 
 /**************************************************************/
 /* LVDS ----------------------------------------------------- */
@@ -1521,9 +1216,7 @@ static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_1[]=
        { 848, 389,1060, 629},
        { 848, 518,1060, 629},
        {1056, 628,1056, 628},
-       {1056, 628,1056, 628},
-       { 800, 449,1000, 644},
-       { 800, 525,1000, 635}
+       {1056, 628,1056, 628}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_2[]=
@@ -1534,9 +1227,7 @@ static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_2[]=
        {1056, 628,1056, 628},
        {1056, 628,1056, 628},
        {1056, 628,1056, 628},
-       {1056, 628,1056, 628},
-       { 800, 449,1000, 644},
-       { 800, 525,1000, 635}
+       {1056, 628,1056, 628}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_1[]=
@@ -1548,8 +1239,6 @@ static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_1[]=
        { 840, 518,1344, 806},   /* 640x480 */
        {1050, 638,1344, 806},   /* 800x600 */
        {1344, 806,1344, 806},   /* 1024x768 */
-       { 800, 449,1280, 801},
-       { 800, 525,1280, 813}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_2[]=
@@ -1561,11 +1250,8 @@ static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_2[]=
        {1344, 806,1344, 806},
        {1344, 806,1344, 806},
        {1344, 806,1344, 806},
-       { 800, 449,1280, 801},
-       { 800, 525,1280, 813}
 };
 
-
 static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_1[]=
 {
        {1048, 442,1688,1066},
@@ -1716,9 +1402,7 @@ static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_1[] =
        { 840, 560,1344, 800},
        { 840, 689,1344, 800},
        {1050, 800,1344, 800},
-       {1344, 800,1344, 800},
-       { 800, 449,1280, 789},
-       { 800, 525,1280, 785}
+       {1344, 800,1344, 800}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_2[] =
@@ -1729,9 +1413,7 @@ static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_2[] =
        {1344, 800,1344, 800},
        {1344, 800,1344, 800},
        {1344, 800,1344, 800},
-       {1344, 800,1344, 800},
-       { 800, 449,1280, 801},
-       { 800, 525,1280, 813}
+       {1344, 800,1344, 800}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_1[] =
@@ -1742,9 +1424,7 @@ static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_1[] =
        { 840, 409,1344, 806},
        { 840, 518,1344, 806},
        {1050, 638,1344, 806},
-       {1344, 806,1344, 806},
-       { 800, 449,1280, 801},
-       { 800, 525,1280, 813}
+       {1344, 806,1344, 806}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_2[] =
@@ -1755,9 +1435,7 @@ static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_2[] =
        {1344, 806,1344, 806},
        {1344, 806,1344, 806},
        {1344, 806,1344, 806},
-       {1344, 806,1344, 806},
-       { 800, 449,1280, 801},
-       { 800, 525,1280, 813}
+       {1344, 806,1344, 806}
 };
 
 /* Pass 1:1 data */
@@ -1770,7 +1448,7 @@ static const SiS_LVDSDataStruct  SiS_LVDSXXXxXXXData_1[]=
        { 800, 525,  800, 525},  /*  640x480   */
        {1056, 628, 1056, 628},  /*  800x600   */
        {1344, 806, 1344, 806},  /* 1024x768   */
-       {1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
+       {1688,1066, 1688,1066},  /* 1280x1024  */  /* INSERTED ! */
        {1688, 806, 1688, 806},  /* 1280x768   */
        /* No other panels ! */
 };
@@ -1885,36 +1563,6 @@ static const SiS_LVDSDataStruct  SiS_CHTVONTSCData[]=
         {1160, 840,1160, 840}
 };
 
-/* LVDS Skew */
-
-static const SiS_LVDSDesStruct  SiS_PanelTypeNS_1[]=
-{
-       { 8,   0},
-       { 8,   0},
-       { 8,   0},
-       { 8,   0},
-       { 8,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0, 806},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS_PanelTypeNS_2[] =
-{
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0}
-};
-
 /* Chrontel TV Skew */
 
 static const SiS_LVDSDesStruct  SiS_CHTVUNTSCDesData[]=
@@ -2453,63 +2101,6 @@ static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_2_H[] =
    0x01}}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1XXXxXXX_1[] =
-{
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
-   0x00}},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-   0x01}},
- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
-   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
-   0x01}},
- {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1XXXxXXX_1_H[] =
-{
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-   0x00}},
- {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
-   0x01}},
- {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-   0x01}}
-};
-
-
 /**************************************************************/
 /* COMMON --------------------------------------------------- */
 /**************************************************************/
@@ -2770,7 +2361,8 @@ static const SiS_PlasmaTables SiS_PlasmaTable[] = {
    { 0x0000 }
 };
 
-USHORT  SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN);
+USHORT  SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
+                         int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight);
 USHORT  SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN,
                           USHORT CustomT, int LCDwith, int LCDheight);
 USHORT  SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
@@ -2791,6 +2383,7 @@ void      SiS_DisplayOn(SiS_Private *SiS_Pr);
 void   SiS_DisplayOff(SiS_Private *SiS_Pr);
 void   SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
 void   SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 void   SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
 void   SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
 void   SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
@@ -2801,6 +2394,7 @@ USHORT    SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
 USHORT SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
               USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo);
 void   SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT ModeIdIndex);
+void   SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
 #ifdef LINUX_XF86
 BOOLEAN        SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
 BOOLEAN        SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
@@ -2821,10 +2415,7 @@ int    sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                              unsigned char modeno, unsigned char rateindex);
 int    sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                         unsigned char modeno, unsigned char rateindex,
-                        ULONG *left_margin, ULONG *right_margin,
-                        ULONG *upper_margin, ULONG *lower_margin,
-                        ULONG *hsync_len, ULONG *vsync_len,
-                        ULONG *sync, ULONG *vmode);
+                        struct fb_var_screeninfo *var);
 BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
 #endif
index 82a73bf..e4b1aa2 100644 (file)
@@ -1,9 +1,10 @@
 /* $XFree86$ */
+/* $XdotOrg$ */
 /*
  * Mode initializing code (CRT2 section)
  * for SiS 300/305/540/630/730 and
- *     SiS 315/550/650/M650/651/661FX/M661xX/740/741/M741/330/660/M660/760/M760
- * (Universal module for Linux kernel framebuffer and XFree86 4.x)
+ *     SiS 315/550/650/M650/651/661FX/M661xX/740/741(GX)/M741/330/660/M660/760/M760
+ * (Universal module for Linux kernel framebuffer and XFree86/X.org 4.x)
  *
  * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
  * * 2) Redistributions in binary form must reproduce the above copyright
  * *    notice, this list of conditions and the following disclaimer in the
  * *    documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * *    must display the following acknowledgement: "This product includes
- * *    software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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,
 
 #include "init301.h"
 
-#if 0
-#define TWNEWPANEL
-#endif
-
 #ifdef SIS300
 #include "oem300.h"
 #endif
@@ -91,6 +85,8 @@
 #define SiS_I2CDELAY      1000
 #define SiS_I2CDELAYSHORT  150
 
+static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr);
+
 /*********************************************/
 /*         HELPER: Lock/Unlock CRT2          */
 /*********************************************/
 void
 SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  if(HwInfo->jChipType >= SIS_315H)
-     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
-  else
-     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
+   if(HwInfo->jChipType >= SIS_315H)
+      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
+   else
+      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
 }
 
 void
 SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  if(HwInfo->jChipType >= SIS_315H)
-     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
-  else
-     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
-}
-
-/*********************************************/
-/*            HELPER: Enable CRT2            */
-/*********************************************/
-
-void
-SiS_EnableCRT2(SiS_Private *SiS_Pr)
-{
-  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+   if(HwInfo->jChipType >= SIS_315H)
+      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
+   else
+      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
 }
 
 /*********************************************/
@@ -130,7 +116,10 @@ SiS_EnableCRT2(SiS_Private *SiS_Pr)
 static void
 SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, USHORT DataOR)
 {
-   if(HwInfo->jChipType >= SIS_661) DataAND &= 0x0f;
+   if(HwInfo->jChipType >= SIS_661) {
+      DataAND &= 0x0f;
+      DataOR  &= 0x0f;
+   }
    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
 }
 
@@ -138,117 +127,45 @@ SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, US
 /*    HELPER: Get Pointer to LCD structure   */
 /*********************************************/
 
-/* For 661 series only */
 #ifdef SIS315H
-#if 0   /* Need to wait until hardware using this really exists */
 static UCHAR *
-GetLCDPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int tabletype,
-             USHORT ModeNo, USHORT ModeIdIndex, USHORT RRTI)
+GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  UCHAR *ROMAddr =  HwInfo->pjVirtualRomBase;
-  UCHAR *tableptr = NULL;
-  UCHAR tablelengths[] = { 8, 7, 6, 6, 8, 6, 0, 0, 0 };
-  USHORT modeflag, CRT2Index, tablelength, lcdid, myid, tableptri;
-
-  if(ModeNo <= 0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  } else {
-     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     CRT2Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT2CRTC;
-     /* This is total bullshit: */
-     if(SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO == SIS_RI_720x576) CRT2Index = 10;
-  }
-
-  if(tabletype <= 1) {
-#if 0  /* Not yet implemented */
-     if(ModeNo <= 0x13) {
-        CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex]. + 5;
-     } else {
-        CRT2Index = SiS_Pr->SiS_RefIndex[RRTI]. + 5;
-     }
-     if(tabletype & 1) CRT2Index >>= 4;
-#endif
-  }
-
-  CRT2Index &= 0x0f;
-
-  tablelength = tablelengths[tabletype];
-  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-     if((tabletype == 5) || (tabletype == 7)) tablelength = 8;
-     if((tabletype == 3) || (tabletype == 8)) tablelength = 8;
-  }
-
-  if(!tablelength) return NULL;
-
-  tableptri = ROMAddr[0x222] | (ROMAddr[0x223] << 8);
-  tableptri += (tabletype << 1);
-  if(!tableptri) return NULL;
-  tableptr = &ROMAddr[tableptri];
-
-  do {
-     lcdid = tableptr[0];
-     if(lcdid == 0xff) break;
-     myid = SiS_Pr->SiS_LCDResInfo;
-     if((lcdid & 0x80) && (lcdid != 0x80)) {
-        lcdid &= 0x7f;
-       myid = SiS_Pr->SiS_LCDTypeInfo;
-     }
-     if(SiS_Pr->SiS_LCDInfo & LCDPass11) myid &= ~0x1f;
-
-     if(myid == lcdid) {
-       lcdid = tableptr[1] | (tableptr[2] << 8);
-       myid = SiS_Pr->SiS_LCDInfo661;
-       if(modeflag & HalfDCLK) myid |= 0x200;
-       if(ModeNo <= 0x13)      myid |= 0x400;
-       lcdid &= myid;
-       myid = tableptr[3] | (tableptr[4] << 8);
-       if(lcdid == myid) break;
-     }
-     tableptr += 7;
-  } while (1);
+   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+   UCHAR  *myptr = NULL;
+   USHORT romindex = 0;
 
-  if(lcdid == myid) {
-     lcdid = tableptr[5] | (tableptr[6] << 8);
-     lcdid += (tablelength * CRT2Index);
-     return((UCHAR *)&ROMAddr[lcdid]);
-  }
+   /* Use the BIOS tables only for LVDS panels; DVI is unreliable
+    * due to the variaty of panels the BIOS doesn't know about.
+    */
 
-  return NULL;
+   if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+      myptr = (UCHAR *)SiS_LCDStruct661;
+      romindex = SISGETROMW(0x100);
+      if(romindex) {
+         romindex += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x7d) & 0x1f) * 26);
+         myptr = &ROMAddr[romindex];
+      }
+   }
+   return myptr;
 }
-#endif
 
-static UCHAR *
-GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static USHORT
+GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-   USHORT lcdres = SiS_Pr->SiS_LCDResInfo;
-   USHORT lcdtype = SiS_Pr->SiS_LCDTypeInfo;
-   USHORT romindex=0;
-   UCHAR  *myptr = NULL;
-   UCHAR  lcdid;
+   USHORT romptr = 0;
 
-   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-      romindex = ROMAddr[0x256] | (ROMAddr[0x257] << 8);
-   }
-   if(romindex) {
-      myptr = &ROMAddr[romindex];
-   } else {
-      myptr = (UCHAR *)SiS_LCDStruct661;
-   }
+   /* Use the BIOS tables only for LVDS panels; DVI is unreliable
+    * due to the variaty of panels the BIOS doesn't know about.
+    */
 
-   while(myptr[0] != 0xff) {
-      lcdid = myptr[0];
-      if((lcdid & 0x80) && (lcdid != 0x80)) {
-         lcdres = lcdtype;
-        lcdid &= 0x7f;
-      }
-      if(lcdid == lcdres) break;
-      myptr += 26;
+   if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+      romptr = SISGETROMW(0x102);
+      romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
    }
-   if(myptr[0] == 0xff) return NULL;
 
-   return myptr;
+   return(romptr);
 }
 #endif
 
@@ -261,71 +178,72 @@ SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                    USHORT RefreshRateTableIndex, USHORT *i,
                   PSIS_HW_INFO HwInfo)
 {
-  USHORT tempax,tempbx,infoflag;
-
-  tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+  USHORT checkmask=0,modeid,infoflag;
 
-  tempax = 0;
+  modeid = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
 
   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
 
-       tempax |= SupportRAMDAC2;
+       checkmask |= SupportRAMDAC2;
        if(HwInfo->jChipType >= SIS_315H) {
-          tempax |= SupportRAMDAC2_135;
+          checkmask |= SupportRAMDAC2_135;
           if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-             tempax |= SupportRAMDAC2_162;
+             checkmask |= SupportRAMDAC2_162;
              if(SiS_Pr->SiS_VBType & VB_SIS301C) {
-                tempax |= SupportRAMDAC2_202;
+                checkmask |= SupportRAMDAC2_202;
              }
           }
        }
 
      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
 
-       tempax |= SupportLCD;
+       checkmask |= SupportLCD;
        if(HwInfo->jChipType >= SIS_315H) {
-          if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
-             if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-                if(tempbx == 0x2e) {  /* 640x480 */
-                   tempax |= Support64048060Hz;
-                }
+          if(SiS_Pr->SiS_VBType & VB_SISVB) {
+             if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+                if(modeid == 0x2e) checkmask |= Support64048060Hz;
              }
           }
        }
 
      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
 
-       tempax |= SupportHiVision;
+       checkmask |= SupportHiVision;
 
      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
 
-        tempax |= SupportTV;
+        checkmask |= SupportTV;
        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-          tempax |= SupportTV1024;
+          checkmask |= SupportTV1024;
+          if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+             if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
+                checkmask |= SupportYPbPr750p;
+             }
+          }
        }
 
      }
 
-  } else {     /* for LVDS  */
+  } else {     /* LVDS */
 
      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-           tempax |= SupportCHTV;
+           checkmask |= SupportCHTV;
        }
      }
 
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-       tempax |= SupportLCD;
+       checkmask |= SupportLCD;
      }
 
   }
 
   /* Look backwards in table for matching CRT2 mode */
-  for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
+  for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == modeid; (*i)--) {
      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
-     if(infoflag & tempax) return(1);
+     if(infoflag & checkmask) return TRUE;
      if((*i) == 0) break;
   }
 
@@ -333,17 +251,17 @@ SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
    * for a matching CRT2 mode if no mode was found yet.
    */
   for((*i) = 0; ; (*i)++) {
-     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
-       return(0);
+     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != modeid) {
+       return FALSE;
      }
      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
-     if(infoflag & tempax) return(1);
+     if(infoflag & checkmask) return TRUE;
   }
-  return(1);
+  return TRUE;
 }
 
 /*********************************************/
-/*              Get rate pointer             */
+/*              Get rate index               */
 /*********************************************/
 
 USHORT
@@ -361,20 +279,19 @@ SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   /* Do NOT check for UseCustomMode here, will skrew up FIFO */
   if(ModeNo == 0xfe) return 0;
 
-  if(ModeNo <= 0x13)
+  if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  else
+  } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
 
   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-       if(modeflag & HalfDCLK) return(0);
+       if(modeflag & HalfDCLK) return 0;
      }
   }
 
-  if(ModeNo < 0x14) return(0xFFFF);
-
-  /* CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4]. */
+  if(ModeNo < 0x14) return 0xFFFF;
 
   index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
   backupindex = index;
@@ -389,7 +306,7 @@ SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
        }
        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
           if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
-              temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
+              temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
               if(index > temp) index = temp;
           }
        }
@@ -462,37 +379,39 @@ SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
 /*    HELPER: GET SOME DATA FROM BIOS ROM    */
 /*********************************************/
 
+#ifdef SIS300
 static BOOLEAN
 SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
+  UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
   USHORT temp,temp1;
-  UCHAR *ROMAddr;
 
-  if((ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+  if(SiS_Pr->SiS_UseROM) {
      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
         temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
-        temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
-        if(temp1 & temp) return(1);
+        temp1 = SISGETROMW(0x23b);
+        if(temp1 & temp) return TRUE;
      }
   }
-  return(0);
+  return FALSE;
 }
 
 static BOOLEAN
 SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
+  UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
   USHORT temp,temp1;
-  UCHAR *ROMAddr;
 
-  if((ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+  if(SiS_Pr->SiS_UseROM) {
      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
         temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
-        temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
-        if(temp1 & temp) return(1);
+        temp1 = SISGETROMW(0x23d);
+        if(temp1 & temp) return TRUE;
      }
   }
-  return(0);
+  return FALSE;
 }
+#endif
 
 /*********************************************/
 /*          HELPER: DELAY FUNCTIONS          */
@@ -508,6 +427,7 @@ SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
   }
 }
 
+#if defined(SIS300) || defined(SIS315H)
 static void
 SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
 {
@@ -522,6 +442,7 @@ SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
      delay--;
   }
 }
+#endif
 
 #ifdef SIS315H
 static void
@@ -533,6 +454,7 @@ SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
 }
 #endif
 
+#if defined(SIS300) || defined(SIS315H)
 static void
 SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
 {
@@ -540,12 +462,15 @@ SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
      SiS_GenericDelay(SiS_Pr,0x42);
   }
 }
+#endif
 
 static void
 SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
 {
+#if defined(SIS300) || defined(SIS315H)
   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT PanelID, DelayIndex, Delay=0;
+#endif
 
   if(HwInfo->jChipType < SIS_315H) {
 
@@ -560,23 +485,19 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
          Delay = 3;
       } else {
          if(DelayTime >= 2) DelayTime -= 2;
-
          if(!(DelayTime & 0x01)) {
                    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
          } else {
                    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
          }
-        if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+        if(SiS_Pr->SiS_UseROM) {
             if(ROMAddr[0x220] & 0x40) {
-               if(!(DelayTime & 0x01)) {
-                 Delay = (USHORT)ROMAddr[0x225];
-               } else {
-                 Delay = (USHORT)ROMAddr[0x226];
-               }
+               if(!(DelayTime & 0x01)) Delay = (USHORT)ROMAddr[0x225];
+               else                   Delay = (USHORT)ROMAddr[0x226];
             }
          }
       }
-      SiS_ShortDelay(SiS_Pr,Delay);
+      SiS_ShortDelay(SiS_Pr, Delay);
 
 #endif  /* SIS300 */
 
@@ -584,11 +505,19 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
 
 #ifdef SIS315H
 
-      if(HwInfo->jChipType >= SIS_330) return;
+      if((HwInfo->jChipType >= SIS_661)    ||
+         (HwInfo->jChipType <= SIS_315PRO) ||
+        (HwInfo->jChipType == SIS_330)) {
+
+         if(!(DelayTime & 0x01)) {
+           SiS_DDC2Delay(SiS_Pr, 0x1000);
+         } else {
+           SiS_DDC2Delay(SiS_Pr, 0x4000);
+         }
 
-      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
+      } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
          (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
-        (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {                      /* 315 series, LVDS; Special */
+        (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) {                  /* 315 series, LVDS; Special */
 
          if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
             PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
@@ -609,7 +538,7 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
                } else {
                          Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
                }
-              if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+              if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
                   if(ROMAddr[0x13c] & 0x40) {
                      if(!(DelayTime & 0x01)) {
                        Delay = (USHORT)ROMAddr[0x17e];
@@ -619,7 +548,7 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
                   }
                }
             }
-           SiS_ShortDelay(SiS_Pr,Delay);
+           SiS_ShortDelay(SiS_Pr, Delay);
         }
 
       } else if(SiS_Pr->SiS_VBType & VB_SISVB) {                       /* 315 series, all bridges */
@@ -662,7 +591,6 @@ SiS_WaitRetrace1(SiS_Private *SiS_Pr)
   USHORT watchdog;
 
   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
-
   if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
 
   watchdog = 65535;
@@ -671,6 +599,7 @@ SiS_WaitRetrace1(SiS_Private *SiS_Pr)
   while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
 }
 
+#if defined(SIS300) || defined(SIS315H)
 static void
 SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
 {
@@ -681,6 +610,7 @@ SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
   watchdog = 65535;
   while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
 }
+#endif
 
 static void
 SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
@@ -718,10 +648,10 @@ SiS_VBWait(SiS_Private *SiS_Pr)
        tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
        if(temp & 0x01) {
           if((tempal & 0x08))  continue;
-          if(!(tempal & 0x08)) break;
+          else break;
        } else {
           if(!(tempal & 0x08)) continue;
-          if((tempal & 0x08))  break;
+          else break;
        }
     }
     temp ^= 0x01;
@@ -742,15 +672,14 @@ SiS_VBLongWait(SiS_Private *SiS_Pr)
 /*               HELPER: MISC                */
 /*********************************************/
 
+#ifdef SIS300
 static BOOLEAN
 SiS_Is301B(SiS_Private *SiS_Pr)
 {
-  USHORT flag;
-
-  flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
-  if(flag >= 0xb0) return TRUE;
+  if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
   return FALSE;
 }
+#endif
 
 static BOOLEAN
 SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
@@ -796,6 +725,16 @@ SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
   return FALSE;
 }
 
+#ifdef SIS315H
+static BOOLEAN
+SiS_IsVAorLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  if(SiS_IsVAMode(SiS_Pr,HwInfo))   return TRUE;
+  if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) return TRUE;
+  return FALSE;
+}
+#endif
+
 static BOOLEAN
 SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
@@ -815,7 +754,7 @@ static BOOLEAN
 SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
-  if(SiS_Pr->SiS_VBType & (VB_301C | VB_SIS301LV302LV)) {
+  if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV302LV)) {
      if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
   }
   return FALSE;
@@ -835,11 +774,8 @@ SiS_LCDAEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 static BOOLEAN
 SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  USHORT flag;
-
   if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
-     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
-     if(flag & 0x10) return TRUE;
+     if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
   }
   return FALSE;
 }
@@ -935,12 +871,12 @@ SiS_BridgeIsOn(SiS_Private *SiS_Pr)
   USHORT flag;
 
   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     return FALSE;
+     return TRUE;
   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
      flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
-     if((flag == 1) || (flag == 2)) return FALSE;
+     if((flag == 1) || (flag == 2)) return TRUE;
   }
-  return TRUE;
+  return FALSE;
 }
 
 static BOOLEAN
@@ -948,21 +884,21 @@ SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   USHORT flag;
 
-  if(!(SiS_BridgeIsOn(SiS_Pr))) {
+  if(SiS_BridgeIsOn(SiS_Pr)) {
      flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
      if(HwInfo->jChipType < SIS_315H) {
        flag &= 0xa0;
-       if((flag == 0x80) || (flag == 0x20)) return FALSE;
+       if((flag == 0x80) || (flag == 0x20)) return TRUE;
      } else {
        flag &= 0x50;
-       if((flag == 0x40) || (flag == 0x10)) return FALSE;
+       if((flag == 0x40) || (flag == 0x10)) return TRUE;
      }
   }
-  return TRUE;
+  return FALSE;
 }
 
 static BOOLEAN
-SiS_BridgeInSlave(SiS_Private *SiS_Pr)
+SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
 {
   USHORT flag1;
 
@@ -985,7 +921,7 @@ SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
    if(!(SiS_Pr->SiS_ChSW)) return;
 
 #ifndef LINUX_XF86
-   SiS_SetRegLong(0xcf8,0x80000874);              /* get ACPI base */
+   SiS_SetRegLong(0xcf8,0x80000874);                  /* get ACPI base */
    acpibase = SiS_GetRegLong(0xcfc);
 #else
    acpibase = pciReadLong(0x00000800, 0x74);
@@ -1003,22 +939,19 @@ SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
 }
 
 void
-SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
-              USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,
-             int checkcrt2mode)
+SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+              PSIS_HW_INFO HwInfo, int checkcrt2mode)
 {
   USHORT tempax,tempbx,temp;
   USHORT modeflag, resinfo=0;
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
   } else {
-     if(SiS_Pr->UseCustomMode) {
-        modeflag = SiS_Pr->CModeFlag;
-     } else {
-       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-     }
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
 
   SiS_Pr->SiS_SetFlag = 0;
@@ -1026,7 +959,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
   SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
 
   tempbx = 0;
-  if(SiS_BridgeIsOn(SiS_Pr) == 0) {
+  if(SiS_BridgeIsOn(SiS_Pr)) {
        temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
 #if 0
        if(HwInfo->jChipType < SIS_661) {
@@ -1054,7 +987,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
                 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
              }
              if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
-                /* Reset LCDA setting */
+                /* Reset LCDA setting if not driver mode */
                 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
              }
              if(IS_SIS650) {
@@ -1071,6 +1004,11 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
                 tempbx |= SetCRT2ToLCDA;
              }
           }
+
+          if(SiS_Pr->SiS_VBType & (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
+             tempbx &= ~(SetCRT2ToRAMDAC);
+          }
+
           if(HwInfo->jChipType >= SIS_661) {
              tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
              temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
@@ -1148,24 +1086,12 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
                                SetPALTV           |
                                SwitchCRT2         |
                                SetSimuScanMode );
-          if(tempbx & SetCRT2ToLCDA) {
-              tempbx &= (clearmask | SetCRT2ToLCDA);
-          }
-          if(tempbx & SetCRT2ToRAMDAC) {
-              tempbx &= (clearmask | SetCRT2ToRAMDAC);
-          }
-          if(tempbx & SetCRT2ToLCD) {
-              tempbx &= (clearmask | SetCRT2ToLCD);
-          }
-          if(tempbx & SetCRT2ToSCART) {
-              tempbx &= (clearmask | SetCRT2ToSCART);
-          }
-          if(tempbx & SetCRT2ToHiVision) {
-              tempbx &= (clearmask | SetCRT2ToHiVision);
-          }
-          if(tempbx & SetCRT2ToYPbPr525750) {
-             tempbx &= (clearmask | SetCRT2ToYPbPr525750);
-          }
+          if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
+          if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);
+          if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);
+          if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);
+          if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);
+          if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
        } else {
           if(HwInfo->jChipType >= SIS_315H) {
              if(tempbx & SetCRT2ToLCDA) {
@@ -1193,14 +1119,12 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
           }
        }
 
-       if(!(tempbx & DriverMode)){
-          tempbx |= SetSimuScanMode;
-       }
+       if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
 
        /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
        if(SiS_Pr->SiS_ModeType <= ModeVGA) {
           if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
-              ((tempbx & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD)) ) {
+              ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
               modeflag &= (~CRT2Mode);
           }
        }
@@ -1218,9 +1142,9 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
                 }
               }
           } else {
-              if(!(SiS_BridgeIsEnabled(SiS_Pr,HwInfo))) {
+              if(SiS_BridgeIsEnabled(SiS_Pr,HwInfo)) {
                 if(!(tempbx & DriverMode)) {
-                   if(SiS_BridgeInSlave(SiS_Pr)) {
+                   if(SiS_BridgeInSlavemode(SiS_Pr)) {
                       tempbx |= SetSimuScanMode;
                    }
                  }
@@ -1346,7 +1270,7 @@ SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_IN
           if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
         }
         if(temp) {
-           if(romindex && ROMAddr && SiS_Pr->SiS_UseROM) {
+           if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
              OutputSelect = ROMAddr[romindex];
              if(!(OutputSelect & EnablePALMN)) {
                  SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
@@ -1443,6 +1367,22 @@ SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_IN
        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
           SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
        }
+       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
+          if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
+             SiS_Pr->SiS_TVMode |= TVAspect169;
+          } else {
+             temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
+             if(temp1 & 0x02) {
+                if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
+                   SiS_Pr->SiS_TVMode |= TVAspect169;
+                } else {
+                   SiS_Pr->SiS_TVMode |= TVAspect43LB;
+                }
+             } else {
+                SiS_Pr->SiS_TVMode |= TVAspect43;
+             }
+          }
+       }
      }
   }
 
@@ -1493,13 +1433,74 @@ SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_IN
 #ifdef TWDEBUG
   xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
 #endif
-
 }
 
 /*********************************************/
 /*               GET LCD INFO                */
 /*********************************************/
 
+static USHORT
+SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr)
+{
+   USHORT temp = SiS_Pr->SiS_LCDResInfo;
+   /* Translate my LCDResInfo to BIOS value */
+   if(temp == Panel_1280x768_2)  temp = Panel_1280x768;
+   if(temp == Panel_1280x768_3)  temp = Panel_1280x768;
+   return temp;
+}
+
+static void
+SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+#ifdef SIS315H
+   UCHAR  *ROMAddr;
+   USHORT temp;
+
+#ifdef TWDEBUG
+   xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
+       SiS_Pr->PanelHT, SiS_Pr->PanelVT,
+       SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
+       SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
+       SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
+       SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
+       SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
+#endif
+
+   if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+      if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
+         SiS_Pr->SiS_NeedRomModeData = TRUE;
+        SiS_Pr->PanelHT  = temp;
+      }
+      if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
+         SiS_Pr->SiS_NeedRomModeData = TRUE;
+         SiS_Pr->PanelVT  = temp;
+      }
+      SiS_Pr->PanelHRS = SISGETROMW(10);
+      SiS_Pr->PanelHRE = SISGETROMW(12);
+      SiS_Pr->PanelVRS = SISGETROMW(14);
+      SiS_Pr->PanelVRE = SISGETROMW(16);
+      SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
+      SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
+        SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (USHORT)((UCHAR)ROMAddr[18]);
+      SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
+        SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
+      SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
+        SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
+
+#ifdef TWDEBUG
+      xf86DrvMsg(0, X_INFO, "Paneldata BIOS:  [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
+       SiS_Pr->PanelHT, SiS_Pr->PanelVT,
+       SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
+       SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
+       SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
+       SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
+       SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
+#endif
+
+   }
+#endif
+}
+
 void
 SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                  PSIS_HW_INFO HwInfo)
@@ -1515,50 +1516,60 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
          { 0,  1,  2,  3,  7,  4,  5,  8,
           0,  0, 10,  0,  0,  0,  0, 15 };
 
-  SiS_Pr->SiS_LCDResInfo = 0;
+  SiS_Pr->SiS_LCDResInfo  = 0;
   SiS_Pr->SiS_LCDTypeInfo = 0;
-  SiS_Pr->SiS_LCDInfo = 0;
+  SiS_Pr->SiS_LCDInfo     = 0;
+  SiS_Pr->PanelHRS        = 999; /* HSync start */
+  SiS_Pr->PanelHRE        = 999; /* HSync end */
+  SiS_Pr->PanelVRS        = 999; /* VSync start */
+  SiS_Pr->PanelVRE        = 999; /* VSync end */
+  SiS_Pr->SiS_NeedRomModeData = FALSE;
 
-  if(SiS_Pr->UseCustomMode) {
+  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
+
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else if(SiS_Pr->UseCustomMode) {
      modeflag = SiS_Pr->CModeFlag;
   } else {
-     if(ModeNo <= 0x13) {
-       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     } else {
-       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-     }
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
 
-  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
-
   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
+  if(!temp) return;
 
-  if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
+  if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
+     SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
+  } else if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
      SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
   } else {
      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
   }
   temp &= 0x0f;
   if(HwInfo->jChipType < SIS_315H) {
-      /* Translate 300 series LCDRes to 315 series for unified usage */
-      temp = SiS300SeriesLCDRes[temp];
+     /* Translate 300 series LCDRes to 315 series for unified usage */
+     temp = SiS300SeriesLCDRes[temp];
   }
-  SiS_Pr->SiS_LCDResInfo = temp;
 
-  if(SiS_Pr->SiS_VBType & VB_SISVB) {
-     if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
-       SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
-  } else {
-     if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
-       SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
+  if(HwInfo->jChipType == SIS_550) {
+     if(temp == Panel310_640x480_2) temp = Panel_640x480_2;
+     if(temp == Panel310_640x480_3) temp = Panel_640x480_3;
   }
 
-  if((!SiS_Pr->CP_HaveCustomData) || (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_PanelCustom)) {
-     if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
-       SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel1024x768;
+  if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {  /* SiS LVDS */
+     if(temp == Panel310_1280x768) {
+        temp = Panel_1280x768_2;
+#ifdef SIS315H
+       if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+          if((myptr[8] | (myptr[9] << 8)) == 798) temp = Panel_1280x768_3;
+       }
+#endif
+     }
   }
 
+  SiS_Pr->SiS_LCDResInfo = temp;
+
   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
      if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
         SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
@@ -1567,113 +1578,306 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      }
   }
 
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
+       SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
+  } else {
+     if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
+       SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
+  }
+
+  SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
+  SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
+
   switch(SiS_Pr->SiS_LCDResInfo) {
-     case Panel_800x600:   SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600; break;
-     case Panel_1024x768:  SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768; break;
-     case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024; break;
-     case Panel_640x480_3:
+     case Panel_320x480:    SiS_Pr->PanelXRes =  320; SiS_Pr->PanelYRes =  480;
+                           SiS_Pr->PanelHT   =  400; SiS_Pr->PanelVT   =  525;
+                           SiS_Pr->PanelVCLKIdx300 = VCLK28;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK28;
+                           break;
      case Panel_640x480_2:
-     case Panel_640x480:   SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480; break;
-     case Panel_1024x600:  SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600; break;
-     case Panel_1152x864:  SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864; break;
-     case Panel_1280x960:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960; break;
-     case Panel_1152x768:  SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768; break;
-     case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050; break;
-     case Panel_1280x768:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768; break;
-     case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200; break;
-     case Panel_320x480:   SiS_Pr->PanelXRes =  320; SiS_Pr->PanelYRes =  480; break;
-     case Panel_Custom:    SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
-                          SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
-                          break;
-     case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024; break;
-     case Panel_848x480:   SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480; break;
-     default:             SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768; break;
+     case Panel_640x480_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
+                           SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
+                           SiS_Pr->PanelVCLKIdx300 = VCLK28;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK28;
+                           break;
+     case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
+                                                     SiS_Pr->PanelVRE  =    3;
+                           SiS_Pr->PanelVCLKIdx300 = VCLK28;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK28;
+                           break;
+     case Panel_800x600:    SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600;
+                           SiS_Pr->PanelHT   = 1056; SiS_Pr->PanelVT   =  628;
+                           SiS_Pr->PanelHRS  =   40; SiS_Pr->PanelHRE  =  128;
+                           SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    4;
+                           SiS_Pr->PanelVCLKIdx300 = VCLK40;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK40;
+                           break;
+     case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;
+                           SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
+                           SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
+                           SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;
+                           SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
+                           break;
+     case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
+                           SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
+                           SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
+                           SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
+                           if(HwInfo->jChipType < SIS_315H) {
+                              SiS_Pr->PanelHRS = 23;
+                                                     SiS_Pr->PanelVRE  =    5;
+                           }
+                           SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
+                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           break;
+     case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;
+                           SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
+                           SiS_Pr->PanelHRS  =   24;
+                           SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
+                           if(HwInfo->jChipType < SIS_315H) {
+                              SiS_Pr->PanelHRS = 23;
+                                                     SiS_Pr->PanelVRE  =    5;
+                           }
+                           SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
+                           break;
+     case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;
+                           break;
+     case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;
+                           SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
+                           SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;
+                           SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
+                           /* Data above for TMDS (projector); get from BIOS for LVDS */
+                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           break;
+     case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
+                           SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
+                           SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRS  =  112;
+                           SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
+                           SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
+                           break;
+     case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
+                           SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
+                           SiS_Pr->PanelHRS  =   16; SiS_Pr->PanelHRE  =   64;
+                           SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
+                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           break;
+     case Panel_1280x768_3: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
+                           SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  798;
+                           SiS_Pr->PanelHRS   =  64; SiS_Pr->PanelHRE  =  128;
+                           SiS_Pr->PanelVRS   =   3; SiS_Pr->PanelVRE  =    7;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_3;
+                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           break;
+     case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
+                           SiS_Pr->PanelHT   = 1656; SiS_Pr->PanelVT   =  841;  /* 1408, 816 */
+                           SiS_Pr->PanelHRS   =  32; SiS_Pr->PanelHRE  =  312;  /*   16,  64 */
+                           SiS_Pr->PanelVRS   =  16; SiS_Pr->PanelVRE  =    8;  /*    4,   3 */
+                           SiS_Pr->PanelVCLKIdx315 = VCLK83_315;
+                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           break;
+     case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
+                           SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
+                           SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
+                           if(resinfo == SIS_RI_1280x1024) {
+                              SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
+                              SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
+                           }
+                           break;
+     case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
+                           SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
+                           SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
+                           SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
+                           SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
+                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           break;
+     case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
+                           SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
+                           SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112; /* HRE OK for LVDS, not for LCDA */
+                           SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
+                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           break;
+     case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
+                           SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
+                           SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;
+                           SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
+                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           break;
+     case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
+                           SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
+                           SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;
+                           SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
+                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           break;
+     case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
+                           SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
+                           SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
+                           SiS_Pr->PanelVT   = SiS_Pr->CVTotal;
+                           if(SiS_Pr->CP_PreferredIndex != -1) {
+                              SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
+                              SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
+                              SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
+                              SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
+                              SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
+                              SiS_Pr->PanelHRE  = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
+                              SiS_Pr->PanelVRS  = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
+                              SiS_Pr->PanelVRE  = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
+                              SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
+                              SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
+                              SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
+                              SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
+                           }
+                           break;
+     case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
+                           SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
+                           break;
+     case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
+                           SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
+                           break;
+     default:              SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
+                           SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
+                           break;
   }
 
   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
-  if(HwInfo->jChipType < SIS_661) {
-     temp &= ~0xe;
-  } else {
+  SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
+
+  if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+
 #ifdef SIS315H
-     if(!(temp & 0x10)) {
-        if(temp & 0x08) temp |= LCDPass11;
+  if(HwInfo->jChipType >= SIS_661) {
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
      }
-     temp &= ~0xe;
      if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-        myptr = GetLCDStructPtr661(SiS_Pr, HwInfo);
-        if(myptr) {
-           if(myptr[2] & 0x01) temp |= LCDDualLink;
-        }
+        if(SiS_Pr->SiS_ROMNew) {
+          if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+       } else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+           if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+       }
+     }
+  } else if(HwInfo->jChipType >= SIS_315H) {
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     }
+     if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
+        SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
+       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+        if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
+       if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+          if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+       }
      }
+  }
 #endif
+
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     /* Always center screen on LVDS (if scaling is disabled) */
+     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+        /* Always center screen on SiS LVDS (if scaling is disabled) */
+        SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+     } else {
+        /* By default, pass 1:1 on SiS TMDS (if scaling is disabled) */
+        SiS_Pr->SiS_LCDInfo |= LCDPass11;
+        if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+     }
   }
-  SiS_Pr->SiS_LCDInfo = temp;
 
   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
      if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
-        SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24 */
+        SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
      }
   }
 
-  if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
-  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-
   if(SiS_Pr->SiS_VBType & VB_SISVB) {
      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) {
-          /* For non-standard LCD resolution, we let the panel scale */
-           SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-          if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
-             /* We do not scale to 1280x960 (B/C bridges only) */
-              SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-          }
-          if(((HwInfo->jChipType >= SIS_315H) && (ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25)) ||
-             ((HwInfo->jChipType < SIS_315H)  && (ModeNo == 0x55 || ModeNo == 0x5a || ModeNo == 0x5b))) {
-             /* We do not scale to 1280x768 (B/C bridges only) */
-              SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-          }
-          if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-             /* No non-scaling data available for LV bridges */
-             SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
-          }
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-           /* No idea about the timing and zoom factors */
-           SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-          if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
-             /* We do not scale to 1280x1024 (all bridges) */
-             SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-          }
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-          if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
-             /* No idea about the timing and zoom factors (C bridge only) */
-             SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-          }
+        if(modeflag & NoSupportLCDScale) {
+          /* No scaling for this mode on any panel */
+          SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
        }
-       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-          if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
-              if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-                SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
-             }
-          }
+        switch(SiS_Pr->SiS_LCDResInfo) {
+        case Panel_Custom:
+               /* For non-standard LCD resolution, we let the panel scale */
+               SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+               break;
+       case Panel_1280x720:
+               if(SiS_Pr->PanelHT == 1650) {
+                  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+               }
+       case Panel_1280x768:    /* TMDS only */
+               /* No idea about the timing and zoom factors */
+               SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+               break;
+       case Panel_1280x960:
+               SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+               break;
+       case Panel_1280x1024:
+               if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
+                  if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
+                     ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
+                     ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16) {
+                     /* We do not scale to 1280x720/800/960 (B/C bridges only) */
+                      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+                  }
+                  if(((HwInfo->jChipType >= SIS_315H) &&
+                      (ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25)) ||
+                     ((HwInfo->jChipType < SIS_315H)  &&
+                      (ModeNo == 0x55 || ModeNo == 0x5a || ModeNo == 0x5b))) {
+                     /* We do not scale to 1280x768 (B/C bridges only) */
+                      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+                  }
+               }
+               break;
+       case Panel_1400x1050:
+               if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
+                  if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
+                     ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
+                     ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16 ||
+                     ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25) {
+                     /* Do not scale to 1280x720/768/800/960 (B/C bridges only) */
+                      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+                  }
+               }
+               if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+                  if(ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78) {
+                     if(SiS_Pr->UsePanelScaler == -1) {
+                        /* Do not scale to 1280x720 by default (LVDS bridges) */
+                        SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+                     }
+                  }
+               }
+               if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
+                  /* Do not scale to 1280x1024 (all bridges) */
+                  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+               }
+               break;
+       case Panel_1600x1200:
+               if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
+                  /* No idea about the timing and zoom factors (C bridge only) */
+                  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+               }
+               break;
        }
      }
   }
 
-  if(HwInfo->jChipType >= SIS_315H) {
-#ifdef SIS315H
-     if(HwInfo->jChipType < SIS_661) {
-        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
-           SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
-          SiS_Pr->SiS_LCDInfo |= LCDPass11;
-       }
-     }
-#endif
-  } else {
 #ifdef SIS300
+  if(HwInfo->jChipType < SIS_315H) {
      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-        if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+        if(SiS_Pr->SiS_UseROM) {
           if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
               if(!(ROMAddr[0x235] & 0x02)) {
                 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
@@ -1685,72 +1889,101 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
            SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
        }
      }
+  }
 #endif
+
+  /* Special cases */
+  if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
+     SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
   }
 
-  /* Trumpion: Assume non-expanding */
-  if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
-     SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
+  if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
+     SiS_Pr->SiS_LCDInfo |= LCDPass11;
   }
 
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-     SiS_Pr->SiS_LCDInfo &= (~LCDPass11);
+  if(SiS_Pr->UseCustomMode) {
+     SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
   }
 
-#ifdef SIS315H
-  if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
-     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-       /* Enable 302LV/302ELV dual link mode.
-        * For 661, this is done above.
-        */
-        if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
-          (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)) {
-          /* (Sets this in SenseLCD; new paneltypes) */
-          SiS_Pr->SiS_LCDInfo |= LCDDualLink;
-       }
-        if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-          (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
-           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
-          SiS_Pr->SiS_LCDInfo |= LCDDualLink;
-       }
-     }
+  /* (In)validate LCDPass11 flag */
+  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
   }
-#endif
 
-  if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
+  /* Special cases */
+  if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
+      (SiS_Pr->SiS_IF_DEF_DSTN)              ||
+      (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
+      (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
+     SiS_Pr->PanelHRS = 999;
+     SiS_Pr->PanelHRE = 999;
+  }
 
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-          if(ModeNo > 0x13) {
-             if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-                 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
-                    SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-                }
-              }
-           }
+  if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
+      (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
+     SiS_Pr->PanelVRS = 999;
+     SiS_Pr->PanelVRE = 999;
+  }
+
+#ifdef SIS315H
+  if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
+     if(!(SiS_Pr->SiS_ROMNew)) {
+        if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+          /* Enable 302LV/302ELV dual link mode.
+           * For 661, this is done above.
+           */
+           if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
+             (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
+             /* (Sets this in SenseLCD; new paneltypes) */
+             SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+          }
+           if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
+             (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
+              (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
+             (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
+             SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+          }
         }
-       if(ModeNo == 0x12) {
-          if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-             SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+     }
+  }
+#endif
+
+  if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
+
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+       if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+          if(ModeNo == 0x12) {
+             if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+                SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+             }
+          } else if(ModeNo > 0x13) {
+             if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
+                if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+                   if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
+                       SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+                   }
+                }
+             }
           }
        }
      }
 
      if(modeflag & HalfDCLK) {
-        if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
-           if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-             if(!(((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (HwInfo->jChipType < SIS_315H)) &&
-                                             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480))) {
-                 if(ModeNo > 0x13) {
-                    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-                       if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-                    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-                       if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-                    }
-                 }
-             } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-           } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-        } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+        if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
+          SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+        } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+          SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+       } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
+          SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+       } else if(ModeNo > 0x13) {
+           if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+              if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+           } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
+              if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+           }
+       }
      }
 
   }
@@ -1763,14 +1996,6 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      SiS_Pr->SiS_SetFlag |= LCDVESATiming;
   }
 
-  SiS_Pr->SiS_LCDInfo661 = 0;
-  if(SiS_Pr->SiS_SetFlag & LCDVESATiming) SiS_Pr->SiS_LCDInfo661 |= 0x0001;
-  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) SiS_Pr->SiS_LCDInfo661 |= 0x0002;
-  if(SiS_Pr->SiS_LCDInfo & LCDPass11)     SiS_Pr->SiS_LCDInfo661 |= 0x0008;
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) SiS_Pr->SiS_LCDInfo661 |= 0x0010;
-  SiS_Pr->SiS_LCDInfo661 |= (SiS_Pr->SiS_LCDInfo & 0xe0);
-  if(SiS_Pr->SiS_LCDInfo & LCDDualLink)   SiS_Pr->SiS_LCDInfo661 |= 0x0100;
-
 #ifdef LINUX_KERNEL
 #ifdef TWDEBUG
   printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
@@ -1792,54 +2017,21 @@ USHORT
 SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
 {
-  USHORT tempbx;
-  const USHORT LCDXlat0VCLK[4]    = {VCLK40,       VCLK40,       VCLK40,       VCLK40};
-  const USHORT LVDSXlat1VCLK[4]   = {VCLK40,       VCLK40,       VCLK40,       VCLK40};
-  const USHORT LVDSXlat4VCLK[4]   = {VCLK28,       VCLK28,       VCLK28,       VCLK28};
-#ifdef SIS300
-  const USHORT LCDXlat1VCLK300[4] = {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
-  const USHORT LCDXlat2VCLK300[4] = {VCLK108_2_300,VCLK108_2_300,VCLK108_2_300,VCLK108_2_300};
-  const USHORT LVDSXlat2VCLK300[4]= {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
-  const USHORT LVDSXlat3VCLK300[4]= {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
-#endif
-#ifdef SIS315H
-  const USHORT LCDXlat1VCLK310[4] = {VCLK65_315,   VCLK65_315,   VCLK65_315,   VCLK65_315};
-  const USHORT LCDXlat2VCLK310[4] = {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
-  const USHORT LVDSXlat2VCLK310[4]= {VCLK65_315,   VCLK65_315,   VCLK65_315,   VCLK65_315};
-  const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
-#endif
-  USHORT CRT2Index,VCLKIndex=0;
-  USHORT modeflag,resinfo;
-  const UCHAR  *CHTVVCLKPtr = NULL;
-  const USHORT *LCDXlatVCLK1 = NULL;
-  const USHORT *LCDXlatVCLK2 = NULL;
-  const USHORT *LVDSXlatVCLK2 = NULL;
-  const USHORT *LVDSXlatVCLK3 = NULL;
-
-  if(HwInfo->jChipType >= SIS_315H) {
-#ifdef SIS315H
-     LCDXlatVCLK1 = LCDXlat1VCLK310;
-     LCDXlatVCLK2 = LCDXlat2VCLK310;
-     LVDSXlatVCLK2 = LVDSXlat2VCLK310;
-     LVDSXlatVCLK3 = LVDSXlat3VCLK310;
-#endif
-  } else {
-#ifdef SIS300
-     LCDXlatVCLK1 = LCDXlat1VCLK300;
-     LCDXlatVCLK2 = LCDXlat2VCLK300;
-     LVDSXlatVCLK2 = LVDSXlat2VCLK300;
-     LVDSXlatVCLK3 = LVDSXlat3VCLK300;
-#endif
-  }
+  USHORT CRT2Index,VCLKIndex=0,VCLKIndexGEN=0;
+  USHORT modeflag,resinfo,tempbx;
+  const UCHAR *CHTVVCLKPtr = NULL;
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
      CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+     VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
   } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
      CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+     VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+     if(HwInfo->jChipType < SIS_315H) VCLKIndexGEN &= 0x3f;
   }
 
   if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
@@ -1847,50 +2039,34 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
 
         CRT2Index >>= 6;
-        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      /*  LCD */
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {              /*  LCD */
 
            if(HwInfo->jChipType < SIS_315H) {
-             if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-                VCLKIndex = LCDXlat0VCLK[CRT2Index];
-             } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-                VCLKIndex = LCDXlatVCLK1[CRT2Index];
-             } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-                VCLKIndex = LCDXlatVCLK1[CRT2Index];
-             } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
-                VCLKIndex = LCDXlatVCLK1[CRT2Index];
-             } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-                VCLKIndex = VCLK81_300;        /* guessed */
-             } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-                VCLKIndex = VCLK108_3_300;
-                if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_300;
-             } else {
-                VCLKIndex = LCDXlatVCLK2[CRT2Index];
-             }
+             VCLKIndex = SiS_Pr->PanelVCLKIdx300;
           } else {
-             if( (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) ||
-                 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
-                if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-                   VCLKIndex = VCLK108_2_315;
-                } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-                   VCLKIndex = VCLK81_315;     /* guessed */
-                } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-                   VCLKIndex = VCLK108_2_315;
-                } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-                   VCLKIndex = VCLK162_315;
-                } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-                   VCLKIndex = VCLK108_3_315;
-                   if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_315;
-                } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-                   VCLKIndex = LCDXlatVCLK1[CRT2Index];
-                } else {
-                   VCLKIndex = LCDXlatVCLK2[CRT2Index];
-                }
-             } else {
-                 VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));  /*  Port 3cch */
-                VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-                if(ModeNo > 0x13) {
-                   VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-                }
+             VCLKIndex = SiS_Pr->PanelVCLKIdx315;
+             if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+                VCLKIndex = VCLKIndexGEN;
+                switch(resinfo) {
+                /* Only those whose IndexGEN doesn't match VBVCLK array: */
+                case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720;
+                                      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
+                                         if(SiS_Pr->PanelHT == 1344) {
+                                            VCLKIndex = VCLK_1280x720_2;
+                                         }
+                                      }
+                                      break;
+                case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
+                case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
+                case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
+                case SIS_RI_848x480:  VCLKIndex = VCLK_848x480;  break;
+                case SIS_RI_856x480:  VCLKIndex = VCLK_856x480;  break;
+                case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;
+                case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
+                case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
+                case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
+                }
+
                 if(ModeNo <= 0x13) {
                    if(HwInfo->jChipType <= SIS_315PRO) {
                       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
@@ -1906,34 +2082,28 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
              }
           }
 
-        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 /*  TV */
+        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                  /*  TV */
 
           if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-              if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
-             else                                  VCLKIndex = HiTVVCLK;
+              if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)            VCLKIndex = HiTVVCLKDIV2;
+             else                                              VCLKIndex = HiTVVCLK;
               if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
-                if(modeflag & Charx8Dot)           VCLKIndex = HiTVSimuVCLK;
-                else                               VCLKIndex = HiTVTextVCLK;
+                if(modeflag & Charx8Dot)                       VCLKIndex = HiTVSimuVCLK;
+                else                                           VCLKIndex = HiTVTextVCLK;
               }
-           } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK - TVCLKBASE_315;
-          else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)   VCLKIndex = TVVCLKDIV2;
-          else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)     VCLKIndex = TVVCLKDIV2;
-           else                                          VCLKIndex = TVVCLK;
+           } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      VCLKIndex = YPbPr750pVCLK;
+          else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)         VCLKIndex = TVVCLKDIV2;
+          else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)           VCLKIndex = TVVCLKDIV2;
+           else                                                VCLKIndex = TVVCLK;
 
-          if(HwInfo->jChipType < SIS_315H) {
-              VCLKIndex += TVCLKBASE_300;
-          } else {
-             VCLKIndex += TVCLKBASE_315;
-          }
+          if(HwInfo->jChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
+          else                             VCLKIndex += TVCLKBASE_315;
 
-        } else {                                               /* VGA2 */
+        } else {                                                       /* VGA2 */
 
-           VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
-           VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-           if(ModeNo > 0x13) {
-              VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-             if(HwInfo->jChipType < SIS_315H) {
-                VCLKIndex &= 0x3f;
+          VCLKIndex = VCLKIndexGEN;
+          if(HwInfo->jChipType < SIS_315H) {
+              if(ModeNo > 0x13) {
                 if( (HwInfo->jChipType == SIS_630) &&
                     (HwInfo->jChipRevision >= 0x30)) {
                    if(VCLKIndex == 0x14) VCLKIndex = 0x34;
@@ -1946,12 +2116,9 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
      } else {   /* If not programming CRT2 */
 
-        VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
-        VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-        if(ModeNo > 0x13) {
-           VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-          if(HwInfo->jChipType < SIS_315H) {
-              VCLKIndex &= 0x3f;
+        VCLKIndex = VCLKIndexGEN;
+       if(HwInfo->jChipType < SIS_315H) {
+           if(ModeNo > 0x13) {
              if( (HwInfo->jChipType != SIS_630) &&
                  (HwInfo->jChipType != SIS_300) ) {
                 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
@@ -1964,7 +2131,7 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
      VCLKIndex = CRT2Index;
 
-     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {  /* programming CRT2 */
+     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
 
         if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
 
@@ -2000,32 +2167,16 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
 
-          VCLKIndex >>= 6;
-          if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
-             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480))
-             VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480   ||
-                  SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-                  SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)
-             VCLKIndex = LVDSXlat4VCLK[VCLKIndex];
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
-             VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
-              VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)
-              VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)
-             VCLKIndex = VCLK68_315;
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
-             VCLKIndex = VCLK162_315;
-          else
-             VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
-
-          if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
-             /* Special Timing: Barco iQ Pro R series */
-             VCLKIndex = 0x44;
+          if(HwInfo->jChipType < SIS_315H) {
+             VCLKIndex = SiS_Pr->PanelVCLKIdx300;
+          } else {
+             VCLKIndex = SiS_Pr->PanelVCLKIdx315;
           }
 
+          /* Special Timing: Barco iQ Pro R series */
+          if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
+
+          /* Special Timing: 848x480 parallel lvds */
           if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
              if(HwInfo->jChipType < SIS_315H) {
                 VCLKIndex = VCLK34_300;
@@ -2038,28 +2189,22 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
         } else {
 
-          VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
-           VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-           if(ModeNo > 0x13) {
-              VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-             if(HwInfo->jChipType < SIS_315H) {
-                VCLKIndex &= 0x3F;
+          VCLKIndex = VCLKIndexGEN;
+          if(HwInfo->jChipType < SIS_315H) {
+              if(ModeNo > 0x13) {
+                if( (HwInfo->jChipType == SIS_630) &&
+                     (HwInfo->jChipRevision >= 0x30) ) {
+                   if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
+                }
               }
-             if( (HwInfo->jChipType == SIS_630) &&
-                  (HwInfo->jChipRevision >= 0x30) ) {
-                if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
-             }
           }
         }
 
      } else {  /* if not programming CRT2 */
 
-        VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
-        VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-        if(ModeNo > 0x13) {
-           VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-           if(HwInfo->jChipType < SIS_315H) {
-             VCLKIndex &= 0x3F;
+        VCLKIndex = VCLKIndexGEN;
+       if(HwInfo->jChipType < SIS_315H) {
+           if(ModeNo > 0x13) {
              if( (HwInfo->jChipType != SIS_630) &&
                  (HwInfo->jChipType != SIS_300) ) {
                 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
@@ -2094,21 +2239,20 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 {
   USHORT i,j,modeflag;
   USHORT tempcl,tempah=0;
-#ifdef SIS300
-  USHORT temp;
+#if defined(SIS300) || defined(SIS315H)
+  USHORT tempbl;
 #endif
 #ifdef SIS315H
-  USHORT tempbl, tempah2, tempbl2;
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+  USHORT tempah2, tempbl2;
 #endif
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
   } else {
-     if(SiS_Pr->UseCustomMode) {
-        modeflag = SiS_Pr->CModeFlag;
-     } else {
-       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     }
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
   /* BIOS does not do this (neither 301 nor LVDS) */
@@ -2123,6 +2267,9 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   } else {
 
      for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
+     if(HwInfo->jChipType >= SIS_315H) {
+        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
+     }
 
      tempcl = SiS_Pr->SiS_ModeType;
 
@@ -2132,14 +2279,14 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
         /* For 301BDH: (with LCD via LVDS) */
         if(SiS_Pr->SiS_VBType & VB_NoLCD) {
-          temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
-          temp &= 0xef;
-          temp |= 0x02;
+          tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
+          tempbl &= 0xef;
+          tempbl |= 0x02;
           if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
-             temp |= 0x10;
-             temp &= 0xfd;
+             tempbl |= 0x10;
+             tempbl &= 0xfd;
           }
-          SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
+          SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
         }
 
         if(ModeNo > 0x13) {
@@ -2226,8 +2373,8 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
         }
 
         if((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
-          if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
+          if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
+             (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)) {
              tempah |= 0x80;
           }
         } else {
@@ -2254,9 +2401,9 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                   }
         }
 
-       if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-          (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  ||
-          ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) &&
+       if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
+          (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)  ||
+          ((SiS_Pr->SiS_LCDResInfo == Panel_Custom) &&
            (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
           tempah |= 0x80;
         }
@@ -2344,10 +2491,11 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
         * in a 650 box (Jake). What is the criteria?
         */
 
-       if((IS_SIS740) || (HwInfo->jChipType >= SIS_661)) {
+       if((IS_SIS740) || (HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
           tempah = 0x30;
           tempbl = 0xc0;
-          if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+          if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
+             ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
              tempah = 0x00;
              tempbl = 0x00;
           }
@@ -2378,23 +2526,23 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
        if(IS_SIS740) {
           tempah = 0x80;
-          if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
-             tempah = 0x00;
-          }
+          if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
        } else {
           tempah = 0x00;
            tempbl = 0x7f;
            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
               tempbl = 0xff;
-             if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) {
-                tempah = 0x80;
-             }
+             if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) tempah = 0x80;
            }
            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
        }
 
-       /* 661: Sets p4 27 and 34 here, done in SetGroup4 here */
+#if 0
+       if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0xc0);
+       }
+#endif
 
 #endif /* SIS315H */
 
@@ -2423,9 +2571,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
           tempbl = 0xfb;
            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
               tempah = 0x00;
-             if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
-                tempbl = 0xff;
-             }
+             if(SiS_IsDualEdge(SiS_Pr, HwInfo)) tempbl = 0xff;
            }
           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
 
@@ -2456,14 +2602,8 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 USHORT
 SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-  USHORT resindex;
-
-  if(ModeNo <= 0x13)
-     resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-  else
-     resindex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-
-  return(resindex);
+  if(ModeNo <= 0x13) return((USHORT)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
+  else               return((USHORT)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
 }
 
 static void
@@ -2473,8 +2613,12 @@ SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
   USHORT xres,yres,modeflag=0,resindex;
 
   if(SiS_Pr->UseCustomMode) {
-     SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = SiS_Pr->CHDisplay;
-     SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
+     xres = SiS_Pr->CHDisplay;
+     if(SiS_Pr->CModeFlag & HalfDCLK) xres *= 2;
+     SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
+     yres = SiS_Pr->CVDisplay;
+     if(SiS_Pr->CModeFlag & DoubleScanMode) yres *= 2;
+     SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
      return;
   }
 
@@ -2489,7 +2633,7 @@ SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
-  if((!SiS_Pr->SiS_IF_DEF_DSTN) && (!SiS_Pr->SiS_IF_DEF_FSTN)) {
+  if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
 
      if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
         if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
@@ -2500,72 +2644,66 @@ SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
         }
      }
 
-     if(ModeNo > 0x13) {
-       if(modeflag & HalfDCLK)       xres *= 2;
-       if(modeflag & DoubleScanMode) yres *= 2;
-     }
+     if(modeflag & HalfDCLK)       xres *= 2;
+     if(modeflag & DoubleScanMode) yres *= 2;
 
   }
 
-  if(SiS_Pr->SiS_VBType & VB_SISVB) {
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+  if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+
+#if 0
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCDA | SetCRT2ToLCD | SetCRT2ToHiVision)) {
            if(xres == 720) xres = 640;
-       } else {
-          if(SiS_Pr->SiS_VBType & VB_NoLCD) {           /* 301BDH */
-               if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
-                   if(xres == 720) xres = 640;
-               }
-               if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-                  yres = 400;
-                  if(HwInfo->jChipType >= SIS_315H) {
-                     if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
-                  } else {
-                     if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
-                  }
-               }
-          } else {
-             if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
-                if(xres == 720) xres = 640;
-             }
-             if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-                if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-                   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-                      if(yres == 1024) yres = 1056;
-                   }
-                } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-                   if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-                      /* BIOS bug - does this regardless of scaling */
-                      if(yres == 400) yres = 405;
-                   }
-                   if(yres == 350) yres = 360;
-                   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
-                      if(yres == 360) yres = 375;
-                   }
-                } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-                   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-                      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-                         if(yres == 350) yres = 357;
-                         if(yres == 400) yres = 420;
-                         if(yres == 480) yres = 525;
-                      }
-                   }
-                }
+       }
+#endif
+
+       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+          switch(SiS_Pr->SiS_LCDResInfo) {
+          case Panel_1024x768:
+             if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+                 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+                   if(yres == 350) yres = 357;
+                   if(yres == 400) yres = 420;
+                   if(yres == 480) yres = 525;
+                }
+             }
+             break;
+          case Panel_1280x1024:
+             if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+                /* BIOS bug - does this regardless of scaling */
+                if(yres == 400) yres = 405;
              }
+             if(yres == 350) yres = 360;
+             if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+                 if(yres == 360) yres = 375;
+             }
+             break;
+          case Panel_1600x1200:
+             if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+                if(yres == 1024) yres = 1056;
+             }
+             break;
           }
        }
+
   } else {
-       if(xres == 720) xres = 640;
-       if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-          yres = 400;
-          if(HwInfo->jChipType >= SIS_315H) {
-             if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
-          } else {
-             if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
-          }
-          if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
-             yres = 480;
-          }
+
+     if(SiS_Pr->SiS_VBType & VB_SISVB) {
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
+           if(xres == 720) xres = 640;
        }
+     } else if(xres == 720) xres = 640;
+
+     if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+       yres = 400;
+        if(HwInfo->jChipType >= SIS_315H) {
+           if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
+        } else {
+           if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
+        }
+        if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN)  yres = 480;
+     }
+
   }
   SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
   SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
@@ -2580,103 +2718,84 @@ SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                   USHORT RefreshRateTableIndex, USHORT *ResIndex,
                   USHORT *DisplayType)
  {
-  USHORT tempbx,modeflag=0;
-  USHORT Flag,CRT2CRTC;
+  USHORT modeflag=0;
 
   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
      }
   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
-     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
+     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))    return FALSE;
   } else
      return FALSE;
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+     (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+     (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   }
 
-  Flag = 1;
-  tempbx = 0;
-  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-        Flag = 0;
-        tempbx = 18;
-        if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
-        if(SiS_Pr->SiS_TVMode & TVSetPAL) {
-          tempbx += 2;
-          if(SiS_Pr->SiS_ModeType > ModeVGA) {
-             if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
-          }
-          if(SiS_Pr->SiS_TVMode & TVSetPALM) {
-             tempbx = 18;  /* PALM uses NTSC data */
-             if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
-          } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
-             tempbx = 20;  /* PALN uses PAL data  */
-             if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
-          }
-        }
-     }
-  }
-  if(Flag) {
-     tempbx = SiS_Pr->SiS_LCDResInfo;
-     tempbx -= SiS_Pr->SiS_PanelMinLVDS;
-     if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
-        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 6;
-        if(modeflag & HalfDCLK) tempbx += 3;
-     } else {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-           tempbx = 14;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
-          if(modeflag & HalfDCLK) tempbx++;
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-           tempbx = 23;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
-          if(modeflag & HalfDCLK) tempbx++;
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
-           tempbx = 27;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
-          if(modeflag & HalfDCLK) tempbx++;
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-           tempbx = 36;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
-          if(modeflag & HalfDCLK) tempbx++;
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-           tempbx = 40;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
-          if(modeflag & HalfDCLK) tempbx++;
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
-           tempbx = 54;
-          if(modeflag & HalfDCLK) tempbx++;
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
-           tempbx = 52;
-          if(modeflag & HalfDCLK) tempbx++;
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-           tempbx = 50;
-          if(modeflag & HalfDCLK) tempbx++;
-        }
+  (*ResIndex) &= 0x3F;
 
+  if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+     (*DisplayType) = 18;
+     if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
+     if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+       (*DisplayType) += 2;
+       if(SiS_Pr->SiS_ModeType > ModeVGA) {
+          if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 99;
+       }
+       if(SiS_Pr->SiS_TVMode & TVSetPALM) {
+          (*DisplayType) = 18;  /* PALM uses NTSC data */
+          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
+       } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
+          (*DisplayType) = 20;  /* PALN uses PAL data  */
+          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
+       }
+     }
+  } else {
+     switch(SiS_Pr->SiS_LCDResInfo) {
+     case Panel_640x480:   (*DisplayType) = 50; break;
+     case Panel_640x480_2: (*DisplayType) = 52; break;
+     case Panel_640x480_3: (*DisplayType) = 54; break;
+     case Panel_800x600:   (*DisplayType) =  0; break;
+     case Panel_1024x600:  (*DisplayType) = 23; break;
+     case Panel_1024x768:  (*DisplayType) =  4; break;
+     case Panel_1152x768:  (*DisplayType) = 27; break;
+     case Panel_1280x768:  (*DisplayType) = 40; break;
+     case Panel_1280x1024: (*DisplayType) =  8; break;
+     case Panel_1400x1050: (*DisplayType) = 14; break;
+     case Panel_1600x1200: (*DisplayType) = 36; break;
+     default: return FALSE;
+     }
+
+     if(modeflag & HalfDCLK) (*DisplayType)++;
+
+     switch(SiS_Pr->SiS_LCDResInfo) {
+     case Panel_640x480:
+     case Panel_640x480_2:
+     case Panel_640x480_3:
+        break;
+     default:
+        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
      }
+
      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-        tempbx = 12;
-       if(modeflag & HalfDCLK) tempbx++;
+        (*DisplayType) = 12;
+       if(modeflag & HalfDCLK) (*DisplayType)++;
      }
   }
 
 #if 0
   if(SiS_Pr->SiS_IF_DEF_FSTN) {
      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
-        tempbx = 22;
+        (*DisplayType) = 22;
      }
   }
 #endif
 
-  *ResIndex = CRT2CRTC & 0x3F;
-  *DisplayType = tempbx;
   return TRUE;
 }
 
@@ -2685,8 +2804,7 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
               USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
               PSIS_HW_INFO HwInfo)
 {
-  USHORT tempbx=0,tempal=0;
-  USHORT Flag,resinfo=0;
+  USHORT tempbx=0,tempal=0,resinfo=0;
 
   if(ModeNo <= 0x13) {
      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
@@ -2699,55 +2817,35 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
 
-       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-          tempbx = 15;
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-          tempbx = 20;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 21;
-          else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 22;
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-          tempbx = 23;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 24;
-          else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 25;
-#if 0
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-          tempbx = 26;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 27;
-          else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 28;
-#endif
-       } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-          if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-             if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx = 13;
-             else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 14;
-             else {
-                tempbx = 29;
-                if(ModeNo >= 0x13) {
-                   /* see below */
-                   if(resinfo == SIS_RI_1280x960) tempal = 10;
-                }
-              }
-          } else {
-             tempbx = 29;
-             if(ModeNo >= 0x13) {
-                /* 1280x768 and 1280x960 have same CRT2CRTC,
-                 * so we change it here if 1280x960 is chosen
-                 */
-                if(resinfo == SIS_RI_1280x960) tempal = 10;
+        tempbx = SiS_Pr->SiS_LCDResInfo;
+       if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
+
+       if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
+          if     (resinfo == SIS_RI_1280x800)  tempal =  9;
+          else if(resinfo == SIS_RI_1400x1050) tempal = 11;
+       }
+
+       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {  /* Pass 1:1 only (center-screen handled outside) */
+          tempbx = 100;
+          if(ModeNo >= 0x13) {
+             tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
+             if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
+                (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  768)) {
+                /* Special for Fujitsu 7911 (VL-17WDX8), others custom */
+                if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768)        tempal = 0x08;
+                else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) tempal = 0x0f;
+                else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) tempal = 0x10;
              }
-          }
-       } else {
-          tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_Panel1024x768;
-          if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-              tempbx += 10;
-                  }
+          }
        }
 
 #ifdef SIS315H
        if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-          if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-             tempbx = 50;
-             if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 51;
-             else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 52;
+          if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
+             if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+                tempbx = 200;
+                if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
+             }
           }
        }
 #endif
@@ -2783,12 +2881,20 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
              (resinfo == SIS_RI_720x576) ||
              (resinfo == SIS_RI_768x576)) {
              tempal = 6;
+             if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) {
+                if(resinfo == SIS_RI_720x480) tempal = 9;
+             }
           }
           if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
               if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
-                if(resinfo == SIS_RI_1024x768) {
+                if(resinfo == SIS_RI_1024x768) tempal = 8;
+             }
+             if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
+                if((resinfo == SIS_RI_720x576) ||
+                   (resinfo == SIS_RI_768x576)) {
                    tempal = 8;
                 }
+                if(resinfo == SIS_RI_1280x720) tempal = 9;
              }
           }
        }
@@ -2799,70 +2905,54 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 
   } else {   /* LVDS, 301B-DH (if running on LCD) */
 
-     Flag = 1;
      tempbx = 0;
-     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-           Flag = 0;
-           tempbx = 10;
-          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
-           if(SiS_Pr->SiS_TVMode & TVSetPAL) {
-             tempbx += 2;
-             if(SiS_Pr->SiS_ModeType > ModeVGA) {
-                if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
-             }
-             if(SiS_Pr->SiS_TVMode & TVSetPALM) {
-                tempbx = 90;
-                if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
-             } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
-                tempbx = 92;
-                if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
-             }
-           }
+     if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+        tempbx = 10;
+       if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
+        if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+          tempbx += 2;
+          if(SiS_Pr->SiS_ModeType > ModeVGA) {
+             if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
+          }
+          if(SiS_Pr->SiS_TVMode & TVSetPALM) {
+             tempbx = 90;
+             if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
+          } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
+             tempbx = 92;
+             if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
+          }
         }
-     }
-
-     if(Flag) {
-
-       if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
-          tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 3;
+     } else {
+        switch(SiS_Pr->SiS_LCDResInfo) {
+       case Panel_640x480:   tempbx = 6;  break;
+       case Panel_640x480_2: tempbx = 30; break;
+       case Panel_640x480_3: tempbx = 30; break;
+       case Panel_800x600:   tempbx = 0;  break;
+       case Panel_1024x600:  tempbx = 15; break;
+       case Panel_1024x768:  tempbx = 2;  break;
+       case Panel_1152x768:  tempbx = 17; break;
+       case Panel_1280x768:  tempbx = 18; break;
+       case Panel_1280x1024: tempbx = 4;  break;
+       case Panel_1400x1050: tempbx = 8;  break;
+       case Panel_1600x1200: tempbx = 21; break;
+       case Panel_Barco1366: tempbx = 80; break;
+       }
 
-          if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
-             tempbx = 82;
-             if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
-          }
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-          tempbx = 18;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-          tempbx = 6;
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
-          tempbx = 30;
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
-          tempbx = 30;
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-          tempbx = 15;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 2;
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
-          tempbx = 16;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 2;
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-          tempbx = 8;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-          tempbx = 21;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) {
-          tempbx = 80;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+       switch(SiS_Pr->SiS_LCDResInfo) {
+       case Panel_640x480:
+       case Panel_640x480_2:
+       case Panel_640x480_3:
+          break;
+       default:
+          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
        }
 
-       if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-          tempbx = 7;
-        }
+       if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 7;
 
-       if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
+       if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
+          tempbx = 82;
+          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+       } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
           tempbx = 84;
           if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
        }
@@ -2870,45 +2960,17 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
      }
 
      if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempal = 7;
+        if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempal = 7;
        if(HwInfo->jChipType < SIS_315H) {
           if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
        }
      }
 
-     *CRT2Index = tempbx;
-     *ResIndex = tempal & 0x1F;
+     (*CRT2Index) = tempbx;
+     (*ResIndex) = tempal & 0x1F;
   }
 }
 
-#ifdef SIS315H
-static void
-SiS_GetCRT2PtrA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
-               USHORT RefreshRateTableIndex,USHORT *CRT2Index,
-               USHORT *ResIndex)
-{
-  USHORT tempbx,tempal;
-
-  tempbx = SiS_Pr->SiS_LCDResInfo;
-
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)      tempbx = 4;
-  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 3;
-  else tempbx -= SiS_Pr->SiS_Panel1024x768;
-
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 5;
-
-  if(ModeNo <= 0x13)
-     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  else
-     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-
-  /* No customs required yet (Clevo, Compaq, etc) */
-
-  *CRT2Index = tempbx;
-  *ResIndex = tempal & 0x1F;
-}
-#endif
-
 static void
 SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
                    USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
@@ -2969,8 +3031,7 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 
 static void
 SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
-                    USHORT RefreshRateTableIndex,
-                   PSIS_HW_INFO HwInfo)
+                    USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
 {
    USHORT CRT2Index, ResIndex;
    const SiS_LVDSDataStruct *LVDSData = NULL;
@@ -2988,23 +3049,55 @@ SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
       SiS_Pr->SiS_RY4COE = 0;
    }
 
-   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
 #ifdef SIS315H
-      SiS_GetCRT2PtrA(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                      &CRT2Index,&ResIndex);
-
-      switch (CRT2Index) {
-       case  0:  LVDSData = SiS_Pr->SiS_LCDA1024x768Data_1;    break;
-       case  1:  LVDSData = SiS_Pr->SiS_LCDA1280x1024Data_1;   break;
-       case  3:  LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_1;   break;
-       case  4:  LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_1;   break;
-       case  5:  LVDSData = SiS_Pr->SiS_LCDA1024x768Data_2;    break;
-       case  6:  LVDSData = SiS_Pr->SiS_LCDA1280x1024Data_2;   break;
-       case  8:  LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_2;   break;
-       case  9:  LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_2;   break;
-       default:  LVDSData = SiS_Pr->SiS_LCDA1024x768Data_1;    break;
+      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+         if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+           if(SiS_Pr->UseCustomMode) {
+              SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
+              SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
+           } else {
+              if(ModeNo < 0x13) {
+                 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+              } else {
+                 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
+                 /* Special for our 3 types, others custom (works with default) */
+                 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
+                    (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  768)) {
+                    if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768)        ResIndex = 0x08;
+                    else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) ResIndex = 0x0f;
+                    else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) ResIndex = 0x10;
+                 }
+                 /* Special for 1280x720 TMDS <> LVDS */
+                 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
+                    (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  720)) {
+                    if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
+                       if(SiS_Pr->PanelHT == 1344) ResIndex = 0x12;
+                    }
+                 }
+              }
+              SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
+               SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
+               SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
+               SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
+           }
+        } else {
+           SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
+            SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
+        }
+      } else {
+        /* This handles custom modes and custom panels */
+        SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
+         SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+         SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
+         SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
+        SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
+        SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
       }
+
+      SiS_CalcLCDACRT1Timing(SiS_Pr,ModeNo,ModeIdIndex);
+
 #endif
 
    } else {
@@ -3015,7 +3108,7 @@ SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
       }
 
       SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
-                     &CRT2Index, &ResIndex, HwInfo);
+                               &CRT2Index, &ResIndex, HwInfo);
 
       /* 301BDH needs LVDS Data */
       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
@@ -3023,72 +3116,59 @@ SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
       }
 
       switch (CRT2Index) {
-       case  0:  LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
-       case  1:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
-       case  2:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1;  break;
-       case  3:  LVDSData = SiS_Pr->SiS_LVDS800x600Data_2;    break;
-       case  4:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2;   break;
-       case  5:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2;  break;
-       case  6:  LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
-        case  7:  LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1;    break;
-       case  8:  LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1;  break;
-       case  9:  LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2;  break;
-       case 10:  LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
-       case 11:  LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
-       case 12:  LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
-       case 13:  LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
-       case 14:  LVDSData = SiS_Pr->SiS_LVDS320x480Data_1;    break;
-       case 15:  LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
-       case 16:  LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1;   break;
-       case 17:  LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2;   break;
-       case 18:  LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2;   break;
-       case 19:  LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1;   break;
-       case 20:  LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2;   break;
-       case 21:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1;  break;
-       case 22:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2;  break;
-       case 30:  LVDSData = SiS_Pr->SiS_LVDS640x480Data_2;    break;
-       case 80:  LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
-       case 81:  LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
-       case 82:  LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
-       case 83:  LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2;  break;
-       case 84:  LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
-       case 85:  LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
-       case 90:  LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
-       case 91:  LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
-       case 92:  LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
-       case 93:  LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
-       case 99:  LVDSData = SiS_Pr->SiS_CHTVSOPALData;        break;  /* Super Overscan */
-       default:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
-      }
-   }
-
-   SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
-   SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
-   SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
-   SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
-
-   if(SiS_Pr->SiS_VBType & VB_SISVB) {
-
-      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-         SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
-         SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+        case  0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
+        case  1: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2;    break;
+        case  2: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
+        case  3: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2;   break;
+        case  4: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1;  break;
+        case  5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2;  break;
+        case  6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
+         case  7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1;    break;
+        case  8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1;  break;
+        case  9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2;  break;
+        case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
+        case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
+        case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
+        case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
+        case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1;    break;
+        case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
+        case 16: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2;   break;
+        case 17: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1;   break;
+        case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2;   break;
+        case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1;   break;
+        case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2;   break;
+        case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1;  break;
+        case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2;  break;
+        case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2;    break;
+        case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
+        case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
+        case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
+        case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2;  break;
+        case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
+        case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
+        case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
+        case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
+        case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
+        case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
+        case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;        break;  /* Super Overscan */
+        default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
       }
 
-   } else {
+      SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
+      SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
+      SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
+      SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
 
-      if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+      if(!(SiS_Pr->SiS_VBType & VB_SISVB)) {
          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
-            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-               if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
-                 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
-                  SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
-
-                 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
-                    if(ResIndex < 0x08) {
-                       SiS_Pr->SiS_HDE = 1280;
-                        SiS_Pr->SiS_VDE = 1024;
-                    }
-                 }
+            if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+              SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
+               SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+              if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+                 if(ResIndex < 0x08) {
+                    SiS_Pr->SiS_HDE = 1280;
+                     SiS_Pr->SiS_VDE = 1024;
+                  }
                }
             }
          }
@@ -3101,25 +3181,40 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
                    USHORT RefreshRateTableIndex,
                   PSIS_HW_INFO HwInfo)
 {
-  USHORT tempax,tempbx,modeflag;
-  USHORT resinfo;
-  USHORT CRT2Index,ResIndex;
+  UCHAR  *ROMAddr = NULL;
+  USHORT tempax,tempbx,modeflag,romptr=0;
+  USHORT resinfo,CRT2Index,ResIndex;
   const SiS_LCDDataStruct *LCDPtr = NULL;
   const SiS_TVDataStruct  *TVPtr  = NULL;
+#ifdef SIS315H
+  SHORT  resinfo661;
+#endif
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
+     resinfo = 0;
   } else {
-     if(SiS_Pr->UseCustomMode) {
-        modeflag = SiS_Pr->CModeFlag;
-       resinfo = 0;
-     } else {
-       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-     }
-  }
-  
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+#ifdef SIS315H
+     resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
+     if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
+         (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
+         (resinfo661 >= 0)                     &&
+        (SiS_Pr->SiS_NeedRomModeData) ) {
+        if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+          if((romptr = (SISGETROMW(21)))) {
+              romptr += (resinfo661 * 10);
+             ROMAddr = HwInfo->pjVirtualRomBase;
+          }
+       }
+     }
+#endif
+  }
+  
   SiS_Pr->SiS_NewFlickerMode = 0;
   SiS_Pr->SiS_RVBHRS = 50;
   SiS_Pr->SiS_RY1COE = 0;
@@ -3145,6 +3240,7 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
      } else {
 
         SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+
      }
 
   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
@@ -3153,20 +3249,20 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
                     &CRT2Index,&ResIndex,HwInfo);
 
      switch(CRT2Index) {
-       case  2:  TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
-       case  3:  TVPtr = SiS_Pr->SiS_ExtPALData;    break;
-       case  4:  TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
-       case  5:  TVPtr = SiS_Pr->SiS_Ext525iData;   break;
-       case  6:  TVPtr = SiS_Pr->SiS_Ext525pData;   break;
-       case  7:  TVPtr = SiS_Pr->SiS_Ext750pData;   break;
-       case  8:  TVPtr = SiS_Pr->SiS_StPALData;     break;
-       case  9:  TVPtr = SiS_Pr->SiS_StNTSCData;    break;
-       case 10:  TVPtr = SiS_Pr->SiS_St525iData;    break;
-       case 11:  TVPtr = SiS_Pr->SiS_St525pData;    break;
-       case 12:  TVPtr = SiS_Pr->SiS_St750pData;    break;
-       case 13:  TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
-       case 14:  TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
-       default:  TVPtr = SiS_Pr->SiS_StPALData;     break;
+        case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
+        case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
+        case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
+        case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
+        case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
+        case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
+        case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
+        case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
+        case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
+        case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
+        case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
+        case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
+        case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
+        default: TVPtr = SiS_Pr->SiS_StPALData;     break;
      }
 
      SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
@@ -3247,10 +3343,11 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 
   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
 
+     SiS_Pr->SiS_RVBHCMAX  = 1;
+     SiS_Pr->SiS_RVBHCFACT = 1;
+
      if(SiS_Pr->UseCustomMode) {
 
-        SiS_Pr->SiS_RVBHCMAX  = 1;
-        SiS_Pr->SiS_RVBHCFACT = 1;
         SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
         SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
         SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
@@ -3260,58 +3357,85 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 
      } else {
 
-        SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                      &CRT2Index,&ResIndex,HwInfo);
-
-        switch(CRT2Index) {
-         case  0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
-         case  1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
-         case  5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data;         break; /* Obviously unused */
-         case  6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data;        break; /* Obviously unused */
-         case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
-         case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
-         case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768;       break; /* Non-expanding */
-         case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;      break; /* Non-expanding */
-         case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;           break; /* 1280x960 */
-         case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;       break; /* VESA Timing */
-         case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050;      break; /* Non-expanding (let panel scale) */
-         case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;        break; /* Non-VESA Timing (let panel scale) */
-         case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;       break; /* VESA Timing */
-         case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200;      break; /* Non-expanding */
-         case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;        break; /* Non-VESA Timing */
-         case 26: LCDPtr = SiS_Pr->SiS_ExtLCD1280x768Data;        break; /* VESA Timing */
-         case 27: LCDPtr = SiS_Pr->SiS_NoScaleData1280x768;       break; /* Non-expanding */
-         case 28: LCDPtr = SiS_Pr->SiS_StLCD1280x768Data;         break; /* Non-VESA Timing */
-         case 29: LCDPtr = SiS_Pr->SiS_NoScaleData;              break; /* Generic no-scale data */
+        BOOLEAN gotit = FALSE;
+
+        if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+
+           SiS_Pr->SiS_VGAHT     = SiS_Pr->PanelHT;
+           SiS_Pr->SiS_VGAVT     = SiS_Pr->PanelVT;
+           SiS_Pr->SiS_HT        = SiS_Pr->PanelHT;
+           SiS_Pr->SiS_VT        = SiS_Pr->PanelVT;
+          gotit = TRUE;
+
+       } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
+
 #ifdef SIS315H
-        case 50: LCDPtr = (SiS_LCDDataStruct *)SiS310_ExtCompaq1280x1024Data;  break;
-        case 51: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;                    break;
-        case 52: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;                     break;
+          SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
+           SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
+           SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
+           SiS_Pr->SiS_VGAVT     = ROMAddr[romptr+4] | ((ROMAddr[romptr+3] & 0xf0) << 4);
+           SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
+           SiS_Pr->SiS_VT        = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4);
+          if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
 #endif
-         default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;       break;
-        }
 
-        SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
-        SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
-        SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
-        SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
-        SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
-        SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
+       }
+
+       if(!gotit) {
+
+           SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                          &CRT2Index,&ResIndex,HwInfo);
+
+           switch(CRT2Index) {
+             case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
+             case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;
+             case Panel_1280x720      :
+             case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
+             case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
+              case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
+             case Panel_1280x768_3    :
+             case Panel_1280x768_3+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x768_3Data;    break;
+             case Panel_1280x800      :
+             case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
+             case Panel_1280x960      :
+             case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
+              case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
+              case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
+              case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
+              case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
+              case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
+              case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
+             case Panel_1680x1050     :
+             case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
+             case 100                 : LCDPtr = SiS_Pr->SiS_NoScaleData;          break;
+#ifdef SIS315H
+             case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
+             case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
+#endif
+              default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
+           }
 
 #ifdef TWDEBUG
-        xf86DrvMsg(0, X_INFO,
-           "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
+           xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
 #endif
 
-       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-           tempax = 1024;
+           SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
+           SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
+           SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
+           SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
+           SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
+           SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
+
+        }
+
+       tempax = SiS_Pr->PanelXRes;
+        tempbx = SiS_Pr->PanelYRes;
+
+       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
               if(HwInfo->jChipType < SIS_315H) {
                  if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
                  else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
-                 else                               tempbx = 768;
-              } else {
-                 tempbx = 768;
               }
            } else {
               if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
@@ -3320,43 +3444,27 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
               else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
               else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
               else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
-              else                               tempbx = 768;
            }
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-           tempax = 1280;
-           if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
-           else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
-           else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
-           else                               tempbx = 1024;
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-           tempax = 1280;
+       } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) {
            if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
            else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
            else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
-           else                                tempbx = 960;
-       } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) &&
-                 (HwInfo->jChipType >= SIS_661)) {
-          tempax = 1400;
-          tempbx = 1050;
-          if(SiS_Pr->SiS_VGAVDE == 1024) {
-             tempax = 1280;
-             tempbx = 1024;
-          }
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-           tempax = 1600;
-          tempbx = 1200;
-          if((HwInfo->jChipType < SIS_661) || (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))) {
+       } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
+           if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
+           else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
+           else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
+        } else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) {
+          if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
               if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
               else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
            }
-        } else {
-          tempax = SiS_Pr->PanelXRes;
-           tempbx = SiS_Pr->PanelYRes;
-       }
+        }
+
         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
            tempax = SiS_Pr->SiS_VGAHDE;
            tempbx = SiS_Pr->SiS_VGAVDE;
         }
+
         SiS_Pr->SiS_HDE = tempax;
         SiS_Pr->SiS_VDE = tempbx;
      }
@@ -3370,31 +3478,15 @@ SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-
-           SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-
-        } else {
-
-          if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-
-             /* Need LVDS Data for LCD on 301B-DH */
-             SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-
-          } else {
-
-             SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-
-           }
-
-        }
-
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+        SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
      } else {
-
-       SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-
+       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+          /* Need LVDS Data for LCD on 301B-DH */
+          SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+       } else {
+          SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+        }
      }
 
   } else {
@@ -3405,7 +3497,7 @@ SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 }
 
 /*********************************************/
-/*            GET LVDS DES DATA              */
+/*         GET LVDS DES (SKEW) DATA          */
 /*********************************************/
 
 static void
@@ -3413,106 +3505,55 @@ SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                   USHORT RefreshRateTableIndex, USHORT *PanelIndex,
                  USHORT *ResIndex, PSIS_HW_INFO HwInfo)
 {
-  USHORT tempbx,tempal,modeflag;
+  USHORT modeflag;
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+     (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+     (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   }
 
-  tempbx = 0;
+  (*ResIndex) &= 0x1F;
+  (*PanelIndex) = 0;
+
   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        tempbx = 50;
-        if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) tempbx += 2;
-        if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
+        (*PanelIndex) = 50;
+        if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) (*PanelIndex) += 2;
+        if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*PanelIndex) += 1;
         /* Nothing special needed for SOverscan    */
-        /*     PALM uses NTSC data, PALN uses PAL data */
+        /* PALM uses NTSC data, PALN uses PAL data */
      }
   }
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-     tempbx = SiS_Pr->SiS_LCDTypeInfo;
+     *PanelIndex = SiS_Pr->SiS_LCDTypeInfo;
      if(HwInfo->jChipType >= SIS_661) {
         /* As long as we don's use the BIOS tables, we
         * need to convert the TypeInfo as for 315 series
         */
-        tempbx = SiS_Pr->SiS_LCDResInfo - 1;
+        (*PanelIndex) = SiS_Pr->SiS_LCDResInfo - 1;
      }
-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 16;
-     if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-        tempbx = 32;
-        if(modeflag & HalfDCLK) tempbx++;
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        (*PanelIndex) += 16;
+        if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+           (*PanelIndex) = 32;
+           if(modeflag & HalfDCLK) (*PanelIndex)++;
+       }
      }
   }
 
   if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
-        tempal = 0x07;
+     if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
+        (*ResIndex) = 7;
         if(HwInfo->jChipType < SIS_315H) {
-           if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
+           if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) (*ResIndex)++;
         }
      }
   }
-
-  *PanelIndex = tempbx;
-  *ResIndex = tempal & 0x1F;
-}
-
-#ifdef SIS315H
-static void
-SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex, USHORT *PanelIndex, USHORT *ResIndex,
-                  PSIS_HW_INFO HwInfo)
-{
-  USHORT tempbx=0,tempal;
-
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)      tempbx = 2;
-  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 3;
-  else tempbx = SiS_Pr->SiS_LCDResInfo - 2;
-
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 4;
-
-  if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-        if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
-          tempbx = 80;
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
-       }
-     }
-  }
-  if((SiS_Pr->SiS_CustomT == CUT_UNIWILL1024) ||
-     (SiS_Pr->SiS_CustomT == CUT_UNIWILL10242)) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-       tempbx = 82;
-       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
-     }
-  }
-  if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-       tempbx = 84;
-       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
-     }
-  }
-  if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-       tempbx = 86;
-       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
-     }
-  }
-
-  if(ModeNo <= 0x13)
-     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  else
-     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-
-  *PanelIndex = tempbx;
-  *ResIndex = tempal & 0x1F;
 }
-#endif
 
 static void
 SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
@@ -3522,39 +3563,45 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
   USHORT PanelIndex,ResIndex;
   const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
 
-  if((SiS_Pr->UseCustomMode) ||
-     (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) ||
-     (SiS_Pr->SiS_CustomT == CUT_PANEL848)) {
-     SiS_Pr->SiS_LCDHDES = 0;
-     SiS_Pr->SiS_LCDVDES = 0;
+  SiS_Pr->SiS_LCDHDES = 0;
+  SiS_Pr->SiS_LCDVDES = 0;
+
+  if( (SiS_Pr->UseCustomMode)                   ||
+      (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||
+      (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||
+      ((SiS_Pr->SiS_VBType & VB_SISVB) &&
+       (SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
+       (SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
      return;
   }
 
   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
 #ifdef SIS315H
-     SiS_GetLVDSDesPtrA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
-                        &PanelIndex, &ResIndex, HwInfo);
-
-     switch (PanelIndex)
-     {
-       case  0: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1;   break;  /* --- expanding --- */
-       case  1: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_1;  break;
-       case  2: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_1;  break;
-       case  3: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_1;  break;
-       case  4: PanelDesPtr = SiS_Pr->LVDS1024x768Des_2;   break;  /* --- non expanding --- */
-       case  5: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_2;  break;
-       case  6: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_2;  break;
-       case  7: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_2;  break;
-       case 80: PanelDesPtr = (SiS_LVDSDesStruct *)Clevo1024x768Des_1;   break;  /*  custom  */
-       case 81: PanelDesPtr = (SiS_LVDSDesStruct *)Clevo1024x768Des_2;   break;
-       case 82: PanelDesPtr = (SiS_LVDSDesStruct *)Uniwill1024x768Des_1; break;
-       case 83: PanelDesPtr = (SiS_LVDSDesStruct *)Uniwill1024x768Des_2; break;
-       case 84: PanelDesPtr = (SiS_LVDSDesStruct *)Compaq1280x1024Des_1; break;
-       case 85: PanelDesPtr = (SiS_LVDSDesStruct *)Compaq1280x1024Des_2; break;
-       case 86: PanelDesPtr = (SiS_LVDSDesStruct *)Asus1024x768Des_1;    break;  /*  custom  */
-       case 87: PanelDesPtr = (SiS_LVDSDesStruct *)Asus1024x768Des_2;    break;
-       default: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1;   break;
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        /* non-pass 1:1 only, see above */
+        if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
+           SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
+       }
+       if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
+          SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
+       }
+     }
+     if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
+        switch(SiS_Pr->SiS_CustomT) {
+        case CUT_UNIWILL1024:
+        case CUT_UNIWILL10242:
+        case CUT_CLEVO1400:
+          if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+             SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+          }
+          break;
+       }
+       if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
+          if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
+             SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+          }
+       }
      }
 #endif
 
@@ -3563,87 +3610,68 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
      SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
                        &PanelIndex, &ResIndex, HwInfo);
 
-     switch (PanelIndex)
-     {
-       case  0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1;   break;   /* ---  */
-       case  1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1;   break;
-       case  2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1;   break;
-       case  3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1;   break;
-       case  4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1;   break;
-       case  5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1;   break;
-       case  6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1;   break;
-       case  7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1;   break;
-       case  8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1;   break;
-       case  9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1;   break;
-       case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1;   break;
-       case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1;   break;
-       case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1;   break;
-       case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1;   break;
-       case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;   break;
-       case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1;   break;
-       case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2;   break;    /* --- */
-       case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2;   break;
-       case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2;   break;
-       case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2;   break;
-       case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2;   break;
-       case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2;   break;
-       case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2;   break;
-       case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2;   break;
-       case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2;   break;
-       case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2;   break;
-       case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2;   break;
-       case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2;   break;
-       case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2;   break;
-       case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2;   break;
-       case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2;   break;
-       case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2;   break;
-       case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1;   break;    /* pass 1:1 */
-       case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2;   break;
-       case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData;   break; /* TV */
-       case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData;   break;
-       case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;    break;
-       case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;    break;
-       default:
-                if(HwInfo->jChipType < SIS_315H)
-                   PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
-                else
-                   PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
-                break;
-     }
-  }
-  SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
-  SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
-
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD){
-     if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-        if(ModeNo <= 0x13) {
-           modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-          if(!(modeflag & HalfDCLK)) {
-             SiS_Pr->SiS_LCDHDES = 632;
-          }
-        }
-     } else {
-        if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
-           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
-              if(SiS_Pr->SiS_LCDResInfo >= SiS_Pr->SiS_Panel1024x768) {
-                 if(ModeNo <= 0x13) {
-                   modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-                   if(HwInfo->jChipType < SIS_315H) {
-                      if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
-                   } else {
-                      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
-                         SiS_Pr->SiS_LCDHDES = 480;
-                       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
-                         SiS_Pr->SiS_LCDHDES = 804;
-                      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
-                         SiS_Pr->SiS_LCDHDES = 704;
-                       if(!(modeflag & HalfDCLK)) {
-                          SiS_Pr->SiS_LCDHDES = 320;
-                         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
-                            SiS_Pr->SiS_LCDHDES = 632;
-                         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
-                            SiS_Pr->SiS_LCDHDES = 542;
-                       }
+     switch(PanelIndex) {
+       case  0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1;    break;   /* ---  */
+       case  1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1;    break;
+       case  2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1;    break;
+       case  3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1;    break;
+       case  4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1;    break;
+       case  5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1;    break;
+       case  6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1;    break;
+       case  7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1;    break;
+       case  8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1;    break;
+       case  9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1;    break;
+       case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1;    break;
+       case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1;    break;
+       case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1;    break;
+       case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1;    break;
+       case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;    break;
+       case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1;    break;
+       case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2;    break;    /* --- */
+       case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2;    break;
+       case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2;    break;
+       case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2;    break;
+       case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2;    break;
+       case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2;    break;
+       case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2;    break;
+       case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2;    break;
+       case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2;    break;
+       case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2;    break;
+       case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2;    break;
+       case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2;    break;
+       case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2;    break;
+       case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2;    break;
+       case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2;    break;
+       case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2;    break;
+       case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1;    break;    /* pass 1:1 */
+       case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2;    break;
+       case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break;    /* TV */
+       case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
+       case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;  break;
+       case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;  break;
+       default: return;
+     }
+
+     SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
+     SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
+
+     if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+        if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+          if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
+        } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+           if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
+              if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
+                if(HwInfo->jChipType < SIS_315H) {
+                   if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
+                } else {
+                   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
+                    if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
+                   if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
+                    if(!(modeflag & HalfDCLK)) {
+                       SiS_Pr->SiS_LCDHDES = 320;
+                      if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
+                      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
                     }
                  }
               }
@@ -3653,18 +3681,6 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
   }
 }
 
-/*********************************************/
-/*          SET CRT2 AUTO-THRESHOLD          */
-/*********************************************/
-
-#ifdef SIS315H
-static void
-SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr)
-{
-  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
-}
-#endif
-
 /*********************************************/
 /*           DISABLE VIDEO BRIDGE            */
 /*********************************************/
@@ -3683,55 +3699,40 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== For 30xB/LV ===== */
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== For 30xB/LV ===== */
 
         if(HwInfo->jChipType < SIS_315H) {
 
 #ifdef SIS300     /* 300 series */
 
-           if(HwInfo->jChipType == SIS_300) {  /* For 300+301LV (A907) */
-
-             if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
-                if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-                   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
-                   SiS_PanelDelay(SiS_Pr, HwInfo, 3);
-                }
+          if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
+             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
+             } else {
+                SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
              }
+             SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+          }
+          if(SiS_Is301B(SiS_Pr)) {
              SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
              SiS_ShortDelay(SiS_Pr,1);
-             SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
-             SiS_DisplayOff(SiS_Pr);
-             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-                if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
-                    (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
-                   SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-                    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
-                }
-             }
-
-          } else {
-
-             if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
-                SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
-                SiS_PanelDelay(SiS_Pr, HwInfo, 3);
-             }
-             if(SiS_Is301B(SiS_Pr)) {
-                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
-                SiS_ShortDelay(SiS_Pr,1);
-             }
-             SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
-             SiS_DisplayOff(SiS_Pr);
-             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-             SiS_UnLockCRT2(SiS_Pr,HwInfo);
+           }
+          SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+          SiS_DisplayOff(SiS_Pr);
+          SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+          SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+          SiS_UnLockCRT2(SiS_Pr,HwInfo);
+          if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
-             if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
-                 (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
-                SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-                 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
+          }
+          if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
+              (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
+             SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+                 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+             } else {
+                SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
              }
           }
 
@@ -3741,149 +3742,99 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
 #ifdef SIS315H    /* 315 series */
 
-           if(IS_SIS550650740660) {            /* 550, 650, 740, 660 */
+          BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+                             (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
+
+          modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
 
-             modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
+           if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
 
-              if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {                      /* LV */
 #ifdef SET_EMI
-                if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-                   if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
-                      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
-                   }
+             if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+                if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
+                   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
                 }
+             }
 #endif
-                if( (modenum <= 0x13) ||
-                    (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
-                    (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
-                   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
-                   if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
-                      (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
-                      SiS_PanelDelay(SiS_Pr, HwInfo, 3);
-                   }
-                }
+             if( (modenum <= 0x13)                  ||
+                 (SiS_IsVAMode(SiS_Pr,HwInfo))      ||
+                 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
+                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
+                if(custom1) SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+             }
 
-                if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
-                   (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
-                   SiS_DDC2Delay(SiS_Pr,0xff00);
-                   SiS_DDC2Delay(SiS_Pr,0xe000);
+             if(!custom1) {
+                SiS_DDC2Delay(SiS_Pr,0xff00);
+                SiS_DDC2Delay(SiS_Pr,0xe000);
+                SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
+                 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
+                if(IS_SIS740) {
+                   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+                }
+                SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+             }
 
-                   SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
+           }
 
-                    pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
+          if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
+             tempah = 0xef;
+             if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
+             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+          }
 
-                   if(IS_SIS740) {
-                      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
-                   }
+          if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
+          }
 
-                   SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+          tempah = 0x3f;
+          if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
+             tempah = 0x7f;
+             if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) tempah = 0xbf;
+          }
+          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
 
-                   if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
-                      tempah = 0xef;
-                      if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
-                         tempah = 0xf7;
-                       }
-                      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
-                   }
-                }
+           if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+             ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
 
-              } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {                       /* B-DH */
+             SiS_DisplayOff(SiS_Pr);
+             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+                SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+             }
+             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
 
-                if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
-                   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,0xef);
-                }
+          }
 
-             }
+          if((!(SiS_IsVAMode(SiS_Pr,HwInfo))) ||
+             ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
 
-             if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
-                (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
-                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xef);
+             if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
+                SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+                SiS_DisplayOff(SiS_Pr);
              }
+             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
 
-              if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
-                (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
-                (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
-                tempah = 0x3f;
-                if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
-                   tempah = 0x7f;
-                   if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
-                      tempah = 0xbf;
-                    }
-                }
-                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+                SiS_PanelDelay(SiS_Pr, HwInfo, 2);
              }
 
-              if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
-                ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
-
-                if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
-                   (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
-                   (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
-                   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
-                   SiS_DisplayOff(SiS_Pr);
-                   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-                } else {
-                   SiS_DisplayOff(SiS_Pr);
-                   SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-                   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-                   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
-                   if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13)) {
-                      SiS_DisplayOff(SiS_Pr);
-                      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-                      SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-                      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-                      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
-                       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
-                      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-                      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
-                   }
-                }
-
-             } else {
-
-                if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
-                   (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
-                   (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
-                   if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
-                      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
-                      SiS_DisplayOff(SiS_Pr);
-                   }
-                   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-                } else {
-                    SiS_DisplayOff(SiS_Pr);
-                   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-                   SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-                }
-
-                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-                temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
-                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
-                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-                SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
-
-             }
+             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+             temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
+              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+             SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
 
-             if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) &&
-                (SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
-                (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
+          }
 
-                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);
+          if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
+             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+          }
 
-                tempah = 0x3f;
-                if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
-                   tempah = 0x7f;
-                   if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
-                      tempah = 0xbf;
-                    }
-                }
-                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+          if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
 
-                if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
-                   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-                }
+             if(!custom1) {
 
                 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
-                   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
                    if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
                       if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
                          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
@@ -3894,95 +3845,39 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
                 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
 
                 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-                   if( (SiS_IsVAMode(SiS_Pr, HwInfo)) ||
-                       (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
+                   if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
                       SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
                    }
                 }
 
-             } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
-
-                /* NIL */
-
-             } else if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
-                       (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
-                       (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+             } else {
 
-                if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
-                   tempah = 0xef;
-                   if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
-                      if(modenum > 0x13) {
-                         tempah = 0xf7;
-                      }
-                    }
-                   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
-                }
-                if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
-                   (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
-                   if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
-                      (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
-                      if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
-                         (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
-                         SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-                         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
-                         SiS_PanelDelay(SiS_Pr, HwInfo, 4);
-                      }
+                if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+                   (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
+                   if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
+                      (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
+                      SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+                      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+                      SiS_PanelDelay(SiS_Pr, HwInfo, 4);
                    }
                 }
 
              }
-
-         } else {                      /* 315, 330 - all bridge types */
-
-            if(SiS_Is301B(SiS_Pr)) {
-               tempah = 0x3f;
-               if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
-                  tempah = 0x7f;
-                  if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
-                     tempah = 0xbf;
-                   }
-               }
-               SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
-               if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
-                  SiS_DisplayOff(SiS_Pr);
-                  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-               }
-            }
-            if( (!(SiS_Is301B(SiS_Pr))) ||
-                (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
-
-               if( (!(SiS_Is301B(SiS_Pr))) ||
-                   (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
-
-                  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
-                  SiS_DisplayOff(SiS_Pr);
-
-               }
-
-                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-
-                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-
-               temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
-                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
-               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
-
-            }
-
-         }    /* 315/330 */
+           }
 
 #endif /* SIS315H */
 
        }
 
-      } else {     /* ============ For 301 ================ */
+     } else {     /* ============ For 301 ================ */
 
         if(HwInfo->jChipType < SIS_315H) {
+#ifdef SIS300
            if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
              SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
              SiS_PanelDelay(SiS_Pr, HwInfo, 3);
           }
+#endif
        }
 
         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
@@ -4000,12 +3895,14 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
            SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
        } else {
+#ifdef SIS300
             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
            if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
                (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
                SiS_PanelDelay(SiS_Pr, HwInfo, 2);
                SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
            }
+#endif
        }
 
       }
@@ -4064,6 +3961,10 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
 #ifdef SIS315H /* 315 series */
 
+        if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
+          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
+        }
+
        if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
 
           if(HwInfo->jChipType == SIS_740) {
@@ -4194,7 +4095,6 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
   BOOLEAN delaylong = FALSE;
 #endif
 
-
   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ====== For 301B et al  ====== */
@@ -4203,28 +4103,55 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
 #ifdef SIS300     /* 300 series */
 
-         if(HwInfo->jChipType == SIS_300) {
-
-           if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
-              if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-                 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
-                 if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
-                    SiS_PanelDelay(SiS_Pr, HwInfo, 0);
-                 }
+        if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+           if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+              SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+           } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+              SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
+           }
+           if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_NoLCD)) {
+              if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
+                 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
               }
            }
+        }
+
+        if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
+           (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
+
+           SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* Enable CRT2 */
+            SiS_DisplayOn(SiS_Pr);
+           SiS_UnLockCRT2(SiS_Pr,HwInfo);
+           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
+           if(SiS_BridgeInSlavemode(SiS_Pr)) {
+              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
+           } else {
+              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
+            }
+           if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+              if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+                 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
+                    SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+                  }
+                 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+                  SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
+               }
+           }
+
+        } else {
+
            temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
-            if(SiS_BridgeInSlave(SiS_Pr)) {
+            if(SiS_BridgeInSlavemode(SiS_Pr)) {
                tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-               if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+               if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
             }
             SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
            SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
            SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
            SiS_DisplayOn(SiS_Pr);
-           if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
-              if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+           if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+              if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
                  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
                     if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
                        SiS_PanelDelay(SiS_Pr, HwInfo, 1);
@@ -4234,440 +4161,279 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
               }
            }
 
-        } else {
+        }
 
-           if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
-              (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
-              /* This is only for LCD output on 301B-DH via LVDS */
-              SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
-              if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
-                 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
-              }
-              SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   /* Enable CRT2 */
-               SiS_DisplayOn(SiS_Pr);
-              SiS_UnLockCRT2(SiS_Pr,HwInfo);
-              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
-              if(SiS_BridgeInSlave(SiS_Pr)) {
-                 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
-              } else {
-                 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
-               }
-              if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
-                  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
-                      if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
-                          SiS_PanelDelay(SiS_Pr, HwInfo, 1);
-                       }
-                      SiS_WaitVBRetrace(SiS_Pr,HwInfo);
-                       SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
-                   }
-              }
-            } else {
-              temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
-               if(SiS_BridgeInSlave(SiS_Pr)) {
-                  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-                  if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
-               }
-               SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
-              SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
-              SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
-              SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
-              SiS_DisplayOn(SiS_Pr);
-           }
 
-         }
 #endif /* SIS300 */
 
       } else {
 
 #ifdef SIS315H    /* 315 series */
 
-        if(IS_SIS550650740660) {               /* 550, 650, 740, 660 */
-
-           UCHAR r30=0, r31=0, r32=0, r33=0, cr36=0;
-
-           if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+#ifdef SET_EMI
+        UCHAR   r30=0, r31=0, r32=0, r33=0, cr36=0;
+        /* USHORT  emidelay=0; */
+#endif
 
-              if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
-                 (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
-                 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
+        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
 #ifdef SET_EMI
-                 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-                    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
-                 }
+           if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+              SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+           }
 #endif
-              }
+        }
 
-               if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
-                 tempah = 0x10;
-                 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
-                    if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
-                    else                              tempah = 0x08;
-                 }
-                 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
-              }
+         if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
+           tempah = 0x10;
+           if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
+              if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
+              else                              tempah = 0x08;
+           }
+           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+        }
 
-              if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
-                 (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
-                 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
-                 SiS_DisplayOff(SiS_Pr);
-                 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
-                 if(IS_SIS740) {
-                    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
-                 }
-              }
+        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
 
-              if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
-                  (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
-                  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
-                    if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
-                       (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
-                       SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
-                       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
-                       if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-                          SiS_GenericDelay(SiS_Pr, 0x4500);
-                       }
-                       SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
-                    } else {
-                       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
-                       SiS_PanelDelay(SiS_Pr, HwInfo, 0);
-                    }
-                 }
-              }
+           SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
+           SiS_DisplayOff(SiS_Pr);
+           pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
+           if(IS_SIS740) {
+              SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+           }
 
-               if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
-                 (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
-                 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
-                     SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
-                    delaylong = TRUE;
+           if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
+               if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+                 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
+                 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+                 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
+                 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+                    SiS_GenericDelay(SiS_Pr, 0x4500);
                  }
               }
+           }
 
-           } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+           if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
+               SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+              delaylong = TRUE;
+           }
 
-              if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
-                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x10);
-              }
+        }
 
-           } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+        if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
 
-              if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
-                 tempah = 0x10;
-                 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
-                    if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
-                    else                              tempah = 0x08;
-                 }
-                 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+            temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+           if(SiS_BridgeInSlavemode(SiS_Pr)) {
+               tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+               if(!(tempah & SetCRT2ToRAMDAC)) {
+                 if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
               }
+            }
+            SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
 
-           }
-
-           if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
-               temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
-              if(SiS_BridgeInSlave(SiS_Pr)) {
-                  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-                  if(!(tempah & SetCRT2ToRAMDAC)) {
-                    if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
-                 }
-               }
-               SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
+           SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
 
-              SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
+           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
 
-              if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
-                 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
-                 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
-                 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-                 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2e);
-                 if(!(temp & 0x80)) {
-                    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
-                 }
-              } else {
-                 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-              }
-           } else {
-              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+           if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+              SiS_PanelDelay(SiS_Pr, HwInfo, 2);
            }
 
-           SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+        } else {
 
-           if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
-              (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
-              (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
-              temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2e);
-              if(!(temp & 0x80)) {
-                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
-              }
-           }
+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
 
-           tempah = 0xc0;
-           if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
-              tempah = 0x80;
-              if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) {
-                 tempah = 0x40;
-               }
-           }
-            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+        }
 
-           if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
-              (((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
-                (SiS_Pr->SiS_CustomT == CUT_CLEVO1400))     &&
-               (!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))))) {
-               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-           }
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
 
-           if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+        tempah = 0xc0;
+        if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
+           tempah = 0x80;
+           if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) tempah = 0x40;
+        }
+         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
 
-              if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
-                 (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
-                 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-              }
-#ifdef COMPAQ_HACK
-              if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-                 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-              }
-#endif
+        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+
+           SiS_PanelDelay(SiS_Pr, HwInfo, 2);
 
-              SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
+           SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
 
-              if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
+           if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
 #ifdef SET_EMI
-                 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-                    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
-                 }
+              if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+                 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+              }
 #endif
-                 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+              SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+
+              if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
 #ifdef SET_EMI
-                 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-
-                    cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
-
-                    /*                                              (P4_30|0x40)  */
-                    /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
-                    /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
-                    /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
-                    /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
-                    /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
-                    /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
-                    /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
-                    /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
-                    /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
-
-                    if(SiS_Pr->HaveEMI) {
-                       r30 = SiS_Pr->EMI_30;
-                       r31 = SiS_Pr->EMI_31;
-                       r32 = SiS_Pr->EMI_32;
-                       r33 = SiS_Pr->EMI_33;
-                    } else {
-                       r30 = 0;
+                 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
+
+                 if(SiS_Pr->SiS_ROMNew) {
+                    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+                    USHORT romptr   = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
+                    if(romptr) {
+                       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+                       SiS_Pr->EMI_30 = 0;
+                       SiS_Pr->EMI_31 = ROMAddr[romptr + 14];
+                       SiS_Pr->EMI_32 = ROMAddr[romptr + 15];
+                       SiS_Pr->EMI_33 = ROMAddr[romptr + 16];
+                       if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
+                       /* emidelay = SISGETROMW((romptr + 0x22)); */
+                       SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
                     }
+                 }
 
-                    /* EMI_30 is read at driver start; however, the BIOS sets this
-                     * (if it is used) only if the LCD is in use. In case we caught
-                     * the machine while on TV output, this bit is not set and we
-                     * don't know if it should be set - hence our detection is wrong.
-                     * Work-around this here:
-                     */
-
-                    if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
-                       if((cr36 & 0x0f) == 0x02) {                     /* 1024x768 */
-                          r30 |= 0x40;
-                          if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
-                             r30 &= ~0x40;
-                          }
-                       } else if((cr36 & 0x0f) == 0x03) {              /* 1280x1024 */
-                          r30 |= 0x40;
-                          if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
-                             r30 &= ~0x40;
-                          }
-                       } else if((cr36 & 0x0f) == 0x09) {              /* 1400x1050 */
-                          r30 |= 0x40;
-                       } else if((cr36 & 0x0f) == 0x0b) {              /* 1600x1200 - unknown */
-                          r30 |= 0x40;
-                       }
-                     }
+                 /*                                              (P4_30|0x40)  */
+                 /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
+                 /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
+                 /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
+                 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
+                 /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
+                 /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
+                 /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
+                 /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
+                 /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
+
+                 if(SiS_Pr->HaveEMI) {
+                    r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
+                    r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
+                 } else {
+                    r30 = 0;
+                 }
 
-                    if(!SiS_Pr->HaveEMI) {
-                       if((cr36 & 0x0f) == 0x02) {
+                 /* EMI_30 is read at driver start; however, the BIOS sets this
+                  * (if it is used) only if the LCD is in use. In case we caught
+                  * the machine while on TV output, this bit is not set and we
+                  * don't know if it should be set - hence our detection is wrong.
+                  * Work-around this here:
+                  */
+
+                 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
+                    switch((cr36 & 0x0f)) {
+                    case 2:
+                       r30 |= 0x40;
+                       if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
+                       if(!SiS_Pr->HaveEMI) {
+                          r31 = 0x05; r32 = 0x60; r33 = 0x33;
                           if((cr36 & 0xf0) == 0x30) {
                              r31 = 0x0d; r32 = 0x70; r33 = 0x40;
-                          } else {
-                             r31 = 0x05; r32 = 0x60; r33 = 0x33;
                           }
-                       } else if((cr36 & 0x0f) == 0x03) {
+                       }
+                       break;
+                    case 3:  /* 1280x1024 */
+                       if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
+                       if(!SiS_Pr->HaveEMI) {
+                          r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
                           if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
                              r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
-                          } else {
-                             r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
                           }
-                       } else if((cr36 & 0x0f) == 0x09) {
+                       }
+                       break;
+                    case 9:  /* 1400x1050 */
+                       r30 |= 0x40;
+                       if(!SiS_Pr->HaveEMI) {
+                          r31 = 0x05; r32 = 0x60; r33 = 0x00;
                           if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
                              r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
-                          } else {
-                             r31 = 0x05; r32 = 0x60; r33 = 0x00;
                           }
-                       } else {
+                       }
+                       break;
+                    case 11: /* 1600x1200 - unknown */
+                       r30 |= 0x40;
+                       if(!SiS_Pr->HaveEMI) {
                           r31 = 0x05; r32 = 0x60; r33 = 0x00;
                        }
                     }
+                  }
 
-                    /* BIOS values don't work so well sometimes */
-                    if(!SiS_Pr->OverruleEMI) {
+                 /* BIOS values don't work so well sometimes */
+                 if(!SiS_Pr->OverruleEMI) {
 #ifdef COMPAL_HACK
-                       if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
-                          if((cr36 & 0x0f) == 0x09) {
-                             r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
-                          }
-                       }
+                    if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
+                       if((cr36 & 0x0f) == 0x09) {
+                          r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
+                       }
+                    }
 #endif
 #ifdef COMPAQ_HACK
-                       if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-                          if((cr36 & 0x0f) == 0x03) {
-                             r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;     /* rev 1 */
-                          }
+                    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+                       if((cr36 & 0x0f) == 0x03) {
+                          r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
                        }
+                    }
 #endif
 #ifdef ASUS_HACK
-                       if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
-                          if((cr36 & 0x0f) == 0x02) {
-                             /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
-                             /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
-                             /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
-                             /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
-                          }
+                    if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
+                       if((cr36 & 0x0f) == 0x02) {
+                          /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
+                          /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
+                          /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
+                          /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
                        }
-#endif
-                    }
-                    if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
-                       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
                     }
-                    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
-                    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
-                    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
-                    if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
-                       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
-                    } else {
-                       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x00);
-                    }
-                    if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
-                        (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
-                       if(r30 & 0x40) {
-                          SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
-                          if(delaylong) {
-                             SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
-                             delaylong = FALSE;
-                          }
-                          SiS_WaitVBRetrace(SiS_Pr,HwInfo);
-                          if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
-                             SiS_GenericDelay(SiS_Pr, 0x500);
-                          }
-                          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
-                       }
-                    }
-                 }
 #endif
-              }
-
-              if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-
-                 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
-                     (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
-                    SiS_DisplayOn(SiS_Pr);
-                    SiS_PanelDelay(SiS_Pr, HwInfo, 1);
-                    SiS_WaitVBRetrace(SiS_Pr, HwInfo);
-                    SiS_PanelDelay(SiS_Pr, HwInfo, 3);
-                    if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
-                       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
-                    }
-                 }
-
-              } else if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
+                 }
 
-                 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
-                    if( (SiS_IsVAMode(SiS_Pr, HwInfo)) ||
-                        (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
-                       SiS_DisplayOn(SiS_Pr);
-                       SiS_PanelDelay(SiS_Pr, HwInfo, 1);
-                       SiS_WaitVBRetrace(SiS_Pr,HwInfo);
-                       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
-                    }
+                 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
+                    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
                  }
+                 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
+                 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
+                 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
+#endif /* SET_EMI */
 
-              } else {
+                 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
 
-                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
-                 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
-                    if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
-                        ((SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ) {
-                       SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
-                       if(delaylong) {
-                          SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
-                       }
-                        SiS_WaitVBRetrace(SiS_Pr,HwInfo);
-                       if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+#ifdef SET_EMI
+                 if( (SiS_LCDAEnabled(SiS_Pr, HwInfo)) ||
+                     (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
+                    if(r30 & 0x40) {
+                       SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
+                       if(delaylong) {
+                          SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
+                          delaylong = FALSE;
+                       }
+                       SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+                       if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
                           SiS_GenericDelay(SiS_Pr, 0x500);
                        }
-                       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+                       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
                     }
-                 }
-
-                 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
-                 SiS_DisplayOn(SiS_Pr);
-                 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
-
-                 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
-                    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-                 }
-
+                 }
+#endif
               }
-
            }
 
-        } else {                       /* 315, 330 */
-
-           if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
-              temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
-              if(SiS_BridgeInSlave(SiS_Pr)) {
-                  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-                  if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
-               }
-               SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
-
-              SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
-
-              temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
-               if(!(temp & 0x80))
-                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
-            }
-
-           SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
-
-           if(SiS_Is301B(SiS_Pr)) {
-
-              temp=SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
-               if(!(temp & 0x80))
-                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
-
-              tempah = 0xc0;
-              if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
-                 tempah = 0x80;
-                 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
-                    tempah = 0x40;
-                  }
+           if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+              if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
+                 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+                 if(delaylong) {
+                    SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+                 }
+                  SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+                 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+                    SiS_GenericDelay(SiS_Pr, 0x500);
+                 }
+                 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
               }
-               SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
-
-              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-
-           } else {
+           }
 
-              SiS_VBLongWait(SiS_Pr);
-               SiS_DisplayOn(SiS_Pr);
-              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
-               SiS_VBLongWait(SiS_Pr);
+           SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
+           SiS_DisplayOn(SiS_Pr);
+           SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
 
-           }
+        }
 
-        }   /* 315, 330 */
+        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+        }
 
 #endif /* SIS315H */
 
@@ -4683,9 +4449,9 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
        }
 
        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
-       if(SiS_BridgeInSlave(SiS_Pr)) {
+       if(SiS_BridgeInSlavemode(SiS_Pr)) {
           tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-          if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+          if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
        }
        SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
 
@@ -4734,11 +4500,11 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
          }
        }
 
-       SiS_EnableCRT2(SiS_Pr);
+       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
        SiS_DisplayOn(SiS_Pr);
        SiS_UnLockCRT2(SiS_Pr,HwInfo);
        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
-       if(SiS_BridgeInSlave(SiS_Pr)) {
+       if(SiS_BridgeInSlavemode(SiS_Pr)) {
          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
        } else {
          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
@@ -4770,6 +4536,10 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
 #ifdef SIS315H    /* 315 series */
 
+       if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
+          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
+       }
+
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
          if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
             SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
@@ -4777,7 +4547,7 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
           }
        }
 
-       SiS_EnableCRT2(SiS_Pr);
+       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
        SiS_UnLockCRT2(SiS_Pr,HwInfo);
 
        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
@@ -4868,33 +4638,31 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*         SET PART 1 REGISTER GROUP         */
 /*********************************************/
 
-/********** Set CRT2 OFFSET / PITCH **********/
+/* Set CRT2 OFFSET / PITCH */
 static void
-SiS_SetCRT2Offset(SiS_Private *SiS_Pr,USHORT ModeNo,
-                  USHORT ModeIdIndex ,USHORT RefreshRateTableIndex,
-                 PSIS_HW_INFO HwInfo)
+SiS_SetCRT2Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                 USHORT RRTI, PSIS_HW_INFO HwInfo)
 {
   USHORT offset;
   UCHAR temp;
 
   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
 
-  offset = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
-                         HwInfo);
+  offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI,HwInfo);
 
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-     SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) offset >>= 1;
+  if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
+     (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
+     offset >>= 1;
+  }
 
-  temp = (UCHAR)(offset & 0xFF);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,temp);
-  temp = (UCHAR)(offset >> 8);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
   temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
   if(offset % 8) temp++;
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
 }
 
-/************* Set CRT2 Sync *************/
+/* Set CRT2 sync and PanelLink mode */
 static void
 SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
                 PSIS_HW_INFO HwInfo)
@@ -4916,23 +4684,27 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex
      } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
         tempah = SiS_Pr->SiS_LCDInfo;
      } else tempah = infoflag >> 8;
-
      tempah &= 0xC0;
-
      tempah |= 0x20;
      if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
         if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
            (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-          tempah |= 0xc0;
+          tempah |= 0xf0;
+        }
+       if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
+            (SiS_Pr->SiS_IF_DEF_DSTN) ||
+            (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
+            (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
+           tempah |= 0x30;
         }
      }
-
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
         if(HwInfo->jChipType >= SIS_315H) {
            tempah >>= 3;
+          tempah &= 0x18;
            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
+          /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
         } else {
            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
         }
@@ -4949,19 +4721,21 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex
         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {                  /* 630 - 301B(-DH) */
 
           tempah = infoflag >> 8;
+          tempbl = 0;
            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
              if(SiS_Pr->SiS_LCDInfo & LCDSync) {
                 tempah = SiS_Pr->SiS_LCDInfo;
+                tempbl = (tempah >> 6) & 0x03;
               }
            }
            tempah &= 0xC0;
-
            tempah |= 0x20;
            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-
-          tempah &= 0x3f;
-          tempah |= tempbl;
+          tempah |= 0xc0;
            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+             SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
+          }
 
         } else {                                                       /* 630 - 301 */
 
@@ -4979,43 +4753,72 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex
 
 #ifdef SIS315H  /* ------- 315 series ------ */
 
-        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {                    /* 315 - 30xLV */
+        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {                    /* 315 - LVDS */
 
-          if(((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
-              (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) ||
-             ((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
-              (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050))) {
+          tempbl = 0;
+          if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
+             (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
              tempah = infoflag >> 8;
+             if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+               tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
+             }
+          } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
+                    (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
+                     tempah = infoflag >> 8;
+             tempbl = 0x03;
           } else {
               tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
+             tempbl = (tempah >> 6) & 0x03;
+             tempbl |= 0x08;
+             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
           }
           tempah &= 0xC0;
-
            tempah |= 0x20;
            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+          if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+             if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+                SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
+             }
+          }
 
-        } else {                                                       /* 315 - 301, 301B */
+        } else {                                                       /* 315 - TMDS */
 
-           tempah = infoflag >> 8;
+           tempah = tempbl = infoflag >> 8;
           if(!SiS_Pr->UseCustomMode) {
-             if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+             tempbl = 0;
+             if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+                if(ModeNo <= 0x13) {
+                   tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
+                }
+             }
+             if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
                 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
                    tempah = SiS_Pr->SiS_LCDInfo;
+                   tempbl = (tempah >> 6) & 0x03;
                 }
              }
           }
           tempah &= 0xC0;
-
            tempah |= 0x20;
            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-
-          if(SiS_Pr->SiS_VBType & VB_NoLCD) {                  /* TEST, imitate BIOS bug */
-             if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-                tempah |= 0xc0;
+          if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+             /* Imitate BIOS bug */
+             if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
+          }
+          if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+             tempah >>= 3;
+             tempah &= 0x18;
+             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
+          } else {
+              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+             if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+                if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+                   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
+                }
              }
           }
-           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
 
         }
 #endif  /* SIS315H */
@@ -5023,7 +4826,7 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex
    }
 }
 
-/******** Set CRT2 FIFO on 300/630/730 *******/
+/* Set CRT2 FIFO on 300/630/730 */
 #ifdef SIS300
 static void
 SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
@@ -5078,7 +4881,7 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
 
   if(!SiS_Pr->CRT1UsesCustomMode) {
 
-     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                        /* get CRT1 ModeNo */
+     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
      SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
      SiS_Pr->SiS_SelectCRT2Rate = 0;
@@ -5087,7 +4890,7 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
      if(CRT1ModeNo >= 0x13) {
         index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
         index &= 0x3F;
-        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                              /* Get VCLK */
+        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                      /* Get VCLK */
 
        colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex);     /* Get colordepth */
         colorth >>= 1;
@@ -5097,9 +4900,9 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
   } else {
 
      CRT1ModeNo = 0xfe;
-     VCLK = SiS_Pr->CSRClock_CRT1;                                             /* Get VCLK */
+     VCLK = SiS_Pr->CSRClock_CRT1;                                     /* Get VCLK */
      data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
-     switch(data2) {                                                           /* Get color depth */
+     switch(data2) {                                                   /* Get color depth */
         case 0 : colorth = 1; break;
         case 1 : colorth = 1; break;
         case 2 : colorth = 2; break;
@@ -5246,10 +5049,10 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
 
        index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
                                refreshratetableindex,HwInfo);
-       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                               /* Get VCLK  */
+       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                /* Get VCLK  */
 
        if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-          if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+          if(SiS_Pr->SiS_UseROM) {
             if(ROMAddr[0x220] & 0x01) {
                 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
             }
@@ -5259,11 +5062,11 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
     } else {
 
        CRT2ModeNo = 0xfe;
-       VCLK = SiS_Pr->CSRClock;                                                        /* Get VCLK */
+       VCLK = SiS_Pr->CSRClock;                                        /* Get VCLK */
 
     }
 
-    colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex);        /* Get colordepth */
+    colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */
     colorth >>= 1;
     if(!colorth) colorth++;
 
@@ -5282,8 +5085,8 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
     if(HwInfo->jChipType == SIS_300) {
        if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
        else             temp = (temp & (~0x1F)) | 0x16;
-       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-                       temp = (temp & (~0x1F)) | 0x13;
+       if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
+                 temp = (temp & (~0x1F)) | 0x13;
        }
     } else {
        if( ( (HwInfo->jChipType == SIS_630) ||
@@ -5313,350 +5116,105 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
 }
 #endif
 
-/**** Set CRT2 FIFO on 315/330 series ****/
+/* Set CRT2 FIFO on 315/330 series */
 #ifdef SIS315H
 static void
-SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr)
+SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,0x04);
+  if( (HwInfo->jChipType == SIS_760)      &&
+      (SiS_Pr->SiS_SysFlags & SF_760LFB)  &&
+      (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
+      (SiS_Pr->SiS_VGAHDE >= 1280)       &&
+      (SiS_Pr->SiS_VGAVDE >= 1024) ) {
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
+  } else {
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
+  }
+
 }
 #endif
 
-/*************** Set LCD-A ***************/
-#ifdef SIS315H
-static void
-SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                   PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+static USHORT
+SiS_GetVGAHT2(SiS_Private *SiS_Pr)
 {
-  USHORT modeflag,resinfo;
-  USHORT push2,tempax,tempbx,tempcx,temp;
-  ULONG tempeax=0,tempebx,tempecx,tempvcfact;
+  ULONG tempax,tempbx;
 
-  /* This is not supported with LCDA */
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
-  if(SiS_Pr->UseCustomMode) return;
+  tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
+  tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
+  tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
+  return((USHORT)tempax);
+}
 
-  if(IS_SIS330) {
-     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);                    /* Xabre 1.01.03 */
-  } else if(IS_SIS740) {
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {                                        /* 740/LVDS */
-        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);         /* 740/LVDS */
-       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
-     } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
-        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);                 /* 740/301LV, 301BDH */
-     }
-  } else {
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {                                        /* 650/LVDS */
-        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);         /* 650/LVDS */
-       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);                  /* 650/LVDS 1.10.07 */
-     } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
-        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);                        /* 650/30xLv 1.10.6s */
-     }
-  }
+/* Set Part 1 / SiS bridge slave mode */
+static void
+SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
+                  PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
+{
+  USHORT  push1,push2;
+  USHORT  tempax,tempbx,tempcx,temp;
+  USHORT  resinfo,modeflag,xres=0;
+  unsigned char p1_7, p1_8;
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
+     resinfo = 0;
+     xres = SiS_Pr->CHDisplay;
   } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
   }
 
-  tempax = SiS_Pr->SiS_LCDHDES;
-
-  temp = (tempax & 0x0007);                                    /* BPLHDESKEW[2:0]   */
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                         /* Part1_1Ah  */
-  temp = (tempax >> 3) & 0x00FF;                                       /* BPLHDESKEW[10:3]  */
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                         /* Part1_16h  */
+  /* The following is only done if bridge is in slave mode: */
 
-  tempbx = SiS_Pr->SiS_HDE;
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-     tempbx = SiS_Pr->PanelXRes;
+  if((HwInfo->jChipType >= SIS_661) && (ModeNo > 0x13)) {
+     if(xres >= 1600) {
+        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
+     }
   }
 
-  tempax += tempbx;                                            /* HDE + HSKEW = lcdhdee  */
-  if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
-
-  temp = tempax;
-  if(SiS_Pr->SiS_VBType & VB_SISVB) {
-     if(temp & 0x07) temp += 8;
-  }
-  temp >>= 3;                                                  /* BPLHDEE  */
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);                         /* Part1_17h  */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff);                  /* set MAX HT */
 
-  tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;                             /* (HT-HDE) / 4  */
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)  modeflag |= Charx8Dot;
 
-  /* 650/30xLV 1.10.6s, 740/LVDS */
-  if( ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
-      ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
-     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x28;
-       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempcx = 0x18;
-       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x30;
-       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x40;
-       else                                                          tempcx = 0x30;
-     }
-  }
+  if(modeflag & Charx8Dot) tempcx = 0x08;
+  else                     tempcx = 0x09;
 
-  tempcx += tempax;                                            /* lcdhrs  */
-  if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
+  tempax = SiS_Pr->SiS_VGAHDE;                                         /* 0x04 Horizontal Display End */
+  if(modeflag & HalfDCLK) tempax >>= 1;
+  tempax = ((tempax / tempcx) - 1) & 0xff;
+  tempbx = tempax;
 
-  temp = (tempcx >> 3) & 0x00FF;                               /* BPLHRS */
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);                                 /* Part1_14h  */
+  temp = tempax;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
 
-  temp += 10;
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-          temp += 6;
-          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
-             temp++;
-             if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
-                temp += 7;
-                if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
-                   temp -= 10;
-                }
-             }
-          }
-       }
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+        temp += 2;
      }
   }
-  temp &= 0x1F;
-  temp |= ((tempcx & 0x07) << 5);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);                         /* Part1_15h  */
-
-  if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
-     tempax = SiS_Pr->PanelYRes;
-  } else {
-     tempax = SiS_Pr->SiS_VGAVDE;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+     if(resinfo == SIS_RI_800x600) temp -= 2;
   }
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
 
-  tempbx = SiS_Pr->SiS_LCDVDES + tempax;
-  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
-  push2 = tempbx;
-
-  tempcx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 2;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
 
-  if( ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
-      ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
-     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 1;
-       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)   tempcx = 3;
-       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 3;
-       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 1;
-       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 1;
-       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 1;
-       else                                                           tempcx = 0x0057;
-     }
-  }
-
-  tempbx += tempcx;
-  if(SiS_Pr->SiS_VBType & VB_SISVB) {
-     tempbx++;                                                 /* BPLVRS  */
-  }
-  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
-  temp = tempbx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);                             /* Part1_18h  */
-
-  tempcx >>= 3;
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-          if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 3;
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)   tempcx = 5;
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 5;
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 5;
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 2;
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 2;
-       }
-     }
-  }
-  tempcx += tempbx;
-  tempcx++;                                                    /* BPLVRE  */
-  temp = tempcx & 0x000F;
-  if(SiS_Pr->SiS_VBType & VB_SISVB) {
-     temp |= 0xC0;
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);            /* Part1_19h  */
-  } else {
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);
-  }
-
-  temp = ((tempbx >> 8) & 0x07) << 3;
-  if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
-  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)   temp |= 0x40;
-  if(SiS_Pr->SiS_VBType & VB_SISVB) {
-     /* Don't check Part1Port,0x00 -> is not being set if LCDA! */
-     /* We check SR06 instead here: */
-     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-        if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
-     }
-  } else {
-     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-        if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
-     }
-  }
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x07,temp);            /* Part1_1Ah */
-
-  tempbx = push2;                                                      /* BPLVDEE */
-
-  tempcx = SiS_Pr->SiS_LCDVDES;                                        /* NPLVDES */
-  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-        if(resinfo == SIS_RI_800x600) tempcx++;
-     }
-  }
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-     tempbx = tempcx = SiS_Pr->SiS_VGAVDE;
-     tempbx--;
-  }
-
-  temp = ((tempbx >> 8) & 0x07) << 3;
-  temp = temp | ((tempcx >> 8) & 0x07);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);                          /* Part1_1Dh */
-  temp = tempbx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,temp);                          /* Part1_1Ch  */
-  temp = tempcx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,temp);                          /* Part1_1Bh  */
-
-  tempeax = SiS_Pr->SiS_VGAVDE << 18;
-  tempebx = SiS_Pr->SiS_VDE;
-  temp = (USHORT)(tempeax % tempebx);
-  tempeax = tempeax / tempebx;
-  if(temp) tempeax++;
-  tempvcfact = tempeax;
-
-  temp = (USHORT)(tempeax & 0x00FF);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
-
-  temp = (USHORT)((tempeax & 0x00FF00) >> 8);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
-
-  temp = (USHORT)((tempeax & 0x00030000) >> 16);
-  if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
-
-  if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
-     temp = (USHORT)(tempeax & 0x00FF);
-     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
-     temp = (USHORT)((tempeax & 0x00FF00) >> 8);
-     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
-     temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
-     temp = 0;
-     if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
-  }
-
-  tempeax = SiS_Pr->SiS_VGAHDE << 16;
-  tempebx = SiS_Pr->SiS_HDE;
-  temp = tempeax % tempebx;
-  tempeax /= tempebx;
-  if(temp) tempeax++;
-  if(tempebx == SiS_Pr->SiS_VGAHDE) tempeax = 0xFFFF;
-  tempecx = tempeax;
-  tempeax = ((SiS_Pr->SiS_VGAHDE << 16) / tempecx) - 1;
-  tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
-  temp = (USHORT)(tempecx & 0x00FF);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);                          /* Part1_1Fh  */
-
-  tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
-  tempbx = (USHORT)(tempeax & 0x0FFFF);
-
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
-
-  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)  tempbx = 1;
-
-  temp = ((tempbx >> 8) & 0x07) << 3;
-  temp = temp | ((tempecx >> 8) & 0x07);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);                         /* Part1_20h */
-
-  temp = tempbx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,temp);                         /* Part1_21h */
-
-  tempecx >>= 16;                                              /* BPLHCFACT  */
-  if(modeflag & HalfDCLK) tempecx >>= 1;
-  temp = (USHORT)((tempecx & 0x0000FF00) >> 8);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);                         /* Part1_22h */
-
-  temp = (USHORT)(tempecx & 0x000000FF);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
-
-  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
-     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
-  }
-}
-#endif  /* SIS 315 */
-
-static USHORT
-SiS_GetVGAHT2(SiS_Private *SiS_Pr)
-{
-  ULONG tempax,tempbx;
-
-  tempbx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX) & 0xFFFF;
-  tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
-  tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
-  return((USHORT) tempax);
-}
-
-/******* Set Part 1 / SiS bridge *********/
-static void
-SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
-                  PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
-{
-  USHORT  push1,push2;
-  USHORT  tempax,tempbx,tempcx,temp;
-  USHORT  resinfo,modeflag;
-  unsigned char p1_7, p1_8;
-
-  if(ModeNo <= 0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-  } else {
-     if(SiS_Pr->UseCustomMode) {
-        modeflag = SiS_Pr->CModeFlag;
-       resinfo = 0;
-     } else {
-       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-     }
-  }
-
-  /* The following is only done if bridge is in slave mode: */
-
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff);                  /* set MAX HT */
-
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)  modeflag |= Charx8Dot;
-
-  if(modeflag & Charx8Dot) tempcx = 0x08;
-  else                     tempcx = 0x09;
-
-  tempax = SiS_Pr->SiS_VGAHDE;                                         /* 0x04 Horizontal Display End */
-  if(modeflag & HalfDCLK) tempax >>= 1;
-  tempax = ((tempax / tempcx) - 1) & 0xff;
-  tempbx = tempax;
-
-  temp = tempax;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
-
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-     if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
-        temp += 2;
-     }
-  }
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-     if(resinfo == SIS_RI_800x600) temp -= 2;
-  }
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
-
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
-
-  tempax = 0xFFFF;
-  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
-  if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
-  if(modeflag & HalfDCLK)         tempax >>= 1;
-  tempax = (tempax / tempcx) - 5;
-  tempcx = tempax;
+  tempax = 0xFFFF;
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
+  if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
+  if(modeflag & HalfDCLK)         tempax >>= 1;
+  tempax = (tempax / tempcx) - 5;
+  tempcx = tempax;
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
      temp = tempcx - 1;
@@ -5684,21 +5242,20 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
      } else {
         if(!(modeflag & HalfDCLK)) {
            temp -= 4;
-           if((SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) &&
-             (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200)) {
+           if((SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
+             (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)) {
               if(SiS_Pr->SiS_VGAHDE >= 800) {
                  temp -= 7;
                 if(HwInfo->jChipType < SIS_315H) {
-                   /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
                     if(SiS_Pr->SiS_ModeType == ModeEGA) {
                        if(SiS_Pr->SiS_VGAVDE == 1024) {
                           temp += 15;
-                          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
+                          if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024)
                             temp += 7;
                        }
                     }
                 }
-                if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+                if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
                     if(SiS_Pr->SiS_VGAHDE >= 1280) {
                        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
                    }
@@ -5762,6 +5319,10 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
              p1_7 = 0xab;
           }
        }
+     } else {
+        if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
+          if(modeflag & HalfDCLK) p1_7 = 0x30;
+       }
      }
   }
 
@@ -5784,7 +5345,7 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
   else if(tempbx == 525) tempbx = 480;
   push2 = tempbx;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
        if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
            if     (tempbx == 350) tempbx += 5;
            else if(tempbx == 480) tempbx += 5;
@@ -5830,7 +5391,7 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
        tempbx += (tempax << 1);
      }
   } else if(HwInfo->jChipType >= SIS_315H) {
-     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+     if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
        tempbx += (tempax << 1);
      }
   }
@@ -5907,521 +5468,465 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
      }
   }
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                 /* 0x1A SR0E */
+
+  temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
 }
 
-/*********** Set Part 1 / LVDS ***********/
+/* Setup panel link
+ * This is used for LVDS, LCDA and Chrontel TV output
+ * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
+ */
 static void
 SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                  PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+                   PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
 {
-  USHORT modeflag, resinfo;
-  USHORT push1, push2, tempax, tempbx, tempcx, temp;
+  USHORT modeflag,resinfo;
+  USHORT push2,tempax,tempbx,tempcx,temp;
+  ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
+  BOOLEAN islvds = FALSE, issis  = FALSE, chkdclkfirst = FALSE;
+#ifdef SIS300
+  USHORT crt2crtc;
+#endif
 #ifdef SIS315H
   USHORT pushcx;
 #endif
-  ULONG  tempeax=0, tempebx, tempecx, tempvcfact=0;
-
-  /* This is not supported on LVDS */
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
-  if(SiS_Pr->UseCustomMode) return;
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+#ifdef SIS300
+     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+#endif
+  } else if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
+     resinfo = 0;
+#ifdef SIS300
+     crt2crtc = 0;
+#endif
   } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+#ifdef SIS300
+     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+#endif
   }
 
-  /* Set up Panel Link */
-
-  /* 1. Horizontal setup */
-
-  tempax = SiS_Pr->SiS_LCDHDES;
-
-  if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
-     if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
-         (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
-          tempax -= 8;
-     }
+  /* is lvds if really LVDS, or SiS 301B-DH with external LVDS transmitter */
+  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
+     ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBType & VB_NoLCD))) {
+     islvds = TRUE;
   }
 
-  tempcx = SiS_Pr->SiS_HT;                               /* Horiz. Total */
-
-  tempbx = SiS_Pr->SiS_HDE;                               /* Horiz. Display End */
+  /* is really sis if sis bridge, but not 301B-DH */
+  if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+     issis = TRUE;
+  }
 
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-     SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
-     tempbx >>= 1;
+  if((HwInfo->jChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
+     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+        chkdclkfirst = TRUE;
+     }
   }
 
-  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
-          tempbx = SiS_Pr->PanelXRes;
-       } else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-          tempbx = SiS_Pr->PanelXRes;
-          if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
-             tempbx = 800;
-             if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
-                tempbx = 1024;
+#ifdef SIS315H
+  if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+     if(IS_SIS330) {
+        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
+     } else if(IS_SIS740) {
+        if(islvds) {
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
+          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
+        } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
+        }
+     } else {
+        if(islvds) {
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
+          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
+        } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
+          if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+             if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
+                (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
+                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
              }
           }
         }
      }
   }
-  tempcx = (tempcx - tempbx) >> 2;              /* HT-HDE / 4 */
-
-  push1 = tempax;
-
-  tempax += tempbx;
-
-  if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
+#endif
 
-  push2 = tempax;
+  /* Horizontal */
 
-  if((!SiS_Pr->SiS_IF_DEF_FSTN) &&
-     (!SiS_Pr->SiS_IF_DEF_DSTN) &&
-     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
-     (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
-     (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
-     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-             if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0028;
-             else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0018;
-             else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
-                   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
-                  if(HwInfo->jChipType < SIS_315H) {
-                     if(SiS_Pr->SiS_VBType & VB_SISVB) {
-                        tempcx = 0x0017;  /* A901; sometimes 0x0018; */
-                     } else {
-                        tempcx = 0x0017;
-#ifdef TWNEWPANEL
-                        tempcx = 0x0018;
-#endif
-                     }
-                  } else {
-                     tempcx = 0x0018;
-                  }
-             }
-             else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0028;
-             else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
-             else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
-             else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
+  tempax = SiS_Pr->SiS_LCDHDES;
+  if(islvds) {
+     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+        if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+           if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
+              (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
+             tempax -= 8;
           }
-        }
+       }
      }
   }
 
-  tempcx += tempax;                              /* lcdhrs  */
-  if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
-
-  tempax = tempcx >> 3;                          /* BPLHRS */
-  temp = tempax & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);          /* Part1_14h; Panel Link Horizontal Retrace Start  */
+  temp = (tempax & 0x0007);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                 /* BPLHDESKEW[2:0]   */
+  temp = (tempax >> 3) & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                 /* BPLHDESKEW[10:3]  */
 
-  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-     temp = (tempax & 0x00FF) + 2;
-  } else {
-     temp = (tempax & 0x00FF) + 10;
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if((!SiS_Pr->SiS_IF_DEF_DSTN) &&
-          (!SiS_Pr->SiS_IF_DEF_FSTN) &&
-          (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
-          (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
-          (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
-           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-             temp += 6;
-              if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
-                temp++;
-                if(HwInfo->jChipType >= SIS_315H) {
-                   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
-                      temp += 7;
-                      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
-                         temp -= 0x14;
-                         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x768) {
-                            temp -= 10;
-                         }
-                      }
-                   }
-                }
-             }
-           }
-        }
+  tempbx = SiS_Pr->SiS_HDE;
+  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+     if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
+        (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
+        tempbx >>= 1;
+     }
+     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+        tempbx = SiS_Pr->PanelXRes;
      }
   }
 
-  temp &= 0x1F;
-  temp |= ((tempcx & 0x0007) << 5);
-#if 0
-  if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;       /* WRONG? BIOS loads cl, not ah */
-#endif
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);          /* Part1_15h; Panel Link Horizontal Retrace End/Skew */
-
-  tempbx = push2;
-  tempcx = push1;                                /* lcdhdes  */
+  tempax += tempbx;
+  if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
 
-  temp = (tempcx & 0x0007);                      /* BPLHDESKEW  */
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);          /* Part1_1Ah; Panel Link Vertical Retrace Start (2:0) */
+  temp = tempax;
+  if(temp & 0x07) temp += 8;
+  temp >>= 3;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);                 /* BPLHDEE  */
 
-  tempcx >>= 3;                                  /* BPLHDES */
-  temp = (tempcx & 0x00FF);
-#if 0 /* Not 550 FSTN */
-  if(HwInfo->jChipType >= SIS_315H) {
-     if(ModeNo == 0x5b) temp--; */
-  }
-#endif
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);          /* Part1_16h; Panel Link Horizontal Display Enable Start  */
+  tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
 
-  if((HwInfo->jChipType < SIS_315H) ||
-     (SiS_Pr->SiS_IF_DEF_FSTN) ||
-     (SiS_Pr->SiS_IF_DEF_DSTN)) {
-     if(tempbx & 0x07) tempbx += 8;
-  }
-  tempbx >>= 3;                                  /* BPLHDEE  */
-  temp = tempbx & 0x00FF;
-#if 0 /* Not 550 FSTN */
-  if(HwInfo->jChipType >= SIS_315H) {
-     if(ModeNo == 0x5b) temp--;
+  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+        if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
+     }
   }
-#endif
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);          /* Part1_17h; Panel Link Horizontal Display Enable End  */
 
-  /* 2. Vertical setup */
+  tempcx += tempax;
+  if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
 
-  if(HwInfo->jChipType < SIS_315H) {
-     tempcx = SiS_Pr->SiS_VGAVT;
-     tempbx = SiS_Pr->SiS_VGAVDE;
-     if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) && (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
-        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-             tempbx = SiS_Pr->PanelYRes;
+  temp = (tempcx >> 3) & 0x00FF;
+  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+     if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
+        if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+           switch(ModeNo) {
+           case 0x04:
+           case 0x05:
+           case 0x0d: temp = 0x56; break;
+           case 0x10: temp = 0x60; break;
+           case 0x13: temp = 0x5f; break;
+           case 0x40:
+           case 0x41:
+           case 0x4f:
+           case 0x43:
+           case 0x44:
+           case 0x62:
+           case 0x56:
+           case 0x53:
+           case 0x5d:
+           case 0x5e: temp = 0x54; break;
            }
-       }
+        }
      }
-     tempcx -= tempbx;
+  }
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);                 /* BPLHRS */
 
+  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+     temp += 2;
+     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+        temp += 8;
+        if(SiS_Pr->PanelHRE != 999) {
+           temp = tempcx + SiS_Pr->PanelHRE;
+          if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
+          temp >>= 3;
+        }
+     }
   } else {
-
-     tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;           /* VGAVT-VGAVDE  */
-
+     temp += 10;
   }
 
-  tempbx = SiS_Pr->SiS_LCDVDES;                                        /* VGAVDES  */
-  push1 = tempbx;
+  temp &= 0x1F;
+  temp |= ((tempcx & 0x07) << 5);
+#if 0
+  if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;                     /* WRONG? BIOS loads cl, not ah */
+#endif
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);                 /* BPLHRE */
 
-  tempax = SiS_Pr->SiS_VGAVDE;
+  /* Vertical */
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-     if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-           tempax = 600;
-          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
-             tempax = 768;
-          }
-       }
-     } else if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0)   &&
-                (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
-                ((SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ||
-                (SiS_Pr->SiS_IF_DEF_FSTN) ||
-                (SiS_Pr->SiS_IF_DEF_DSTN)) ) {
+  tempax = SiS_Pr->SiS_VGAVDE;
+  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
        tempax = SiS_Pr->PanelYRes;
      }
   }
 
-  tempbx += tempax;
+  tempbx = SiS_Pr->SiS_LCDVDES + tempax;
   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
 
   push2 = tempbx;
 
-  tempcx >>= 1;
-
-  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
-     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) &&
-     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
-     (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
-     (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
-       tempcx = 0x0017;
-     } else if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-        if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
-          if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 0x0003;
-          else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
-                  (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)) tempcx = 0x0003;
-           else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0001;
-           else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0001;
-          else                                                           tempcx = 0x0057;
-        } else  {
-          if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 0x0001;
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0001;
-          else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
-                  (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)) {
-                  if(HwInfo->jChipType < SIS_315H) {
-                     if(SiS_Pr->SiS_VBType & VB_SISVB) {
-                        tempcx = 0x0002;   /* A901; sometimes 0x0003; */
-                     } else {
-                        tempcx = 0x0002;
-#ifdef TWNEWPANEL
-                        tempcx = 0x0003;
-#endif
-                     }
-                  } else tempcx = 0x0003;
-           }
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0003;
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0001;
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0001;
-          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0001;
-          else                                                          tempcx = 0x0057;
+  tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
+  if(HwInfo->jChipType < SIS_315H) {
+     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+        if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+          tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
        }
      }
   }
+  if(islvds) tempcx >>= 1;
+  else       tempcx >>= 2;
 
-  tempbx += tempcx;                            /* BPLVRS  */
-
-  if((HwInfo->jChipType < SIS_315H) ||
-     (SiS_Pr->SiS_IF_DEF_FSTN) ||
-     (SiS_Pr->SiS_IF_DEF_DSTN)) {
-     tempbx++;
+  if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
+      (!(SiS_Pr->SiS_LCDInfo & LCDPass11))                 &&
+      (SiS_Pr->PanelVRS != 999) ) {
+     tempcx = SiS_Pr->PanelVRS;
+     tempbx += tempcx;
+     if(issis) tempbx++;
+  } else {
+     tempbx += tempcx;
+     if(HwInfo->jChipType < SIS_315H) tempbx++;
+     else if(issis)                   tempbx++;
   }
 
-  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
+  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;       /* BPLVRS  */
 
   temp = tempbx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);          /* Part1_18h; Panel Link Vertical Retrace Start  */
+  if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+        if(ModeNo == 0x10) temp = 0xa9;
+     }
+  }
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
 
   tempcx >>= 3;
+  tempcx++;
 
-  if((!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
-     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
-     (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
-     (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if( (HwInfo->jChipType < SIS_315H) &&
-            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) )     tempcx = 0x0001;
-       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2)  tempcx = 0x0002;
-       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)  tempcx = 0x0002;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)    tempcx = 0x0003;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0005;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)   tempcx = 0x0005;
-       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 0x0011;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0005;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0002;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 0x0011;
-        else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
-               if(HwInfo->jChipType < SIS_315H) {
-                  if(SiS_Pr->SiS_VBType & VB_SISVB) {
-                     tempcx = 0x0004;   /* A901; Other BIOS sets 0x0005; */
-                  } else {
-                     tempcx = 0x0004;
-#ifdef TWNEWPANEL
-                     tempcx = 0x0005;
-#endif
-                  }
-               } else {
-                  tempcx = 0x0005;
-               }
-        }
+  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+        if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
      }
   }
 
-  tempcx = tempcx + tempbx + 1;                  /* BPLVRE  */
+  tempcx += tempbx;
   temp = tempcx & 0x000F;
-  if(SiS_Pr->SiS_IF_DEF_FSTN ||
-     SiS_Pr->SiS_IF_DEF_DSTN ||
-     (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
-     (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
-     (SiS_Pr->SiS_CustomT == CUT_PANEL848)) {
-     temp |= 0x30;
-  }
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; Panel Link Vertical Retrace End (3:0); Misc.  */
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);       /* BPLVRE  */
 
-  temp = ((tempbx & 0x0700) >> 8) << 3;          /* BPLDESKEW =0 */
+  temp = ((tempbx >> 8) & 0x07) << 3;
   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
      if(SiS_Pr->SiS_HDE != 640) {
-        if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)   temp |= 0x40;
+        if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
+     }
+  } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)          temp |= 0x40;
+  tempbx = 0x87;
+  if((HwInfo->jChipType >= SIS_315H) ||
+     (HwInfo->jChipRevision >= 0x30)) {
+     tempbx = 0x07;
+     if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+       if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03)    temp |= 0x80;
+     }
+     /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit mutliplexed) via VGA2 */
+     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+          if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10)      temp |= 0x80;
+       } else {
+          if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
+       }
      }
-  } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
-  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)           temp |= 0x40;
-  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-     if(HwInfo->jChipType >= SIS_315H) {
-        if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
-           temp |= 0x80;
+  }
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
+
+  tempbx = push2;                                                      /* BPLVDEE */
+
+  tempcx = SiS_Pr->SiS_LCDVDES;                                        /* BPLVDES */
+
+  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+     switch(SiS_Pr->SiS_LCDResInfo) {
+     case Panel_640x480:
+        tempbx = SiS_Pr->SiS_VGAVDE - 1;
+        tempcx = SiS_Pr->SiS_VGAVDE;
+       break;
+     case Panel_800x600:
+        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+           if(resinfo == SIS_RI_800x600) tempcx++;
         }
-     } else {
-       if( (HwInfo->jChipType == SIS_630) ||
-           (HwInfo->jChipType == SIS_730) ) {
-          if(HwInfo->jChipRevision >= 0x30) {
-             temp |= 0x80;
+       break;
+     case Panel_1024x600:
+        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+           if(resinfo == SIS_RI_1024x600) tempcx++;
+           if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+             if(resinfo == SIS_RI_800x600) tempcx++;
           }
-       }
+        }
+       break;
+     case Panel_1024x768:
+        if(HwInfo->jChipType < SIS_315H) {
+           if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+              if(resinfo == SIS_RI_1024x768) tempcx++;
+          }
+        }
+       break;
      }
   }
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
 
-  if (HwInfo->jChipType < SIS_315H) {
+  temp = ((tempbx >> 8) & 0x07) << 3;
+  temp = temp | ((tempcx >> 8) & 0x07);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
+  /* if(SiS_Pr->SiS_IF_DEF_FSTN) tempbx++;  */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
 
-#ifdef SIS300      /* 300 series */
+  /* Vertical scaling */
 
-        tempeax = SiS_Pr->SiS_VGAVDE << 6;
-        temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
-        tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
-        if(temp != 0) tempeax++;
-        tempebx = tempeax;                         /* BPLVCFACT  */
+  if(HwInfo->jChipType < SIS_315H) {
 
-       if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
-          tempebx = 0x003F;
-       }
+#ifdef SIS300      /* 300 series */
+     tempeax = SiS_Pr->SiS_VGAVDE << 6;
+     temp = (tempeax % (ULONG)SiS_Pr->SiS_VDE);
+     tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
+     if(temp) tempeax++;
 
-       temp = (USHORT)(tempebx & 0x00FF);
-       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; Panel Link Vertical Scaling Factor */
+     if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
 
+     temp = (USHORT)(tempeax & 0x00FF);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);              /* BPLVCFACT */
+     tempvcfact = temp;
 #endif /* SIS300 */
 
   } else {
 
 #ifdef SIS315H  /* 315 series */
+     tempeax = SiS_Pr->SiS_VGAVDE << 18;
+     tempebx = SiS_Pr->SiS_VDE;
+     temp = (tempeax % tempebx);
+     tempeax = tempeax / tempebx;
+     if(temp) tempeax++;
+     tempvcfact = tempeax;
 
-        if(HwInfo->jChipType == SIS_740) {
-           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
-        } else {
-          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,0x23);
-       }
-
-       tempeax = SiS_Pr->SiS_VGAVDE << 18;
-       temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
-       tempeax = tempeax / SiS_Pr->SiS_VDE;
-       if(temp != 0) tempeax++;
-       tempebx = tempeax;                         /* BPLVCFACT  */
-        tempvcfact = tempeax;
-       temp = (USHORT)(tempebx & 0x00FF);
-       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);      /* Part1_37h; Panel Link Vertical Scaling Factor */
-       temp = (USHORT)((tempebx & 0x00FF00) >> 8);
-       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);      /* Part1_36h; Panel Link Vertical Scaling Factor */
-       temp = (USHORT)((tempebx & 0x00030000) >> 16);
-       temp &= 0x03;
-       if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
-       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);      /* Part1_35h; Panel Link Vertical Scaling Factor */
-
-#endif /* SIS315H */
-
-  }
-
-  tempbx = push2;                                  /* BPLVDEE  */
-  tempcx = push1;
-
-  push1 = temp;
-
-  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-       if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
-               if(HwInfo->jChipType < SIS_315H) {
-                       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-                               if(resinfo == SIS_RI_1024x600) tempcx++;
-                               if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-                                       if(resinfo == SIS_RI_800x600) tempcx++;
-                               }
-                       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-                               if(resinfo == SIS_RI_800x600)  tempcx++;
-                               if(resinfo == SIS_RI_1024x768) tempcx++; /* Doesnt make sense anyway... */
-                       } else  if(resinfo == SIS_RI_1024x768) tempcx++;
-               } else {
-                       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-                               if(resinfo == SIS_RI_800x600)  tempcx++;
-                       }
-               }
-       }
-  }
+     temp = (USHORT)(tempeax & 0x00FF);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
+     temp = (USHORT)((tempeax & 0x00FF00) >> 8);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
+     temp = (USHORT)((tempeax & 0x00030000) >> 16);
+     if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
 
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
-        tempcx = SiS_Pr->SiS_VGAVDE;
-        tempbx = SiS_Pr->SiS_VGAVDE - 1;
+     if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
+        temp = (USHORT)(tempeax & 0x00FF);
+        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
+        temp = (USHORT)((tempeax & 0x00FF00) >> 8);
+        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
+        temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
+        temp = 0;
+        if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
      }
-  }
-
-  temp = ((tempbx & 0x0700) >> 8) << 3;
-  temp |= ((tempcx & 0x0700) >> 8);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);         /* Part1_1Dh; Vertical Display Overflow; Control Signal */
-
-  temp = tempbx & 0x00FF;
-  /* if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;  */
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,temp);         /* Part1_1Ch; Panel Link Vertical Display Enable End  */
+#endif
 
-  temp = tempcx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,temp);         /* Part1_1Bh; Panel Link Vertical Display Enable Start  */
+  }
 
-  /* 3. Additional horizontal setup (scaling, etc) */
+  /* Horizontal scaling */
 
-  tempecx = SiS_Pr->SiS_VGAHDE;
-  if(HwInfo->jChipType >= SIS_315H) {
-     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
-        if(modeflag & HalfDCLK) tempecx >>= 1;
-     }
+  tempeax = SiS_Pr->SiS_VGAHDE;                /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
+  if(chkdclkfirst) {
+     if(modeflag & HalfDCLK) tempeax >>= 1;
   }
-  tempebx = SiS_Pr->SiS_HDE;
-  if(tempecx == tempebx) tempeax = 0xFFFF;
-  else {
-     tempeax = tempecx;
-     tempeax <<= 16;
-     temp = (USHORT)(tempeax % tempebx);
-     tempeax = tempeax / tempebx;
+  tempebx = tempeax << 16;
+  if(SiS_Pr->SiS_HDE == tempeax) {
+     tempecx = 0xFFFF;
+  } else {
+     tempecx = tempebx / SiS_Pr->SiS_HDE;
      if(HwInfo->jChipType >= SIS_315H) {
-        if(temp) tempeax++;
+        if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
      }
   }
-  tempecx = tempeax;
 
   if(HwInfo->jChipType >= SIS_315H) {
-     tempeax = SiS_Pr->SiS_VGAHDE;
-     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
-        if(modeflag & HalfDCLK) tempeax >>= 1;
-     }
-     tempeax <<= 16;
-     tempeax = (tempeax / tempecx) - 1;
+     tempeax = (tempebx / tempecx) - 1;
   } else {
      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
   }
-  tempecx <<= 16;
-  tempecx |= (tempeax & 0xFFFF);
+  tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
   temp = (USHORT)(tempecx & 0x00FF);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);          /* Part1_1Fh; Panel Link DDA Operational Number in each horiz. line */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
 
-  tempbx = SiS_Pr->SiS_VDE;
   if(HwInfo->jChipType >= SIS_315H) {
      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
-     tempbx = (USHORT)(tempeax & 0x0FFFF);
+     tempbx = (USHORT)(tempeax & 0xFFFF);
   } else {
      tempeax = SiS_Pr->SiS_VGAVDE << 6;
-     tempbx = push1 & 0x3f;
+     tempbx = tempvcfact & 0x3f;
      if(tempbx == 0) tempbx = 64;
      tempeax /= tempbx;
-     tempbx = (USHORT)(tempeax & 0x0FFFF);
+     tempbx = (USHORT)(tempeax & 0xFFFF);
   }
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
+  if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
-     else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  tempbx = 1;
+     else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480)             tempbx = 1;
   }
 
-  temp = ((tempbx & 0xFF00) >> 8) << 3;
-  temp |= (USHORT)((tempecx & 0x0700) >> 8);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);         /* Part1_20h; Overflow register */
-
-  temp = tempbx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,temp);         /* Part1_21h; Panel Link Vertical Accumulator Register */
+  temp = ((tempbx >> 8) & 0x07) << 3;
+  temp = temp | ((tempecx >> 8) & 0x07);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
 
-  tempecx >>= 16;                               /* BPLHCFACT  */
-  if((HwInfo->jChipType < SIS_315H) || (SiS_Pr->SiS_IF_DEF_FSTN) || (SiS_Pr->SiS_IF_DEF_DSTN)) {
+  tempecx >>= 16;                                              /* BPLHCFACT  */
+  if(!chkdclkfirst) {
      if(modeflag & HalfDCLK) tempecx >>= 1;
   }
   temp = (USHORT)((tempecx & 0xFF00) >> 8);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);         /* Part1_22h; Panel Link Horizontal Scaling Factor High */
-
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
   temp = (USHORT)(tempecx & 0x00FF);
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; Panel Link Horizontal Scaling Factor Low */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
+
+#ifdef SIS315H
+  if(HwInfo->jChipType >= SIS_315H) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+        if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
+           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+       }
+     } else {
+        if(islvds) {
+           if(HwInfo->jChipType == SIS_740) {
+              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
+           } else {
+             SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
+           }
+        }
+     }
+  }
+#endif
 
-  /* 630/301B and 630/LVDS do something for 640x480 panels here */
+#ifdef SIS300
+  if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
+     int i;
+     UCHAR TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };
+     UCHAR TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
+     UCHAR TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
+
+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
+     for(i=0; i<5; i++) {
+        SiS_SetTrumpionBlock(SiS_Pr, &SiS300_TrumpionData[crt2crtc][0]);
+     }
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+        if(ModeNo == 0x13) {
+          for(i=0; i<4; i++) {
+             SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
+          }
+       } else if(ModeNo == 0x10) {
+          for(i=0; i<4; i++) {
+             SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
+             SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
+          }
+       }
+     }
+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
+  }
+#endif
 
 #ifdef SIS315H
   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
@@ -6431,10 +5936,10 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
      tempax = SiS_Pr->SiS_HDE;                                 /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+     if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
      tempax += 64;
      temp = tempax & 0x00FF;
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
@@ -6448,8 +5953,8 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
 
      tempax = SiS_Pr->SiS_VDE;
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+     if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
      tempax >>= 1;
      temp = tempax & 0x00FF;
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
@@ -6457,8 +5962,8 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
 
      tempeax = SiS_Pr->SiS_HDE;
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempeax >>= 1;
+     if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempeax >>= 1;
      tempeax <<= 2;                                            /* BDxFIFOSTOP = (HDE*4)/128 */
      tempebx = 128;
      temp = (USHORT)(tempeax % tempebx);
@@ -6472,8 +5977,8 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
 
      tempax = SiS_Pr->SiS_HDE;
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+     if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
      tempax >>= 4;                                             /* BDxWadroff = HDE*4/8/8 */
      pushcx = tempax;
      temp = tempax & 0x00FF;
@@ -6482,8 +5987,8 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
 
      tempax = SiS_Pr->SiS_VDE;                                 /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+     if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
      tempeax = (tempax * pushcx);
      tempebx = 0x00100000 + tempeax;
      temp = (USHORT)tempebx & 0x000000FF;
@@ -6525,496 +6030,380 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      }
   }
 #endif  /* SIS315H */
-
 }
 
-/************** Set Part 1 ***************/
+/* Set Part 1 */
 static void
 SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
               PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
 {
-  UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
-  USHORT  temp=0, tempax=0, tempbx=0, tempcx=0;
-  USHORT  pushbx=0, CRT1Index=0;
+#if defined(SIS300) || defined(SIS315H)
+  UCHAR   *ROMAddr = HwInfo->pjVirtualRomBase;
+#endif
+  USHORT  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
+  USHORT  pushbx=0, CRT1Index=0, modeflag, resinfo=0;
 #ifdef SIS315H
   USHORT  tempbl=0;
 #endif
-  USHORT  modeflag, resinfo=0;
+
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+     SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+     return;
+  }
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
   } else {
-     if(SiS_Pr->UseCustomMode) {
-       modeflag = SiS_Pr->CModeFlag;
-     } else {
-       CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     }
+     CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-
-#ifdef SIS315H
-     SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
-     SiS_SetGroup1_LCDA(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
-#endif
-
-  } else {
+  SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
 
-     if( (HwInfo->jChipType >= SIS_315H) &&
+  if( ! ((HwInfo->jChipType >= SIS_315H) &&
          (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
-        (SiS_Pr->SiS_VBInfo & SetInSlaveMode) ) {
-
-        SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+         (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
 
-     } else {
-
-        SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex,
-                         RefreshRateTableIndex, HwInfo);
-
-        if (HwInfo->jChipType < SIS_315H ) {
+     if(HwInfo->jChipType < SIS_315H ) {
 #ifdef SIS300
-             SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
+       SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
 #endif
-        } else {
+     } else {
 #ifdef SIS315H
-              SiS_SetCRT2FIFO_310(SiS_Pr);
+        SiS_SetCRT2FIFO_310(SiS_Pr, HwInfo);
 #endif
-       }
-
-        SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+     }
 
-       /* 1. Horizontal setup */
+     /* 1. Horizontal setup */
 
-        if(HwInfo->jChipType < SIS_315H ) {
+     if(HwInfo->jChipType < SIS_315H ) {
 
 #ifdef SIS300   /* ------------- 300 series --------------*/
 
-               temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;                         /* BTVGA2HT 0x08,0x09 */
-               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);                   /* CRT2 Horizontal Total */
-
-               temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
-               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);          /* CRT2 Horizontal Total Overflow [7:4] */
+       temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;                   /* BTVGA2HT 0x08,0x09 */
+       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
 
-               temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                       /* BTVGA2HDEE 0x0A,0x0C */
-               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);                   /* CRT2 Horizontal Display Enable End */
+       temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
 
-               pushbx = SiS_Pr->SiS_VGAHDE + 12;                               /* bx  BTVGA@HRS 0x0B,0x0C */
-               tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
-               tempbx = pushbx + tempcx;
-               tempcx <<= 1;
-               tempcx += tempbx;
+       temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */
+       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */
 
-               if(SiS_Pr->SiS_VBType & VB_SISVB) {
-
-                  if(SiS_Pr->UseCustomMode) {
-                     tempbx = SiS_Pr->CHSyncStart + 12;
-                     tempcx = SiS_Pr->CHSyncEnd + 12;
-                  }
+       pushbx = SiS_Pr->SiS_VGAHDE + 12;                         /* bx  BTVGA2HRS 0x0B,0x0C */
+       tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
+       tempbx = pushbx + tempcx;
+       tempcx <<= 1;
+       tempcx += tempbx;
 
-                  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
-                     unsigned char cr4, cr14, cr5, cr15;
-                     if(SiS_Pr->UseCustomMode) {
-                        cr4  = SiS_Pr->CCRT1CRTC[4];
-                        cr14 = SiS_Pr->CCRT1CRTC[14];
-                        cr5  = SiS_Pr->CCRT1CRTC[5];
-                        cr15 = SiS_Pr->CCRT1CRTC[15];
-                     } else {
-                        cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
-                        cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
-                        cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
-                        cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
-                     }
-                     tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 1) << 3;
-                     tempcx = (((cr5 & 0x1F) | ((cr15 & 0x04) << (6-2))) - 1) << 3;
-                  }
-
-                  if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
-                     if(!(SiS_Pr->SiS_TVMode & TVSetPAL)){
-                        tempbx = 1040;
-                        tempcx = 1042;
-                     }
-                  }
-               }
+       bridgeadd = 12;
 
-               temp = tempbx & 0x00FF;
-               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* CRT2 Horizontal Retrace Start */
 #endif /* SIS300 */
 
-       } else {
+     } else {
 
 #ifdef SIS315H  /* ------------------- 315/330 series --------------- */
 
-               tempcx = SiS_Pr->SiS_VGAHT;                                    /* BTVGA2HT 0x08,0x09 */
-               if(modeflag & HalfDCLK) {
-                   if(SiS_Pr->SiS_VBType & VB_SISVB) {
-                      tempcx >>= 1;
-                   } else {
-                      tempax = SiS_Pr->SiS_VGAHDE >> 1;
-                      tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
-                      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-                         tempcx = SiS_Pr->SiS_HT - tempax;
-                      }
-                   }
-               }
-               tempcx--;
+       tempcx = SiS_Pr->SiS_VGAHT;                               /* BTVGA2HT 0x08,0x09 */
+       if(modeflag & HalfDCLK) {
+          if(SiS_Pr->SiS_VBType & VB_SISVB) {
+             tempcx >>= 1;
+          } else {
+             tempax = SiS_Pr->SiS_VGAHDE >> 1;
+             tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
+             if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+                tempcx = SiS_Pr->SiS_HT - tempax;
+             }
+          }
+       }
+       tempcx--;
+       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx);            /* CRT2 Horizontal Total */
+       temp = (tempcx >> 4) & 0xF0;
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
+
+       tempcx = SiS_Pr->SiS_VGAHT;                               /* BTVGA2HDEE 0x0A,0x0C */
+       tempbx = SiS_Pr->SiS_VGAHDE;
+       tempcx -= tempbx;
+       tempcx >>= 2;
+       if(modeflag & HalfDCLK) {
+          tempbx >>= 1;
+          tempcx >>= 1;
+       }
+       tempbx += 16;
 
-               temp = tempcx & 0xff;
-               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* CRT2 Horizontal Total */
+       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx);            /* CRT2 Horizontal Display Enable End */
 
-               temp = ((tempcx & 0xff00) >> 8) << 4;
-               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* CRT2 Horizontal Total Overflow [7:4] */
+       pushbx = tempbx;
+       tempcx >>= 1;
+       tempbx += tempcx;
+       tempcx += tempbx;
 
-               tempcx = SiS_Pr->SiS_VGAHT;                                    /* BTVGA2HDEE 0x0A,0x0C */
-               tempbx = SiS_Pr->SiS_VGAHDE;
-               tempcx -= tempbx;
-               tempcx >>= 2;
-               if(modeflag & HalfDCLK) {
-                  tempbx >>= 1;
-                  tempcx >>= 1;
-               }
-               tempbx += 16;
-
-               temp = tempbx & 0xff;
-               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* CRT2 Horizontal Display Enable End */
-
-               pushbx = tempbx;
-               tempcx >>= 1;
-               tempbx += tempcx;
-               tempcx += tempbx;
-
-               if(SiS_Pr->SiS_VBType & VB_SISVB) {
-
-                  if(HwInfo->jChipType >= SIS_661) {
-                     if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ||
-                        (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) {
-                        if(resinfo == SIS_RI_1280x1024) {
-                           tempcx = 0x30;
-                        } else if(resinfo == SIS_RI_1600x1200) {
-                           tempcx = 0xff;
-                        }
-                     }
-                  }
+       bridgeadd = 16;
 
-                  if(SiS_Pr->UseCustomMode) {
-                     tempbx = SiS_Pr->CHSyncStart + 16;
-                     tempcx = SiS_Pr->CHSyncEnd + 16;
-                     tempax = SiS_Pr->SiS_VGAHT;
-                     if(modeflag & HalfDCLK) tempax >>= 1;
-                     tempax--;
-                     if(tempcx > tempax)  tempcx = tempax;
-                  }
+       if(SiS_Pr->SiS_VBType & VB_SISVB) {
+          if(HwInfo->jChipType >= SIS_661) {
+             if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
+                (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
+                if(resinfo == SIS_RI_1280x1024) {
+                   tempcx = (tempcx & 0xff00) | 0x30;
+                } else if(resinfo == SIS_RI_1600x1200) {
+                   tempcx = (tempcx & 0xff00) | 0xff;
+                }
+             }
+          }
+        }
 
-                  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
-                     unsigned char cr4, cr14, cr5, cr15;
-                     if(SiS_Pr->UseCustomMode) {
-                        cr4  = SiS_Pr->CCRT1CRTC[4];
-                        cr14 = SiS_Pr->CCRT1CRTC[14];
-                        cr5  = SiS_Pr->CCRT1CRTC[5];
-                        cr15 = SiS_Pr->CCRT1CRTC[15];
-                     } else {
-                        cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
-                        cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
-                        cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
-                        cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
-                     }
-                      tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3;                /* (VGAHRS-3)*8 */
-                      tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
-                     tempcx &= 0x00FF;
-                     tempcx |= (tempbx & 0xFF00);
-                      tempbx += 16;
-                      tempcx += 16;
-                     tempax = SiS_Pr->SiS_VGAHT;
-                     if(modeflag & HalfDCLK) tempax >>= 1;
-                     tempax--;
-                     if(tempcx > tempax)  tempcx = tempax;
-                  }
-
-                  if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
-                     tempbx = 1040;
-                     tempcx = 1042;
-                  }
-
-                }
-
-               temp = tempbx & 0xff;
-               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* CRT2 Horizontal Retrace Start */
 #endif  /* SIS315H */
 
-       }  /* 315/330 series */
+     }  /* 315/330 series */
+
+     if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-       /* The following is done for all bridge/chip types/series */
+        if(SiS_Pr->UseCustomMode) {
+          tempbx = SiS_Pr->CHSyncStart + bridgeadd;
+          tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
+          tempax = SiS_Pr->SiS_VGAHT;
+          if(modeflag & HalfDCLK) tempax >>= 1;
+          tempax--;
+          if(tempcx > tempax) tempcx = tempax;
+       }
 
-       tempax = tempbx & 0xFF00;
-       tempbx = pushbx;
-       tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
-       tempax |= (tempbx & 0xFF00);
-       temp = (tempax & 0xFF00) >> 8;
-       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);                        /* Overflow */
+       if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+          unsigned char cr4, cr14, cr5, cr15;
+          if(SiS_Pr->UseCustomMode) {
+             cr4  = SiS_Pr->CCRT1CRTC[4];
+             cr14 = SiS_Pr->CCRT1CRTC[14];
+             cr5  = SiS_Pr->CCRT1CRTC[5];
+             cr15 = SiS_Pr->CCRT1CRTC[15];
+          } else {
+             cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+             cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
+             cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
+             cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
+          }
+           tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3;               /* (VGAHRS-3)*8 */
+           tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
+          tempcx &= 0x00FF;
+          tempcx |= (tempbx & 0xFF00);
+           tempbx += bridgeadd;
+           tempcx += bridgeadd;
+          tempax = SiS_Pr->SiS_VGAHT;
+          if(modeflag & HalfDCLK) tempax >>= 1;
+          tempax--;
+          if(tempcx > tempax) tempcx = tempax;
+        }
 
-       temp = tempcx & 0x00FF;
-       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* CRT2 Horizontal Retrace End */
+        if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
+          tempbx = 1040;
+          tempcx = 1044;   /* HWCursor bug! */
+        }
 
-       /* 2. Vertical setup */
+     }
 
-       tempcx = SiS_Pr->SiS_VGAVT - 1;
-       temp = tempcx & 0x00FF;
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx);                      /* CRT2 Horizontal Retrace Start */
 
-       if(HwInfo->jChipType < SIS_661) {
-           if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-             if(HwInfo->jChipType < SIS_315H) {
-                if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-                   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
-                      temp--;
-                   }
-                 }
-             } else {
-                temp--;
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx);               /* CRT2 Horizontal Retrace End */
+
+     temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);                /* Overflow */
+
+     /* 2. Vertical setup */
+
+     tempcx = SiS_Pr->SiS_VGAVT - 1;
+     temp = tempcx & 0x00FF;
+
+     if(HwInfo->jChipType < SIS_661) {
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+          if(HwInfo->jChipType < SIS_315H) {
+             if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+                if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
+                   temp--;
+                }
               }
-           } else if(HwInfo->jChipType >= SIS_315H) {
-             temp--;
-          }
-       }
-       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* CRT2 Vertical Total */
-
-       tempbx = SiS_Pr->SiS_VGAVDE - 1;
-       temp = tempbx & 0x00FF;
-       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* CRT2 Vertical Display Enable End */
-
-       temp = ((tempbx & 0xFF00) << 3) >> 8;
-       temp |= ((tempcx & 0xFF00) >> 8);
-       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* Overflow (and HWCursor Test Mode) */
-
-       if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
-           tempbx++;
-          tempax = tempbx;
-          tempcx++;
-          tempcx -= tempax;
-          tempcx >>= 2;
-          tempbx += tempcx;
-          if(tempcx < 4) tempcx = 4;
-          tempcx >>= 2;
-          tempcx += tempbx;
-          tempcx++;
-       } else {
-          tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
-          tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
+          } else {
+             temp--;
+           }
+        } else if(HwInfo->jChipType >= SIS_315H) {
+          temp--;
        }
+     }
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                 /* CRT2 Vertical Total */
+
+     tempbx = SiS_Pr->SiS_VGAVDE - 1;
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx);               /* CRT2 Vertical Display Enable End */
+
+     temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                 /* Overflow */
+
+     if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
+        tempbx++;
+       tempax = tempbx;
+       tempcx++;
+       tempcx -= tempax;
+       tempcx >>= 2;
+       tempbx += tempcx;
+       if(tempcx < 4) tempcx = 4;
+       tempcx >>= 2;
+       tempcx += tempbx;
+       tempcx++;
+     } else {
+       tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
+       tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
+     }
 
-       if(SiS_Pr->SiS_VBType & VB_SISVB) {
-
+     if(SiS_Pr->SiS_VBType & VB_SISVB) {
+       if(SiS_Pr->UseCustomMode) {
+          tempbx = SiS_Pr->CVSyncStart;
+          tempcx = SiS_Pr->CVSyncEnd;
+       }
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+          unsigned char cr8, cr7, cr13;
           if(SiS_Pr->UseCustomMode) {
-             tempbx = SiS_Pr->CVSyncStart;
-             tempcx = (tempcx & 0xFF00) | (SiS_Pr->CVSyncEnd & 0x00FF);
+             cr8    = SiS_Pr->CCRT1CRTC[8];
+             cr7    = SiS_Pr->CCRT1CRTC[7];
+             cr13   = SiS_Pr->CCRT1CRTC[13];
+             tempcx = SiS_Pr->CCRT1CRTC[9];
+          } else {
+             cr8    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
+             cr7    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
+             cr13   = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
+             tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
           }
+          tempbx = cr8;
+          if(cr7  & 0x04) tempbx |= 0x0100;
+          if(cr7  & 0x80) tempbx |= 0x0200;
+          if(cr13 & 0x08) tempbx |= 0x0400;
+               }
+     }
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx);               /* CRT2 Vertical Retrace Start */
 
-          if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
-             unsigned char cr8, cr7, cr13, cr9;
-             if(SiS_Pr->UseCustomMode) {
-                cr8  = SiS_Pr->CCRT1CRTC[8];
-                cr7  = SiS_Pr->CCRT1CRTC[7];
-                cr13 = SiS_Pr->CCRT1CRTC[13];
-                cr9  = SiS_Pr->CCRT1CRTC[9];
-             } else {
-                cr8  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
-                cr7  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
-                cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
-                cr9  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
-             }
-             tempbx = cr8;
-             if(cr7 & 0x04)  tempbx |= 0x0100;
-             if(cr7 & 0x80)  tempbx |= 0x0200;
-             if(cr13 & 0x08) tempbx |= 0x0400;
-             tempcx = (tempcx & 0xFF00) | (cr9 & 0x00FF);
-          }
-       }
-       temp = tempbx & 0x00FF;
-       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);           /* CRT2 Vertical Retrace Start */
-
-       temp = ((tempbx & 0xFF00) >> 8) << 4;
-       temp |= (tempcx & 0x000F);
-       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);           /* CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
+     temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);                 /* CRT2 Vert. Retrace End; Overflow */
 
-       /* 3. Panel compensation delay */
+     /* 3. Panel delay compensation */
 
-       if(HwInfo->jChipType < SIS_315H) {
+     if(HwInfo->jChipType < SIS_315H) {
 
 #ifdef SIS300  /* ---------- 300 series -------------- */
 
-          if(SiS_Pr->SiS_VBType & VB_SISVB) {
-               temp = 0x20;
+       if(SiS_Pr->SiS_VBType & VB_SISVB) {
+          temp = 0x20;
+          if(HwInfo->jChipType == SIS_300) {
+             temp = 0x10;
+             if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  temp = 0x2c;
+             if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
+          }
+          if(SiS_Pr->SiS_VBType & VB_SIS301) {
+             if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
+          }
+          if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960)     temp = 0x24;
+          if(SiS_Pr->SiS_LCDResInfo == Panel_Custom)       temp = 0x2c;
+          if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)             temp = 0x08;
+          if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+             if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)       temp = 0x2c;
+             else                                          temp = 0x20;
+          }
+          if(SiS_Pr->SiS_UseROM) {
+             if(ROMAddr[0x220] & 0x80) {
+                if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
+                   temp = ROMAddr[0x221];
+                else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
+                   temp = ROMAddr[0x222];
+                else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
+                   temp = ROMAddr[0x223];
+                else
+                   temp = ROMAddr[0x224];
+                temp &= 0x3c;
+             }
+          }
+          if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+             if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC & 0x3c;
+          }
 
-               if(HwInfo->jChipType == SIS_300) {
-                  temp = 0x10;
-                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
-                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
-               }
-               if(SiS_Pr->SiS_VBType & VB_SIS301) {
-                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
-               }
-               if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)     temp = 0x24;
-               if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)       temp = 0x2c;
-               if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)            temp = 0x08;
-               if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-                  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)      temp = 0x2c;
-                  else                                         temp = 0x20;
-               }
-               if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
-                   if(ROMAddr[0x220] & 0x80) {
-                       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
-                               temp = ROMAddr[0x221];
-                       else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
-                               temp = ROMAddr[0x222];
-                       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)
-                               temp = ROMAddr[0x223];
-                       else
-                               temp = ROMAddr[0x224];
-                       temp &= 0x3c;
-                   }
-               }
-               if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-                  if(SiS_Pr->PDC) {
-                       temp = SiS_Pr->PDC & 0x3c;
-                  }
-               }
-          } else {
-               temp = 0x20;
-               if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
-                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) temp = 0x04;
-               }
-               if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-                   if(ROMAddr[0x220] & 0x80) {
-                       temp = ROMAddr[0x220] & 0x3c;
-                   }
-               }
-               if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-                  if(SiS_Pr->PDC) {
-                     temp = SiS_Pr->PDC & 0x3c;
-                  }
-               }
+       } else {
+          temp = 0x20;
+          if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+             if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
+          }
+          if(SiS_Pr->SiS_UseROM) {
+             if(ROMAddr[0x220] & 0x80) {
+                temp = ROMAddr[0x220] & 0x3c;
+             }
+          }
+          if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+             if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
           }
+        }
 
-          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
 
 #endif  /* SIS300 */
 
-       } else {
+     } else {
 
 #ifdef SIS315H   /* --------------- 315/330 series ---------------*/
 
-          if(HwInfo->jChipType < SIS_661) {
+        if(HwInfo->jChipType < SIS_661) {
 
-             if(SiS_Pr->SiS_VBType & VB_SISVB) {
-
-                 temp = 0x10;
-                 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
-                if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
-                if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
-                if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)    temp = 0x2c;
-                if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-                   temp = 0x08;
-                   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-                      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  temp = 0x2c;
-                      else                                     temp = 0x20;
-                   }
-                }
-                if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
-                   tempbl = 0x00;
-                   if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
-                      if(HwInfo->jChipType < SIS_330) {
-                         if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
-                      } else {
-                         if(ROMAddr[0x1bc] & 0x80) tempbl = 0xf0;
-                      }
-                   }
-                } else {  /* LV (550/301LV checks ROM byte, other LV BIOSes do not) */
-                   tempbl = 0xF0;
-                }
-                if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {
-                   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-                      if(SiS_Pr->PDC) {
-                         temp = SiS_Pr->PDC;
-                         tempbl = 0;
-                      }
-                   }
-                }
+          if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
 
-             } else {  /* LVDS */
+             if(HwInfo->jChipType == SIS_740) temp = 0x03;
+             else                             temp = 0x00;
 
-                if(HwInfo->jChipType == SIS_740) {
-                   temp = 0x03;
-                } else {
-                   temp = 0x00;
-                }
-                if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
-                tempbl = 0xF0;
-                if(HwInfo->jChipType == SIS_650) {
-                   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-                      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
-                   }
+             if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
+             tempbl = 0xF0;
+             if(HwInfo->jChipType == SIS_650) {
+                if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+                   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
                 }
+             }
 
-                if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
-                   temp = 0x08;
-                   tempbl = 0;
-                   if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
-                      if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
-                   }
+             if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
+                temp = 0x08;
+                tempbl = 0;
+                if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
+                   if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
                 }
              }
 
              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);      /* Panel Link Delay Compensation */
+          }
 
-          } /* < 661 */
+       } /* < 661 */
 
-          tempax = 0;
-          if (modeflag & DoubleScanMode) tempax |= 0x80;
-          if (modeflag & HalfDCLK)       tempax |= 0x40;
-          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
+       tempax = 0;
+       if(modeflag & DoubleScanMode) tempax |= 0x80;
+       if(modeflag & HalfDCLK)       tempax |= 0x40;
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
 
 #endif  /* SIS315H */
 
-       }
-
-     }  /* Slavemode */
+     }
 
-     if(SiS_Pr->SiS_VBType & VB_SISVB) {
+  }  /* Slavemode */
 
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
         /* For 301BDH with LCD, we set up the Panel Link */
-        if( (SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
-
-           SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex,
-                              HwInfo, RefreshRateTableIndex);
-
-        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-
-           SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex,
-                             HwInfo, RefreshRateTableIndex);
-        }
-
+       SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+     } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+       SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+     }
+  } else {
+     if(HwInfo->jChipType < SIS_315H) {
+       SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
      } else {
-
-        if(HwInfo->jChipType < SIS_315H) {
-
-          SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex,
-                               HwInfo, RefreshRateTableIndex);
+       if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+           if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+             SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
+           }
        } else {
-
-          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-              if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-                 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,
-                                     HwInfo,RefreshRateTableIndex);
-              }
-          } else {
-             SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,
-                                HwInfo,RefreshRateTableIndex);
-          }
-
+          SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
        }
-
      }
-  } /* LCDA */
+  }
 }
 
 /*********************************************/
@@ -7025,9 +6414,8 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 static UCHAR *
 SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
 {
-   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
    const UCHAR  *tableptr = NULL;
-   USHORT a, b, p = 0;
+   USHORT       a, b, p = 0;
 
    a = SiS_Pr->SiS_VGAHDE;
    b = SiS_Pr->SiS_HDE;
@@ -7036,66 +6424,33 @@ SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
       b = SiS_Pr->SiS_VDE;
    }
 
-   if((HwInfo->jChipType >= SIS_661) && (ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
-
-      if(a < b) {
-         p = ROMAddr[0x278] | (ROMAddr[0x279] << 8);
-      } else if(a == b) {
-         p = ROMAddr[0x27a] | (ROMAddr[0x27b] << 8);
-      } else {
-         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
-           p = ROMAddr[0x27e] | (ROMAddr[0x27f] << 8);
-        } else {
-           p = ROMAddr[0x27c] | (ROMAddr[0x27d] << 8);
-        }
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
-           if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)      p = ROMAddr[0x280] | (ROMAddr[0x281] << 8);
-           else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) p = ROMAddr[0x282] | (ROMAddr[0x283] << 8);
-           else                                         p = ROMAddr[0x284] | (ROMAddr[0x285] << 8);
-        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-           p = ROMAddr[0x286] | (ROMAddr[0x287] << 8);
-        }
-        do {
-           if((ROMAddr[p] | ROMAddr[p+1] << 8) == a) break;
-           p += 0x42;
-        } while((ROMAddr[p] | ROMAddr[p+1] << 8) != 0xffff);
-        if((ROMAddr[p] | ROMAddr[p+1] << 8) == 0xffff) p -= 0x42;
-      }
-      p += 2;
-      return(&ROMAddr[p]);
-
+   if(a < b) {
+      tableptr = SiS_Part2CLVX_1;
+   } else if(a == b) {
+      tableptr = SiS_Part2CLVX_2;
    } else {
-
-      if(a < b) {
-         tableptr = SiS_Part2CLVX_1;
-      } else if(a == b) {
-         tableptr = SiS_Part2CLVX_2;
+      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+        tableptr = SiS_Part2CLVX_4;
       } else {
-         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
-           tableptr = SiS_Part2CLVX_4;
-        } else {
-           tableptr = SiS_Part2CLVX_3;
-        }
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
-           if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)      tableptr = SiS_Part2CLVX_3;
-           else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
-           else                                         tableptr = SiS_Part2CLVX_5;
-
-        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-           tableptr = SiS_Part2CLVX_6;
-        }
-        do {
-           if((tableptr[p] | tableptr[p+1] << 8) == a) break;
-           p += 0x42;
-        } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
-        if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
+        tableptr = SiS_Part2CLVX_3;
+      }
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+        if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)        tableptr = SiS_Part2CLVX_3;
+        else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)   tableptr = SiS_Part2CLVX_3;
+        else                                           tableptr = SiS_Part2CLVX_5;
+      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+        tableptr = SiS_Part2CLVX_6;
       }
-      p += 2;
-      return((UCHAR *)&tableptr[p]);
+      do {
+        if((tableptr[p] | tableptr[p+1] << 8) == a) break;
+        p += 0x42;
+      } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
+      if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
    }
+   p += 2;
+   return((UCHAR *)&tableptr[p]);
 }
 
-
 static void
 SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                    USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
@@ -7121,49 +6476,97 @@ SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
 }
 
-static void
+static BOOLEAN
 SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
                    USHORT RefreshRateTableIndex,USHORT *CRT2Index,
                    USHORT *ResIndex,PSIS_HW_INFO HwInfo)
 {
-  USHORT tempbx,tempal;
+
+  if(HwInfo->jChipType < SIS_315H) return FALSE;
 
   if(ModeNo <= 0x13)
-       tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+     (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   else
-       tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+     (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 
-  tempbx = SiS_Pr->SiS_LCDResInfo;
+  (*ResIndex) &= 0x3f;
+  (*CRT2Index) = 0;
 
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx += 16;
-  else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx += 32;
-
-  if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-        tempbx = 100;
-        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx = 101;
-       else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 102;
-     }
-  } else if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-        if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
-           tempbx = 103;
-           if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx = 104;
-          else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 105;
-       }
-     }
-  } else if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-        if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 106;
+  if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+        (*CRT2Index) = 200;
      }
   }
 
-  *CRT2Index = tempbx;
-  *ResIndex = tempal & 0x3F;
+  if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+        if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
+     }
+  }
+  return(((*CRT2Index) != 0));
 }
 #endif
 
 #ifdef SIS300
+static void
+SiS_Group2LCDSpecial(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT crt2crtc)
+{
+   USHORT tempcx;
+   const UCHAR atable[] = {
+       0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
+       0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
+   };
+
+   if(!SiS_Pr->UseCustomMode) {
+      if( ( ( (HwInfo->jChipType == SIS_630) ||
+              (HwInfo->jChipType == SIS_730) ) &&
+            (HwInfo->jChipRevision > 2) )  &&
+          (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
+          (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
+          (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
+         if(ModeNo == 0x13) {
+            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
+            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
+            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
+         } else {
+            if((crt2crtc & 0x3F) == 4) {
+               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
+               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
+               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
+               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
+               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
+            }
+         }
+      }
+
+      if(HwInfo->jChipType < SIS_315H) {
+         if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
+            crt2crtc &= 0x1f;
+            tempcx = 0;
+            if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+                  tempcx += 7;
+               }
+            }
+            tempcx += crt2crtc;
+            if(crt2crtc >= 4) {
+               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
+            }
+
+            if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+                  if(crt2crtc == 4) {
+                     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
+                  }
+               }
+            }
+            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
+            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
+         }
+      }
+   }
+}
+
 /* For ECS A907. Highly preliminary. */
 static void
 SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
@@ -7232,15 +6635,81 @@ SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
           if(SiS_Pr->SiS_TVMode & TVSetPALM) {
              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
+             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
           } else {
-             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x15);
+             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);  /* 15 */
+             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a);  /* 1b */
           }
-          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
        }
      }
   } else {
-     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x21);
-     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x5a);
+     if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
+        (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 21 */
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 5a */
+     } else {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a);  /* 21 */
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53);  /* 5a */
+     }
+  }
+}
+
+static void
+SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
+{
+  USHORT temp;
+
+  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+     if(SiS_Pr->SiS_VGAVDE == 525) {
+       temp = 0xc3;
+       if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+          temp++;
+          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
+       }
+       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
+       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
+     } else if(SiS_Pr->SiS_VGAVDE == 420) {
+       temp = 0x4d;
+       if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+          temp++;
+          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
+       }
+       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
+     }
+  }
+
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
+       if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+          SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
+          /* Not always for LV, see SetGrp2 */
+       }
+       temp = 1;
+       if(ModeNo <= 0x13) temp = 3;
+       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
+     }
+#if 0
+     /* 651+301C, for 1280x768 - do I really need that? */
+     if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
+        if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
+          if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
+             ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
+             SiS_SetReg(SiS_Part2Port,0x01,0x2b);
+             SiS_SetReg(SiS_Part2Port,0x02,0x13);
+             SiS_SetReg(SiS_Part2Port,0x04,0xe5);
+             SiS_SetReg(SiS_Part2Port,0x05,0x08);
+             SiS_SetReg(SiS_Part2Port,0x06,0xe2);
+             SiS_SetReg(SiS_Part2Port,0x1c,0x21);
+             SiS_SetReg(SiS_Part2Port,0x1d,0x45);
+             SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
+             SiS_SetReg(SiS_Part2Port,0x20,0x00);
+             SiS_SetReg(SiS_Part2Port,0x21,0xa9);
+             SiS_SetReg(SiS_Part2Port,0x23,0x0b);
+             SiS_SetReg(SiS_Part2Port,0x25,0x04);
+          }
+       }
+     }
+#endif
   }
 }
 
@@ -7248,37 +6717,27 @@ static void
 SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
              PSIS_HW_INFO HwInfo)
 {
-  USHORT      i, j, tempax, tempbx, tempcx, temp;
-  USHORT      push1, push2, modeflag, crt2crtc;
-  ULONG       longtemp, tempeax;
+  USHORT      i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
+  USHORT      push2, modeflag, crt2crtc, bridgeoffset;
+  ULONG       longtemp;
   const       UCHAR *PhasePoint;
   const       UCHAR *TimingPoint;
 #ifdef SIS315H
   USHORT      resindex, CRT2Index;
   const       SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
-#endif
-#ifdef SIS300
-  const UCHAR atable[] = {
-       0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
-       0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
-  };
-#endif
 
-#ifdef SIS315H   
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
 #endif
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
+     crt2crtc = 0;
   } else {
-     if(SiS_Pr->UseCustomMode) {
-        modeflag = SiS_Pr->CModeFlag;
-       crt2crtc = 0;
-     } else {
-        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-       crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-     }
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   }
 
   temp = 0;
@@ -7395,7 +6854,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)   tempax = 950;
   else if(SiS_Pr->SiS_TVMode & TVSetPAL)       tempax = 520;
-  else                                                 tempax = 440;
+  else                                                 tempax = 440; /* NTSC, YPbPr 525, 750 */
 
   if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
       ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
@@ -7411,10 +6870,10 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
      temp = tempax + (USHORT)TimingPoint[1];
      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
 
-     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
+     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
-           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x19);
-           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x52);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 19 */
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 52 */
         } else {
            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
@@ -7427,199 +6886,157 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
   tempcx--;
   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--;
-  temp = tempcx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,temp);
-  temp = (tempcx & 0xFF00) >> 8;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,temp);
-
-  tempcx++;
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx++;
-  tempcx >>= 1;
-
-  push1 = tempcx;
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
 
+  tempcx = SiS_Pr->SiS_HT >> 1;
+  if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
   tempcx += 7;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
-  temp = (tempcx & 0x00FF) << 4;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
 
-  tempbx = TimingPoint[j] | ((TimingPoint[j+1]) << 8);
+  tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
   tempbx += tempcx;
-
-  temp = tempbx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,temp);
-  temp = ((tempbx & 0xFF00) >> 8) << 4;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
 
   tempbx += 8;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
      tempbx -= 4;
      tempcx = tempbx;
   }
-  temp = (tempbx & 0x00FF) << 4;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
 
   j += 2;
-  tempcx += ((TimingPoint[j] | ((TimingPoint[j+1]) << 8)));
-  temp = tempcx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,temp);
-  temp = ((tempcx & 0xFF00) >> 8) << 4;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,temp);
+  tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
 
   tempcx += 8;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
-  temp = (tempcx & 0x00FF) << 4;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,temp);
-
-  tempcx = push1;
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
 
+  tempcx = SiS_Pr->SiS_HT >> 1;
+  if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
   j += 2;
   tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
-  temp = (tempcx & 0x00FF) << 4;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
 
   tempcx -= 11;
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
      tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
   }
-  temp = tempcx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
 
   tempbx = SiS_Pr->SiS_VDE;
-  if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
-  if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
-  if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
-  if(HwInfo->jChipType < SIS_315H) {
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
-  } else {
-     if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
-         (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
-       tempbx >>= 1;
-       if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
-          if(ModeNo <= 0x13) {
-             if(crt2crtc == 1) tempbx++;
-          }
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+     if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
+     if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
+     if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
+  } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
+             (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
+     tempbx >>= 1;
+     if(HwInfo->jChipType >= SIS_315H) {
+        if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
+          if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-          if(crt2crtc == 4) {
-              if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
+          if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+             if(crt2crtc == 4) tempbx++;
           }
        }
      }
-  }
-  tempbx -= 2;
-  temp = tempbx & 0x00FF;
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-        if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) temp++;
-     }
-  }
-
-  if(HwInfo->jChipType < SIS_661) {
-     /* From 1.10.7w - doesn't make sense */
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-           if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
-             if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {   /* SetFlag?? */
-                if(ModeNo == 0x03) temp++;
-             }
-          }
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+          if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
+       }
+       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
+          if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
         }
      }
   }
-  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,temp);
+  tempbx -= 2;
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
 
   temp = (tempcx >> 8) & 0x0F;
-  temp |= (((tempbx >> 8) << 6) & 0xC0);
-  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750 | SetCRT2ToSCART))) {
+  temp |= ((tempbx >> 2) & 0xC0);
+  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
      temp |= 0x10;
-     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x20;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
   }
   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
 
-  if((HwInfo->jChipType > SIS_315H) && (HwInfo->jChipType < SIS_661)) {
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
-           if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
-               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ) {
-              SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
-          }
-        }
+  if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
+  }
+
+#if 0
+  /* TEST qqqq */
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+     for(i=0x01, j=0; i<=0x2D; i++, j++) {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
+     }
+     for(i=0x39; i<=0x45; i++, j++) {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
      }
   }
+#endif
 
   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
      tempbx = SiS_Pr->SiS_VDE;
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
-           tempbx >>= 1;
-       }
+     if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
+         (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
+        tempbx >>= 1;
      }
      tempbx -= 3;
-     if(HwInfo->jChipType >= SIS_661) {
-        if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {  /* Why not 301B/LV? */
-           temp = 0;
-          if(tempcx & 0x0400) temp |= 0x20;
-          if(tempbx & 0x0400) temp |= 0x40;
-          SiS_SetReg(SiS_Pr->SiS_Part4Port,0x10,temp);
-       }
-     }
-     tempbx &= 0x03ff;
-     temp = ((tempbx & 0xFF00) >> 8) << 5;
-     temp |= 0x18;
+     temp = ((tempbx >> 3) & 0x60) | 0x18;
      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
-     temp = tempbx & 0x00FF;
-     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,temp);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
 
+     if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
+     }
   }
 
   tempbx = 0;
   if(!(modeflag & HalfDCLK)) {
      if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
         tempax = 0;
-        tempbx |= 0x2000;
+        tempbx |= 0x20;
      }
   }
 
-  tempcx = 0x0101;
+  tempch = tempcl = 0x01;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
      if(SiS_Pr->SiS_VGAHDE >= 1024) {
         if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
-           tempcx = 0x1920;
+           tempch = 0x19;
+          tempcl = 0x20;
            if(SiS_Pr->SiS_VGAHDE >= 1280) {
-              tempcx = 0x1420;
-              tempbx &= ~0x2000;
+              tempch = 0x14;
+              tempbx &= ~0x20;
            }
         }
      }
   }
 
-  if(!(tempbx & 0x2000)) {
-     if(modeflag & HalfDCLK) {
-        tempcx = (tempcx & 0xFF00) | ((tempcx << 1) & 0x00FF);
-     }
-     longtemp = (SiS_Pr->SiS_VGAHDE * ((tempcx & 0xFF00) >> 8)) / (tempcx & 0x00FF);
-     longtemp <<= 13;
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-       longtemp <<= 3;
-     }
-     tempeax = longtemp / SiS_Pr->SiS_HDE;
-     if(longtemp % SiS_Pr->SiS_HDE) tempeax++;
-     tempax = (USHORT)tempeax;
-     tempbx |= (tempax & 0x1F00);
-     tempcx = (tempax & 0xFF00) >> (8 + 5);
+  if(!(tempbx & 0x20)) {
+     if(modeflag & HalfDCLK) tempcl <<= 1;
+     longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) longtemp <<= 3;
+     tempax = longtemp / SiS_Pr->SiS_HDE;
+     if(longtemp % SiS_Pr->SiS_HDE) tempax++;
+     tempbx |= ((tempax >> 8) & 0x1F);
+     tempcx = tempax >> 13;
   }
 
   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,(tempbx >> 8));
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
 
   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 
-     temp = tempcx & 0x0007;
-     if(tempbx & 0x2000) temp = 0;
-     if((HwInfo->jChipType < SIS_661) || (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
-        temp |= 0x18;
-     }
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
+     tempcx &= 0x07;
+     if(tempbx & 0x20) tempcx = 0;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
 
      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
         tempbx = 0x0382;
@@ -7628,11 +7045,9 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
         tempbx = 0x0369;
         tempcx = 0x0061;
      }
-     temp = (tempbx & 0x00FF) ;
-     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,temp);
-     temp = (tempcx & 0x00FF) ;
-     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,temp);
-     temp = (tempcx & 0x0300) >> (8 - 2);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
+     temp = (tempcx & 0x0300) >> 6;
      temp |= ((tempbx >> 8) & 0x03);
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
         temp |= 0x10;
@@ -7642,7 +7057,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
 
      temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
-     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
 
      SiS_SetTVSpecial(SiS_Pr, ModeNo);
 
@@ -7657,7 +7072,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
      if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
         temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
-        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
      }
      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
   }
@@ -7675,13 +7090,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
   tempbx = SiS_Pr->SiS_HDE;
   if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
   tempbx--;                                    /* RHACTE = HDE - 1 */
-  temp = tempbx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,temp);
-  temp = (tempbx & 0xFF00) >> 4;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
 
   temp = 0x01;
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+  if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
      if(SiS_Pr->SiS_ModeType == ModeEGA) {
         if(SiS_Pr->SiS_VGAHDE >= 1024) {
            temp = 0x02;
@@ -7696,49 +7109,19 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
 
   tempbx = SiS_Pr->SiS_VDE - 1;
-  temp = tempbx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,temp);
-  temp = ((tempbx & 0xFF00) >> 8) & 0x07;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
 
   tempcx = SiS_Pr->SiS_VT - 1;
-  temp = tempcx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,temp);
-
-  temp = ((tempcx & 0xFF00) >> 8) << 5;
-
-  /* Enable dithering; only do this for 32bpp mode */
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
+  temp = (tempcx >> 3) & 0xE0;
   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+     /* Enable dithering; only do this for 32bpp mode */
      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
         temp |= 0x10;
      }
   }
-
-  /* Must do special for Compaq1280; Acer1280 OK, Clevo1400 OK, COMPAL1400 OK */
-  /* Compaq1280 panel loses sync if using CR37 sync info. */
-  if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-     if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
-       if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
-          (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) {
-          if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-             temp |= ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
-          }
-       } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
-                 (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)) {
-          temp |= 0x03;
-       } else {
-           temp |= (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) >> 6);
-          temp |= 0x08;
-          if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04;
-       }
-     } else {
-        if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-          temp |= ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
-       }
-     }
-  }
-
-  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1A,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
 
   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
@@ -7746,154 +7129,13 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
 
-#if 0  /* Use the 315/330 series code for now */
-  if((HwInfo->jChipType >= SIS_661)          &&
-     (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) &&
-     (ROMAddr && SiS_Pr->SiS_UseROM)) {
-
-      /* This is done for the LVDS bridges only, since
-       * the TMDS panels already work correctly with
-       * the old code. Besides, we only do that if
-       * we can get the data from the ROM, I am tired
-       * of carrying a lot of tables around.
-       */
-
-#ifdef SIS315H                                                         /* ------------ 661/741/760 series --------- */
-      UCHAR *myptr = NULL, myptr1 = NULL;
-
-      myptr = (UCHAR *)GetLCDPtr661(SiS_Pr, HwInfo, 6, ModeNo, ModeIdIndex, RefreshRateTableIndex);
-      myptr1 = (UCHAR *)GetLCDStructPtr661(SiS_Pr, HwInfo);
-
-      tempbx = (myptr[3] | (myptr[4] << 8)) & 0x0fff;
-      tempcx = SiS_Pr->PanelYRes;
-      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-         tempcx = SiS_Pr->SiS_VDE;
-      }
-
-      tempcx += tempbx;
-      if(tempcx >= SiS_Pr->SiS_VT) tempcx -= SiS_Pr->SiS_VT;
-
-      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempbx);
-      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempcx);
-
-      tempcx &= 0x07ff;
-      tempbx &= 0x07ff;
-      temp = (tempcx >> 8) << 3;
-      temp |= (tempbx >> 8);
-      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
-
-      tempbx = (myptr[4] | (myptr[5] << 8)) >> 4;
-      tempcx = myptr1[6];
-      if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempcx = myptr[7];
-
-      tempcx += tempbx;
-      if(tempcx >= SiS_Pr->SiS_VT) tempcx -= SiS_Pr->SiS_VT;
-
-      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);
-      temp = tempcx & 0x000f;
-      temp |= ((tempbx & 0x0f00) >> 4);
-      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
-
-      tempax = SiS_Pr->SiS_HT;
-      tempbx = (myptr[0] | (myptr[1] << 8)) & 0x0fff;
-      tempcx = SiS_Pr->PanelXRes;
-      if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempcx = SiS_Pr->SiS_HDE;
-
-      if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
-         tempax >>= 1;
-        tempbx >>= 1;
-        tempcx >>= 1;
-      }
-      if(SiS_Pr->SiS_VBType & VB_SIS302LV)                 tempbx++;
-      if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) tempbx++;
-
-      tempcx += tempbx;
-      if(tempcx >= tempax) tempcx -= tempax;
-
-      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,tempbx);
-      temp = ((tempbx & 0xff00) >> 8) << 4;
-      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x20,temp);
-      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempcx);
-      temp = tempcx >> 8;
-      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x25,temp);
-
-      tempax = SiS_Pr->SiS_HT;
-      tempbx = (myptr[1] | (myptr[2] << 8)) >> 4;
-      tempcx = myptr1[5];
-      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-         tempcx = myptr[6];
-      }
-      if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
-         tempax >>= 1;
-        tempbx >>= 1;
-        tempcx >>= 1;
-      }
-      if(SiS_Pr->SiS_VBType & VB_SIS302LV) tempbx++;
-
-      tempcx += tempbx;
-      if(tempcx >= tempax) tempcx -= tempax;
-
-      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1c,tempbx);
-      temp = (tempbx & 0x0f00) >> 4;
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1d,0x0f,temp);
-      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempcx);
-
-      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-         if(SiS_Pr->SiS_VGAVDE == 525) {
-           temp = 0xc3;
-           if(SiS_Pr->SiS_ModeType <= ModeVGA) {
-              temp++;
-              if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
-           }
-           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
-           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
-        } else if(SiS_Pr->SiS_VGAVDE == 420) {
-           temp = 0x4d;
-           if(SiS_Pr->SiS_ModeType <= ModeVGA) {
-              temp++;
-              if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
-           }
-           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
-        }
-      }
-
-#endif
-
-  } else
-#endif
-         if((HwInfo->jChipType >= SIS_315H)                    &&
-            (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)            &&
-            ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  ||
-             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
-             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) ) {
-
-#ifdef SIS315H                                                         /* ------------- 315/330 series ------------ */
-
-      SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
-                          &CRT2Index, &resindex, HwInfo);
-
+#ifdef SIS315H
+  if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                                               &CRT2Index, &resindex, HwInfo)) {
       switch(CRT2Index) {
-        case Panel_1024x768      : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;  break;  /* "Normal" */
-        case Panel_1280x1024     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_1; break;
-       case Panel_1400x1050     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_1; break;
-       case Panel_1600x1200     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_1; break;
-        case Panel_1024x768  + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;  break;  /* Non-Expanding */
-        case Panel_1280x1024 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_2; break;
-       case Panel_1400x1050 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_2; break;
-       case Panel_1600x1200 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_2; break;
-        case Panel_1024x768  + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;  break;  /* VESA Timing */
-        case Panel_1280x1024 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_3; break;
-       case Panel_1400x1050 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_3; break;
-       case Panel_1600x1200 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_3; break;
-       case 100:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_1; break;  /* Custom */
-       case 101:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_2; break;
-       case 102:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_3; break;
-       case 103:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_1; break;    /* Custom */
-       case 104:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_2; break;
-       case 105:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_3; break;
-       case 106:                  CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Asus1024x768_3; break;
-       default:                   CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;  break;
+        case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;
+       case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
+       default:  CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;   break;
       }
 
       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
@@ -7910,58 +7152,34 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
 
-      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-        if(SiS_Pr->SiS_VGAVDE == 525) {
-         temp = 0xc3;
-         if(SiS_Pr->SiS_ModeType <= ModeVGA) {
-            temp++;
-            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
-         }
-         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
-         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
-       } else if(SiS_Pr->SiS_VGAVDE == 420) {
-         temp = 0x4d;
-         if(SiS_Pr->SiS_ModeType <= ModeVGA) {
-            temp++;
-            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
-         }
-         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
-       }
-     }
-
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-          /* See Sync above, 0x1a */
-          temp = 1;
-          if(ModeNo <= 0x13) temp = 3;
-          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
-       }
-     }
-#endif
+      SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
 
-  } else {   /* ------ 300 series and other bridges, other LCD resolutions ------ */
 
-      /* Using this on the 301B with an auto-expanding 1024 panel (CR37=1) makes
-       * the panel scale at modes < 1024 (no black bars); if the panel is non-expanding,
-       * the bridge scales all modes to 1024.
-       * !!! Malfunction at 640x480 and 640x400 when panel is auto-expanding - black screen !!!
-       */
+  } else {
+#endif
 
-    tempcx = SiS_Pr->SiS_VT;
-    tempbx = SiS_Pr->PanelYRes;
+    /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
+    /*             Clevo dual-link 1024x768 */
+    /*                    Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct)  */
+    /*            Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
 
     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-       tempbx = SiS_Pr->SiS_VDE - 1;
-       tempcx--;
-    }
-
-    tempax = 1;
-    if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-       if(tempbx != SiS_Pr->SiS_VDE) {
-          tempax = tempbx;
-          if(tempax < SiS_Pr->SiS_VDE) {
-             tempax = 0;
-             tempcx = 0;
+       if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
+          tempbx = SiS_Pr->SiS_VDE - 1;
+          tempcx = SiS_Pr->SiS_VT - 1;
+       } else {
+          tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
+         tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
+       }
+    } else {
+       tempbx = SiS_Pr->PanelYRes;
+       tempcx = SiS_Pr->SiS_VT;
+       tempax = 1;
+       if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
+          tempax = SiS_Pr->PanelYRes;
+         /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c;   */  /* 651+301C */
+          if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
+             tempax = tempcx = 0;
           } else {
              tempax -= SiS_Pr->SiS_VDE;
           }
@@ -7971,29 +7189,55 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
        tempbx -= tempax; /* lcdvdee */
     }
 
-    /* Non-expanding: lcdvdees = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
+    /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
 
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
 #endif
 
-    temp = tempcx & 0x00FF;                            /* RVEQ1EQ=lcdvdes */
-    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,temp);
-    temp = tempbx & 0x00FF;                            /* RVEQ2EQ=lcdvdee */
-    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,temp);
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);     /* lcdvdes  */
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);     /* lcdvdee  */
 
-    temp = ((tempbx & 0xFF00) >> 8) << 3;
-    temp |= ((tempcx & 0xFF00) >> 8);
+    temp = (tempbx >> 5) & 0x38;
+    temp |= ((tempcx >> 8) & 0x07);
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
 
-    tempbx = SiS_Pr->SiS_VT;    /* push2; */
-    tempax = SiS_Pr->SiS_VDE;   /* push1; */
-    tempcx = (tempbx - tempax) >> 4;
-    tempbx += tempax;
-    tempbx >>= 1;
-    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx -= 10;
+    tempax = SiS_Pr->SiS_VDE;
+    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+       tempax = SiS_Pr->PanelYRes;
+    }
+    tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
+    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+       if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
+         tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
+       }
+    }
+
+    tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
+    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+       if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
+          if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
+             tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
+            if(tempax % 4) { tempax >>= 2; tempax++; }
+            else           { tempax >>= 2;           }
+             tempbx -= (tempax - 1);
+         } else {
+            tempbx -= 10;
+            if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
+         }
+       }
+    }
+    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+       tempbx++;
+       if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
+          if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+            tempbx = 770;
+            tempcx = 3;
+         }
+       }
+    }
 
-    /* non-expanding: lcdvrs = tempbx = ((VT + VDE) / 2) - 10 */
+    /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
 
     if(SiS_Pr->UseCustomMode) {
        tempbx = SiS_Pr->CVSyncStart;
@@ -8003,12 +7247,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
     xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
 #endif
 
-    temp = tempbx & 0x00FF;                            /* RTVACTEE = lcdvrs */
-    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);         /* lcdvrs */
 
-    temp = ((tempbx & 0xFF00) >> 8) << 4;
+    temp = (tempbx >> 4) & 0xF0;
     tempbx += (tempcx + 1);
-    temp |= (tempbx & 0x000F);
+    temp |= (tempbx & 0x0F);
 
     if(SiS_Pr->UseCustomMode) {
        temp &= 0xf0;
@@ -8021,149 +7264,103 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
 
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
 
-    /* Code from 630/301B (I+II) BIOS */
-
 #ifdef SIS300
-    if(!SiS_Pr->UseCustomMode) {
-       if( ( ( (HwInfo->jChipType == SIS_630) ||
-               (HwInfo->jChipType == SIS_730) ) &&
-             (HwInfo->jChipRevision > 2) )  &&
-           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
-           (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
-           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
-          if(ModeNo == 0x13) {
-             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
-             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
-             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
-          } else {
-             if((crt2crtc & 0x3F) == 4) {
-                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
-                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
-                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
-                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
-                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
-             }
-          }
-       }
+    SiS_Group2LCDSpecial(SiS_Pr, HwInfo, ModeNo, crt2crtc);
+#endif
 
-       if(HwInfo->jChipType < SIS_315H) {
-          if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
-             crt2crtc &= 0x1f;
-             tempcx = 0;
-             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
-                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-                   tempcx += 7;
-                }
-             }
-             tempcx += crt2crtc;
-             if(crt2crtc >= 4) {
-                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
-             }
+    bridgeoffset = 7;
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)          bridgeoffset += 2;
+    if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) bridgeoffset++;
+    if(SiS_IsDualLink(SiS_Pr, HwInfo))                  bridgeoffset++;
 
-             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
-                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-                   if(crt2crtc == 4) {
-                      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
-                   }
-                }
-             }
-             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
-             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
-          }
+    temp = 0;
+    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+       if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
+          temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
+         if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp >>= 1;
        }
     }
-#endif
-
-    tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2;     /* (HT - HDE) >> 2 */
-    tempbx = SiS_Pr->SiS_HDE + 7;                        /* lcdhdee         */
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-       tempbx += 2;
+    temp += bridgeoffset;
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);            /* lcdhdes */
+    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
+
+    tempcx = SiS_Pr->SiS_HT;
+    tempax = tempbx = SiS_Pr->SiS_HDE;
+    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+       if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
+          tempax = SiS_Pr->PanelXRes;
+          tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
+       }
+    }
+    if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
+       tempcx >>= 1;
+       tempbx >>= 1;
+       tempax >>= 1;
     }
-    push1 = tempbx;
 
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
 #endif
 
-    temp = tempbx & 0x00FF;                                      /* RHEQPLE = lcdhdee */
-    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,temp);
-    temp = (tempbx & 0xFF00) >> 8;
-    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp);
+    tempbx += bridgeoffset;
 
-    temp = 7;
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-       temp += 2;
-    }
-    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);         /* RHBLKE = lcdhdes[7:0] */
-    SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x20,0x0F);      /* lcdhdes [11:8] */
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx);         /* lcdhdee */
+    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
+
+    tempcx = (tempcx - tempax) >> 2;
 
     tempbx += tempcx;
     push2 = tempbx;
 
-    if(SiS_Pr->UseCustomMode) {
-       tempbx = SiS_Pr->CHSyncStart + 7;
-       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-          tempbx += 2;
+    if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
+       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+          if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+             if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
+         }
        }
     }
 
+    if(SiS_Pr->UseCustomMode) {
+       tempbx = SiS_Pr->CHSyncStart;
+       if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+       tempbx += bridgeoffset;
+    }
+
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
 #endif
 
-    temp = tempbx & 0x00FF;                                      /* RHBURSTS = lcdhrs */
-    if(!SiS_Pr->UseCustomMode) {
-       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-             if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
-          }
-       }
-    }
-    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,temp);
-    temp = (tempbx & 0x0F00) >> 4;
-    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);         /* lcdhrs */
+    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
 
     tempbx = push2;
+
     tempcx <<= 1;
+    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+       if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
+    }
     tempbx += tempcx;
 
     if(SiS_Pr->UseCustomMode) {
-       tempbx = SiS_Pr->CHSyncEnd + 7;
-       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-          tempbx += 2;
-       }
+       tempbx = SiS_Pr->CHSyncEnd;
+       if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+       tempbx += bridgeoffset;
     }
 
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
 #endif
 
-    temp = tempbx & 0x00FF;                                      /* RHSYEXP2S = lcdhre */
-    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,temp);
-
-    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-       if(SiS_Pr->SiS_VGAVDE == 525) {
-          if(SiS_Pr->SiS_ModeType <= ModeVGA)
-            temp=0xC6;
-          else
-                    temp=0xC3;
-          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
-          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xB3);
-       } else if(SiS_Pr->SiS_VGAVDE == 420) {
-          if(SiS_Pr->SiS_ModeType <= ModeVGA)
-            temp=0x4F;
-          else
-                    temp=0x4D;
-          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
-       }
-    }
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);         /* lcdhre */
+
+    SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
 
 #ifdef SIS300
-    SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex,
-                        RefreshRateTableIndex, ModeNo);
+    SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex, RefreshRateTableIndex, ModeNo);
+#endif
+#ifdef SIS315H
+  } /* CRT2-LCD from table */
 #endif
-
-  } /* HwInfo */
 }
 
 /*********************************************/
@@ -8174,26 +7371,14 @@ static void
 SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
               PSIS_HW_INFO HwInfo)
 {
-  USHORT modeflag, i;
-  const UCHAR  *tempdi;
+  USHORT       i;
+  const UCHAR          *tempdi;
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
 
-  if(ModeNo<=0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  } else {
-     if(SiS_Pr->UseCustomMode) {
-        modeflag = SiS_Pr->CModeFlag;
-     } else {
-       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     }
-  }
-
 #ifndef SIS_CP
   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
-#endif
-
-#ifdef SIS_CP
+#else
   SIS_CP_INIT301_CP
 #endif
 
@@ -8216,11 +7401,6 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      tempdi = SiS_Pr->SiS_HiTVGroup3Data;
      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
         tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
-#if 0
-        if(!(modeflag & Charx8Dot)) {
-           tempdi = SiS_Pr->SiS_HiTVGroup3Text;
-        }
-#endif
      }
   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
      if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
@@ -8229,7 +7409,7 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      }
   }
   if(tempdi) {
-     for(i=0; i<=0x3E; i++){
+     for(i=0; i<=0x3E; i++) {
         SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
      }
      if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
@@ -8239,11 +7419,9 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      }
   }
 
-  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) {
 #ifdef SIS_CP
-     SIS_CP_INIT301_CP2
+  SIS_CP_INIT301_CP2
 #endif
-  }
 }
 
 /*********************************************/
@@ -8252,11 +7430,37 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
 #ifdef SIS315H
 static void
-SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ShiftXPos(SiS_Private *SiS_Pr, int shift)
 {
-   USHORT temp, temp1;
+   USHORT temp, temp1, temp2;
 
-   if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
+   temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
+   temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
+   temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
+   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
+   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
+   temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
+   temp = (USHORT)((int)(temp) + shift);
+   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
+   temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
+   temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
+   temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
+   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
+   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
+}
+
+static void
+SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                    USHORT ModeNo, USHORT ModeIdIndex)
+{
+   USHORT temp, temp1, resinfo = 0;
+
+   if(!(SiS_Pr->SiS_VBType & VB_SIS301C)) return;
+   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
+
+   if(ModeNo > 0x13) {
+      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+   }
 
    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
    temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
@@ -8267,28 +7471,37 @@ SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
       }
       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
-      temp = 0;
-      if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)) {
-         temp |= 0x0002;
-         if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)) {
-           temp ^= 0x0402;
-           if(!(SiS_Pr->SiS_TVMode & TVSetHiVision)) {
-              temp ^= 0x0002;
-           }
-        }
-      }
+      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      temp = 0x0000;
+      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
+      else if(SiS_Pr->SiS_TVMode & TVSetHiVision)  temp = 0x0400;
+      else                                        temp = 0x0402;
       if(HwInfo->jChipType >= SIS_661) {
-         temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
-         if(temp1 & 0x01) temp |= 0x10;
-         if(temp1 & 0x02) temp |= 0x01;
-        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xec,(temp & 0xff));
+         temp1 = 0;
+        if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
+        if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
       } else {
          temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
         if(temp1 == 0x01) temp |= 0x01;
         if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */
-        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xea,(temp & 0xff));
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
       }
       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
+
+      if(HwInfo->jChipType >= SIS_661) {               /* ? */
+         if(SiS_Pr->SiS_TVMode & TVAspect43) {
+            if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
+              if(resinfo == SIS_RI_1024x768) {
+                 SiS_ShiftXPos(SiS_Pr, 97);
+              } else {
+                 SiS_ShiftXPos(SiS_Pr, 111);
+              }
+           } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
+              SiS_ShiftXPos(SiS_Pr, 136);
+           }
+         }
+      }
    }
 }
 #endif
@@ -8330,25 +7543,22 @@ SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
 }
 
-/* Set 301 VGA2 registers */
 static void
 SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
              USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
 {
-  USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,resinfo;
+  USHORT tempax,tempcx,tempbx,modeflag,temp,resinfo;
   ULONG tempebx,tempeax,templong;
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
+     resinfo = 0;
   } else {
-     if(SiS_Pr->UseCustomMode) {
-        modeflag = SiS_Pr->CModeFlag;
-       resinfo = 0;
-     } else {
-       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-     }
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
 
   if(HwInfo->jChipType >= SIS_315H) {
@@ -8371,186 +7581,151 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
           if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
              SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
           }
-#ifdef SET_EMI
+
           if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
              SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+#ifdef SET_EMI
              SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+#endif
              SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
           }
-#endif
        }
        return;
      }
   }
 
-  temp = SiS_Pr->SiS_RVBHCFACT;
-  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
 
   tempbx = SiS_Pr->SiS_RVBHCMAX;
-  temp = tempbx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
 
-  temp2 = (((tempbx & 0xFF00) >> 8) << 7) & 0x00ff;
+  temp = (tempbx >> 1) & 0x80;
 
   tempcx = SiS_Pr->SiS_VGAHT - 1;
-  temp = tempcx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
 
-  temp = (((tempcx & 0xFF00) >> 8) << 3) & 0x00ff;
-  temp2 |= temp;
+  temp |= ((tempcx >> 5) & 0x78);
 
   tempcx = SiS_Pr->SiS_VGAVT - 1;
-  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempcx -= 5;
-
-  temp = tempcx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,temp);
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
 
-  temp = temp2 | ((tempcx & 0xFF00) >> 8);
+  temp |= ((tempcx >> 8) & 0x07);
   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
 
   tempbx = SiS_Pr->SiS_VGAHDE;
-  if(modeflag & HalfDCLK)  tempbx >>= 1;
-  if(HwInfo->jChipType >= SIS_661) {
-     if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
-  }
+  if(modeflag & HalfDCLK)            tempbx >>= 1;
+  if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
 
-  temp = 0xA0;
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
      temp = 0;
-     if(tempbx > 800) {
-        temp = 0xA0;
-        if(tempbx != 1024) {
-           temp = 0xC0;
-           if(tempbx != 1280) temp = 0;
-       }
-     }
-  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-     if(tempbx <= 800) {
-        temp = 0x80;
-     }
+     if(tempbx > 800)        temp = 0x60;
+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+     temp = 0;
+     if(tempbx == 1024)      temp = 0xA0;
+     else if(tempbx > 1024)  temp = 0xC0;
+  } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
+     temp = 0;
+     if(tempbx >= 1280)      temp = 0x40;
+     else if(tempbx >= 1024) temp = 0x20;
   } else {
      temp = 0x80;
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        temp = 0;
-        if(tempbx > 800) temp = 0x60;
-     }
-  }
-
-  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
-     temp = 0;
-     if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
-  }
-
-  if(HwInfo->jChipType < SIS_661) {
-     if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp = 0;
+     if(tempbx >= 1024)      temp = 0xA0;
   }
 
   if(SiS_Pr->SiS_VBType & VB_SIS301) {
-     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
-        temp |= 0x0A;
+     if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) temp |= 0x0A;
   }
 
   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
 
+  tempeax = SiS_Pr->SiS_VGAVDE;
   tempebx = SiS_Pr->SiS_VDE;
-
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
      if(!(temp & 0xE0)) tempebx >>=1;
   }
 
   tempcx = SiS_Pr->SiS_RVBHRS;
-  temp = tempcx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
+  tempcx >>= 8;
+  tempcx |= 0x40;
 
-  tempeax = SiS_Pr->SiS_VGAVDE;
-  tempcx |= 0x4000;
   if(tempeax <= tempebx) {
-     tempcx ^= 0x4000;
+     tempcx ^= 0x40;
   } else {
      tempeax -= tempebx;
   }
 
-  templong = (tempeax * 256 * 1024) % tempebx;
-  tempeax = (tempeax * 256 * 1024) / tempebx;
-  tempebx = tempeax;
-  if(templong != 0) tempebx++;
+  tempeax *= (256 * 1024);
+  templong = tempeax % tempebx;
+  tempeax /= tempebx;
+  if(templong) tempeax++;
 
-  temp = (USHORT)(tempebx & 0x000000FF);
+  temp = (USHORT)(tempeax & 0x000000FF);
   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
-  temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
+  temp = (USHORT)((tempeax & 0x0000FF00) >> 8);
   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
-
-  tempbx = (USHORT)(tempebx >> 16);
-  temp = tempbx & 0x00FF;
-  temp <<= 4;
-  temp |= ((tempcx & 0xFF00) >> 8);
+  temp = (USHORT)((tempeax >> 12) & 0x70); /* sic! */
+  temp |= (tempcx & 0x4F);
   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
 
   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
 
+     /* Calc Linebuffer max address and set/clear decimode */
      tempbx = 0;
+     if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
      tempax = SiS_Pr->SiS_VGAHDE;
-     if(modeflag & HalfDCLK)           tempax >>= 1;
+     if(modeflag & HalfDCLK)            tempax >>= 1;
      if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-       if(tempax > 800) tempax -= 800;
-     } else {
-        if(tempax > 800) {
-          tempbx = 8;
-           if(tempax == 1024)
-             tempax *= 25;
-           else
-             tempax *= 20;
-
+     if(tempax > 800) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+          tempax -= 800;
+       } else {  /* 651+301C: Only if TVNoHiviNoYPbPr */
+          tempbx = 0x08;
+           if(tempax == 1024) tempax *= 25;
+           else                      tempax *= 20;
           temp = tempax % 32;
-          tempax /= 32;
-          tempax--;
-          if (temp!=0) tempax++;
-        }
+          tempax /= 32;
+          if(temp) tempax++;
+          tempax++;
+          if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) ||
+             (SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
+             if(resinfo == SIS_RI_1024x768) {
+                /* Otherwise white line at right edge */
+                tempax = (tempax & 0xff00) | 0x20;
+             }
+          }
+       }
      }
      tempax--;
-     temp = ((tempax & 0xFF00) >> 8) & 0x03;
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                    /* From 1.10.7w */
-       if(ModeNo > 0x13) {                                     /* From 1.10.7w */
-          if(resinfo == SIS_RI_1024x768) tempax = 0x1f;        /* From 1.10.7w */
-       }                                                       /* From 1.10.7w */
-     }                                                         /* From 1.10.7w */
-     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
-     temp <<= 4;
-     temp |= tempbx;
+     temp = ((tempax >> 4) & 0x30) | tempbx;
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
 
-     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-       if(IS_SIS550650740660) {
-          temp = 0x0026;  /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
-       } else {
-          temp = 0x0036;
-       }
-     } else {
-       temp = 0x0036;
+     temp = 0x0036; tempbx = 0xD0;
+     if((IS_SIS550650740660) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+       temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
      }
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
         if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
           temp |= 0x01;
           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
              if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
-                temp &= 0xFE;
+                temp &= ~0x01;
              }
           }
        }
      }
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
 
-     tempbx = SiS_Pr->SiS_HT;
+     tempbx = SiS_Pr->SiS_HT >> 1;
      if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
-     tempbx >>= 1;
      tempbx -= 2;
-     temp = ((tempbx & 0x0700) >> 8) << 3;
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
+     temp = (tempbx >> 5) & 0x38;
      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
-     temp = tempbx & 0x00FF;
-     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,temp);
 
      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
@@ -8562,13 +7737,13 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
              SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
           }
        }
-#ifdef SET_EMI
        if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
           SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+#ifdef SET_EMI
           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+#endif
           SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
        }
-#endif
      }
 
   }  /* 301B */
@@ -8580,7 +7755,6 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*         SET PART 5 REGISTER GROUP         */
 /*********************************************/
 
-/* Set 301 Palette address port registers */
 static void
 SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
               PSIS_HW_INFO HwInfo)
@@ -8590,7 +7764,7 @@ SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
   if(SiS_Pr->SiS_ModeType == ModeVGA) {
      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
-        SiS_EnableCRT2(SiS_Pr);
+        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
         SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
      }
   }
@@ -8608,11 +7782,8 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   USHORT ResIndex,DisplayType;
   const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
 
-  if(ModeNo <= 0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  } else {
-     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-  }
+  if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
@@ -8620,7 +7791,9 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      return;
 
   if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
-                          &ResIndex, &DisplayType))) return;
+                          &ResIndex, &DisplayType))) {
+     return;
+  }
 
   if(HwInfo->jChipType < SIS_315H) {
      if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
@@ -8628,16 +7801,16 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
   switch(DisplayType) {
     case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1;           break;
-    case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
-    case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1;         break;
-    case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H;         break;
-    case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H;        break;
-    case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H;       break;
-    case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2;           break;
-    case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2;          break;
-    case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2;         break;
-    case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H;         break;
-    case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H;        break;
+    case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H;         break;
+    case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2;           break;
+    case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H;         break;
+    case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
+    case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H;        break;
+    case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2;          break;
+    case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H;        break;
+    case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1;         break;
+    case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H;       break;
+    case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2;         break;
     case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H;       break;
     case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1;           break;
     case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H;         break;
@@ -8676,7 +7849,7 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
     default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
   }
 
-  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                        /*unlock cr0-7  */
+  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
 
   tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
   SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
@@ -8711,12 +7884,6 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   tempah <<= 5;
   if(modeflag & DoubleScanMode)  tempah |= 0x080;
   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
-
-  /* 650/LVDS BIOS - doesn't make sense */
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-     if(modeflag & HalfDCLK)
-        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
-  }
 }
 
 /*********************************************/
@@ -8731,7 +7898,7 @@ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   USHORT clkbase, vclkindex=0;
   UCHAR  sr2b, sr2c;
 
-  if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) {
+  if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) || (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
        SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
         if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
           RefreshRateTableIndex--;
@@ -8748,7 +7915,7 @@ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
 
   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-     if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+     if(SiS_Pr->SiS_UseROM) {
        if(ROMAddr[0x220] & 0x01) {
            sr2b = ROMAddr[0x227];
           sr2c = ROMAddr[0x228];
@@ -8763,7 +7930,6 @@ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      }
   }
 
-  SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
@@ -8783,14 +7949,17 @@ static void
 SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                USHORT RefreshRateTableIndex)
 {
-  USHORT temp, tempbx, tempcl;
+#if defined(SIS300) || defined(SIS315H)
+  USHORT temp, tempbx;
+#endif
+  USHORT tempcl;
   USHORT TVType, resindex;
   const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
 
   if(ModeNo <= 0x13)
-       tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+     tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   else
-       tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+     tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 
   TVType = 0;
   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
@@ -8808,16 +7977,16 @@ SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
        }
   }
   switch(TVType) {
-       case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
-       case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
-       case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
-       case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
-       case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
-       case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
-       case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
-       case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
-       case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
-       default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
+     case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
+     case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
+     case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
+     case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
+     case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
+     case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
+     case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
+     case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
+     case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
+     default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
   }
   resindex = tempcl & 0x3F;
 
@@ -9089,21 +8258,21 @@ SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
   /* Set up Power up/down timing */
 
   if(HwInfo->jChipType == SIS_740) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
         if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
         else                                     tableptr = table1024_740;
-     } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
-              (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
+     } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
+               (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
+              (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
        if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
         else                                     tableptr = table1400_740;
      } else return;
   } else {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
         tableptr = table1024_650;
-     } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
-              (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
+     } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
+               (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
+              (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
         tableptr = table1400_650;
      } else return;
   }
@@ -9139,45 +8308,35 @@ SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
   int i;
 
   if(HwInfo->jChipType == SIS_740) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-        tableptr = table1024_740;
-     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-        tableptr = table1280_740;
-     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-        tableptr = table1400_740;
-     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-        tableptr = table1600_740;
-     } else return;
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_740;
+     else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
+     else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
+     else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
+     else return;
   } else {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-        tableptr = table1024_650;
-     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-        tableptr = table1280_650;
-     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-        tableptr = table1400_650;
-     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-        tableptr = table1600_650;
-     } else return;
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_650;
+     else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
+     else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
+     else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
+     else return;
   }
 
   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
      tempbh = SiS_GetCH701x(SiS_Pr,0x73);
      if(tempbh == 0xc8) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) return;
+        if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
      } else if(tempbh == 0xdb) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) return;
-       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
+        if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
+       if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
      } else if(tempbh == 0xde) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) return;
+        if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
      }
   }
 
-  if(HwInfo->jChipType == SIS_740) {
-     tempbh = 0x0d;
-  } else {
-     tempbh = 0x0c;
-  }
+  if(HwInfo->jChipType == SIS_740) tempbh = 0x0d;
+  else                            tempbh = 0x0c;
+
   for(i = 0; i < tempbh; i++) {
      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
   }
@@ -9564,13 +8723,12 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 
    SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
 
-   /* Set up Panel Link for LVDS, 301BDH and 30xLV(for LCDA) */
+   /* Set up Panel Link for LVDS and LCDA */
+   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
    if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
        ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
        ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
       SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-   } else {
-      SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
    }
 
 #ifdef LINUX_XF86
@@ -9598,13 +8756,15 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
           SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
           SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
 #ifdef SIS315H
-          SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo);
+          SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
 #endif
           SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
 
+          SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+
           /* For 301BDH (Panel link initialization): */
           if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-             if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+             if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
                 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
                    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
                       SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
@@ -9619,15 +8779,13 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 
    } else {
 
-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-          if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
-             SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
-                             RefreshRateTableIndex,HwInfo);
-          }
+        SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+
+        if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+          SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
        }
 
-        SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
-                       RefreshRateTableIndex,HwInfo);
+        SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
 
        if(SiS_Pr->SiS_SetFlag & LowModeTests) {
           if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
@@ -9639,8 +8797,7 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
                 }
              }
              if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-                        SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,
-                              RefreshRateTableIndex);
+                        SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
              }
           }
        }
@@ -9651,7 +8808,7 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
    if(HwInfo->jChipType < SIS_315H) {
       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
         if(SiS_Pr->SiS_UseOEM) {
-           if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
+           if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
               if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
                  SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
                                    RefreshRateTableIndex);
@@ -9684,13 +8841,11 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
         if(HwInfo->jChipType < SIS_661) {
            SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
-            if(SiS_Pr->SiS_UseOEM) {
-               SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
-            }
+            SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
         } else {
            SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
         }
-         SiS_CRT2AutoThreshold(SiS_Pr);
+         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
       }
    }
 #endif
@@ -9761,6 +8916,63 @@ SiS_SetupDDCN(SiS_Private *SiS_Pr)
   }
 }
 
+#ifdef SIS300
+static UCHAR *
+SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
+{
+  int i, j, num;
+  USHORT tempah,temp;
+  UCHAR *mydataptr;
+
+  for(i=0; i<20; i++) {                                /* Do 20 attempts to write */
+     mydataptr = dataptr;
+     num = *mydataptr++;
+     if(!num) return mydataptr;
+     if(i) {
+        SiS_SetStop(SiS_Pr);
+       SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT*2);
+     }
+     if(SiS_SetStart(SiS_Pr)) continue;                /* Set start condition */
+     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);  /* Write DAB (S0=0=write) */
+     if(temp) continue;                                /*    (ERROR: no ack) */
+     tempah = *mydataptr++;
+     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);  /* Write register number */
+     if(temp) continue;                                /*    (ERROR: no ack) */
+     for(j=0; j<num; j++) {
+        tempah = *mydataptr++;
+        temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
+       if(temp) break;
+     }
+     if(temp) continue;
+     if(SiS_SetStop(SiS_Pr)) continue;
+     return mydataptr;
+  }
+  return NULL;
+}
+
+static BOOLEAN
+SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
+{
+  SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;           /* DAB (Device Address Byte) */
+  SiS_Pr->SiS_DDC_Index = 0x11;                        /* Bit 0 = SC;  Bit 1 = SD */
+  SiS_Pr->SiS_DDC_Data  = 0x02;                /* Bitmask in IndexReg for Data */
+  SiS_Pr->SiS_DDC_Clk   = 0x01;                /* Bitmask in IndexReg for Clk */
+  SiS_SetupDDCN(SiS_Pr);
+
+  SiS_SetSwitchDDC2(SiS_Pr);
+
+  while(*dataptr) {
+     dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
+     if(!dataptr) return FALSE;
+  }
+#ifdef TWDEBUG
+  xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
+#endif
+  return TRUE;
+}
+#endif
+
 /* The Chrontel 700x is connected to the 630/730 via
  * the 630/730's DDC/I2C port.
  *
@@ -9796,6 +9008,20 @@ SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor)
   return FALSE;
 }
 
+#ifdef SIS300
+/* Write Trumpion register */
+void
+SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
+{
+  SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;           /* DAB (Device Address Byte) */
+  SiS_Pr->SiS_DDC_Index = 0x11;                        /* Bit 0 = SC;  Bit 1 = SD */
+  SiS_Pr->SiS_DDC_Data  = 0x02;                /* Bitmask in IndexReg for Data */
+  SiS_Pr->SiS_DDC_Clk   = 0x01;                /* Bitmask in IndexReg for Clk */
+  SiS_SetupDDCN(SiS_Pr);
+  SiS_SetChReg(SiS_Pr, tempbx, 0);
+}
+#endif
+
 /* Write to Chrontel 700x */
 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
 void
@@ -9831,17 +9057,16 @@ SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
   SiS_SetupDDCN(SiS_Pr);
   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;           /* DAB (Device Address Byte) */
-
   SiS_SetChReg(SiS_Pr, tempbx, 0);
 }
 
 void
 SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
 {
-   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
-      SiS_SetCH700x(SiS_Pr,tempbx);
-   else
-      SiS_SetCH701x(SiS_Pr,tempbx);
+  if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+     SiS_SetCH700x(SiS_Pr,tempbx);
+  else
+     SiS_SetCH701x(SiS_Pr,tempbx);
 }
 
 static USHORT
@@ -9873,6 +9098,21 @@ SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor)
   return 0xFFFF;
 }
 
+#ifdef SIS300
+/* Read from Trumpion */
+USHORT
+SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
+{
+  SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;   /* DAB */
+  SiS_Pr->SiS_DDC_Index = 0x11;                /* Bit 0 = SC;  Bit 1 = SD */
+  SiS_Pr->SiS_DDC_Data  = 0x02;         /* Bitmask in IndexReg for Data */
+  SiS_Pr->SiS_DDC_Clk   = 0x01;         /* Bitmask in IndexReg for Clk */
+  SiS_SetupDDCN(SiS_Pr);
+  SiS_Pr->SiS_DDC_ReadAddr = tempbx;
+  return(SiS_GetChReg(SiS_Pr,0));
+}
+#endif
+
 /* Read from Chrontel 700x */
 /* Parameter is [Register no (S7-S0)] */
 USHORT
@@ -9925,10 +9165,10 @@ SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
 USHORT
 SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
 {
-   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
-      return(SiS_GetCH700x(SiS_Pr, tempbx));
-   else
-      return(SiS_GetCH701x(SiS_Pr, tempbx));
+  if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+     return(SiS_GetCH700x(SiS_Pr, tempbx));
+  else
+     return(SiS_GetCH701x(SiS_Pr, tempbx));
 }
 
 /* Our own DDC functions */
@@ -10315,6 +9555,8 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
    for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
    SiS_Pr->CP_HaveCustomData = FALSE;
    SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
+   SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
+   SiS_Pr->CP_PreferredIndex = -1;
 
    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
    if(pSiS->VBFlags & VB_30xBDH) return 0;
@@ -10409,12 +9651,14 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
         SiS_Pr->CP_PreferredY = yres;
 
          switch(xres) {
+#if 0      /* Treat as custom */
             case 800:
                if(yres == 600) {
                   paneltype = Panel_800x600;
                   checkexpand = TRUE;
                }
                break;
+#endif
             case 1024:
                if(yres == 768) {
                   paneltype = Panel_1024x768;
@@ -10452,9 +9696,11 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
 #if 0      /* Treat this as custom, as we have no valid timing data yet */
            case 1600:
                if(pSiS->VGAEngine == SIS_315_VGA) {
-                  if(yres == 1200) {
-                     paneltype = Panel310_1600x1200;
-                     checkexpand = TRUE;
+                  if(pSiS->VBFlags & VB_301C) {
+                     if(yres == 1200) {
+                        paneltype = Panel310_1600x1200;
+                        checkexpand = TRUE;
+                     }
                   }
                }
                break;
@@ -10580,6 +9826,10 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
                  if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
                  if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
 
+                 if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
+                    SiS_Pr->CP_PreferredIndex = i;
+                 }
+
                  SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
                  SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
 
@@ -10660,28 +9910,20 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
       SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
       SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
       switch(xres) {
+#if 0
          case 800:
             if(yres == 600) {
                paneltype = Panel_800x600;
                checkexpand = TRUE;
             }
             break;
+#endif
          case 1024:
             if(yres == 768) {
                paneltype = Panel_1024x768;
                checkexpand = TRUE;
             }
             break;
-        case 1152:
-            if(yres == 768) {
-               if(pSiS->VGAEngine == SIS_300_VGA) {
-                  paneltype = Panel300_1152x768;
-               } else {
-                  paneltype = Panel310_1152x768;
-               }
-               checkexpand = TRUE;
-            }
-            break;
         case 1280:
             if(yres == 960) {
                if(pSiS->VGAEngine == SIS_315_VGA) {
@@ -10706,9 +9948,11 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
 #if 0    /* Treat this one as custom since we have no timing data yet */
         case 1600:
             if(pSiS->VGAEngine == SIS_315_VGA) {
-               if(yres == 1200) {
-                  paneltype = Panel310_1600x1200;
-                  checkexpand = TRUE;
+               if(pSiS->VBFlags & VB_301C) {
+                  if(yres == 1200) {
+                     paneltype = Panel310_1600x1200;
+                     checkexpand = TRUE;
+                  }
                }
             }
             break;
@@ -10810,6 +10054,10 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
 
               if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
 
+              if((SiS_Pr->CP_MaxX == xres) && (SiS_Pr->CP_MaxY == yres)) {
+                 SiS_Pr->CP_PreferredIndex = i;
+              }
+
               SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
               SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
               SiS_Pr->CP_SyncValid[i] = TRUE;
@@ -10864,14 +10112,18 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
    if(paneltype) {
        if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
        if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
-       cr37 &= 0xf1;
-       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x36,0xf0,paneltype);
-       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0xf1,cr37);
        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
+       SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,paneltype);
+       cr37 &= 0xf1;
+       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0x0c,cr37);
+       SiS_Pr->PanelSelfDetected = TRUE;
 #ifdef TWDEBUG
        xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3, 
-               "CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
+                  "CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
 #endif 
+   } else {
+       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
+       SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,0x00);
    }
    return 0;
 }
@@ -11148,13 +10400,13 @@ GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
   USHORT romptr;
 
   if(HwInfo->jChipType < SIS_330) {
-     romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);
+     romptr = SISGETROMW(0x128);
      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
-        romptr = ROMAddr[0x12a] | (ROMAddr[0x12b] << 8);
+        romptr = SISGETROMW(0x12a);
   } else {
-     romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);
+     romptr = SISGETROMW(0x1a8);
      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
-        romptr = ROMAddr[0x1aa] | (ROMAddr[0x1ab] << 8);
+        romptr = SISGETROMW(0x1aa);
   }
   return(romptr);
 }
@@ -11166,13 +10418,13 @@ GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
   USHORT romptr;
 
   if(HwInfo->jChipType < SIS_330) {
-     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
+     romptr = SISGETROMW(0x120);
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
-        romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
+        romptr = SISGETROMW(0x122);
   } else {
-     romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);
+     romptr = SISGETROMW(0x1a0);
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
-        romptr = ROMAddr[0x1a2] | (ROMAddr[0x1a3] << 8);
+        romptr = SISGETROMW(0x1a2);
   }
   return(romptr);
 }
@@ -11184,13 +10436,13 @@ GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
   USHORT romptr;
 
   if(HwInfo->jChipType < SIS_330) {
-     romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8);
+     romptr = SISGETROMW(0x114);
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
-        romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8);
+        romptr = SISGETROMW(0x11a);
   } else {
-     romptr = ROMAddr[0x194] | (ROMAddr[0x195] << 8);
+     romptr = SISGETROMW(0x194);
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
-        romptr = ROMAddr[0x19a] | (ROMAddr[0x19b] << 8);
+        romptr = SISGETROMW(0x19a);
   }
   return(romptr);
 }
@@ -11212,9 +10464,9 @@ GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
      }
   }
 
-  index = SiS_Pr->SiS_LCDResInfo & 0x0F;
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)      index -= 5;
-  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) index -= 6;
+  index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
+  if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)      index -= 5;
+  else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
   index--;
   index *= 3;
   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
@@ -11227,12 +10479,9 @@ GetLCDPtrIndex(SiS_Private *SiS_Pr)
 {
   USHORT index;
 
-  index = SiS_Pr->SiS_LCDResInfo & 0x0F;
-  index--;
-  index *= 3;
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
+  index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         index += 2;
   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
-
   return index;
 }
 
@@ -11258,7 +10507,7 @@ GetTVPtrIndex(SiS_Private *SiS_Pr)
 }
 
 static ULONG
-GetOEMTVPtr661_2(SiS_Private *SiS_Pr)
+GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
 {
    USHORT index = 0, temp = 0;
 
@@ -11275,7 +10524,7 @@ GetOEMTVPtr661_2(SiS_Private *SiS_Pr)
    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
       if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
-        index += 8;
+        index += addme;
         temp++;
       }
       temp += 0x0100;
@@ -11283,16 +10532,37 @@ GetOEMTVPtr661_2(SiS_Private *SiS_Pr)
    return(ULONG)(index | (temp << 16));
 }
 
+static ULONG
+GetOEMTVPtr661_2_OLD(SiS_Private *SiS_Pr)
+{
+   return(GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
+}
+
+#if 0
+static ULONG
+GetOEMTVPtr661_2_NEW(SiS_Private *SiS_Pr)
+{
+   return(GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
+}
+#endif
+
 static int
 GetOEMTVPtr661(SiS_Private *SiS_Pr)
 {
    int index = 0;
 
-   if(SiS_Pr->SiS_TVMode & TVSetPAL)       index = 2;
-   if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
-   if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
-   if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
-   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
+   if(SiS_Pr->SiS_TVMode & TVSetPAL)          index = 2;
+   if(SiS_Pr->SiS_ROMNew) {
+      if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
+      if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
+      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
+      if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 10;
+   } else {
+      if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
+      if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
+      if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
+      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
+   }
 
    if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
 
@@ -11306,15 +10576,21 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
   USHORT delay=0,index,myindex,temp,romptr=0;
   BOOLEAN dochiptest = TRUE;
 
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
+  } else {
+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
+  }
+
   /* Find delay (from ROM, internal tables, PCI subsystem) */
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {                   /* ------------ VGA */
      
-     if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+     if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
         romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
-       if(!romptr) return;
-       delay = ROMAddr[romptr];
-     else {
+     }
+     if(romptr) delay = ROMAddr[romptr];
+     else {
         delay = 0x04;
         if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
           if(IS_SIS650) {
@@ -11326,8 +10602,7 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
           } else {
              delay = 0x0c;
           }
-       }
-        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+       } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
            delay = 0x00;
        }
      }
@@ -11336,13 +10611,39 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 
      BOOLEAN gotitfrompci = FALSE;
 
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+     /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
 
-     /* Could we detect a PDC for LCD? If yes, use it */
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+       if(SiS_Pr->PDC != -1) {
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
+          return;
+       }
+     } else {
+       if(SiS_Pr->PDCA != -1) {
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
+          return;
+       }
+     }
+
+     /* Custom Panel? */
 
-     if(SiS_Pr->PDC) {
+     if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDC & 0x0f) << 4));
+          delay = 0x00;
+          if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
+             delay = 0x20;
+          }
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
+       } else {
+          delay = 0x0c;
+          if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x03;
+          else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+             if(IS_SIS740) delay = 0x01;
+             else          delay = 0x03;
+          }
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
        }
         return;
      }
@@ -11355,7 +10656,7 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
      switch(SiS_Pr->SiS_CustomT) {
      case CUT_COMPAQ1280:
      case CUT_COMPAQ12802:
-       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+       if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
           gotitfrompci = TRUE;
           dochiptest = FALSE;
           delay = 0x03;
@@ -11363,15 +10664,13 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
        break;
      case CUT_CLEVO1400:
      case CUT_CLEVO14002:
-       /* if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { */
-          gotitfrompci = TRUE;
-          dochiptest = FALSE;
-          delay = 0x02;
-       /* } */
+       gotitfrompci = TRUE;
+       dochiptest = FALSE;
+       delay = 0x02;
        break;
      case CUT_CLEVO1024:
      case CUT_CLEVO10242:
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
           gotitfrompci = TRUE;
           dochiptest = FALSE;
           delay = 0x33;
@@ -11392,12 +10691,12 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 
            if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) {
 
-              if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+              if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
                 /* Always use the second pointer on 650; some BIOSes */
                  /* still carry old 301 data at the first location    */
-                /* romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);  */
+                /* romptr = SISGETROMW(0x120);                       */
                 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
-                romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
+                romptr = SISGETROMW(0x122);
                 if(!romptr) return;
                 delay = ROMAddr[(romptr + index)];
              } else {
@@ -11412,10 +10711,13 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 
           }
 
-        } else if((ROMAddr) && SiS_Pr->SiS_UseROM &&
-                 (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) {
+        } else if(SiS_Pr->SiS_UseROM                         &&
+                 (!(SiS_Pr->SiS_ROMNew))                     &&
+                 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
+                 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768)  &&
+                 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)) {
 
-          /* Data for 1280x1024 wrong in BIOS */
+          /* Data for 1280x1024 wrong in 301B BIOS */
            romptr = GetLCDromptr(SiS_Pr, HwInfo);
           if(!romptr) return;
           delay = ROMAddr[(romptr + index)];
@@ -11430,7 +10732,11 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
            delay = SiS310_LCDDelayCompensation_301[myindex];
           if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
              if(IS_SIS740) delay = 0x01;
+             else if(HwInfo->jChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
              else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];
+          } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+             if(IS_SIS740) delay = 0x01;  /* ? */
+             else          delay = 0x03;
           } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
              if(IS_SIS740) delay = 0x01;
              else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
@@ -11453,12 +10759,12 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 
         if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
 
-           if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+           if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
              /* Always use the second pointer on 650; some BIOSes */
               /* still carry old 301 data at the first location    */
-              /* romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8);  */
-             /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
-             romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8);
+              /* romptr = SISGETROMW(0x114);                      */
+             /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
+             romptr = SISGETROMW(0x11a);
              if(!romptr) return;
              delay = ROMAddr[romptr + index];
 
@@ -11491,7 +10797,7 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
           }
         }
 
-     } else if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+     } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
 
         romptr = GetTVromptr(SiS_Pr, HwInfo);
        if(!romptr) return;
@@ -11507,14 +10813,16 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
           if(IS_SIS740) {
              delay = SiS310_TVDelayCompensation_740301B[index];
+             /* LV: use 301 data? BIOS bug? */
           } else {
               delay = SiS310_TVDelayCompensation_301B[index];
+             if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
           }
        }
 
      }
 
-     if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) {  /* LCDA */
+     if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
        delay &= 0x0f;
        dochiptest = FALSE;
      }
@@ -11580,15 +10888,18 @@ SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   temp >>= 1;            /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
   temp1 = temp;
 
-  if(ROMAddr && SiS_Pr->SiS_UseROM) {
+  if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
      if(HwInfo->jChipType >= SIS_661) {
-       romptr = ROMAddr[0x260] | (ROMAddr[0x261] << 8);
-       temp1 = GetOEMTVPtr661(SiS_Pr);
+        temp1 = GetOEMTVPtr661(SiS_Pr);
         temp1 >>= 1;
+        romptr = SISGETROMW(0x260);
+        if(HwInfo->jChipType >= SIS_760) {
+          romptr = SISGETROMW(0x360);
+       }
      } else if(HwInfo->jChipType >= SIS_330) {
-        romptr = ROMAddr[0x192] | (ROMAddr[0x193] << 8);
+        romptr = SISGETROMW(0x192);
      } else {
-        romptr = ROMAddr[0x112] | (ROMAddr[0x113] << 8);
+        romptr = SISGETROMW(0x112);
      }
   }
 
@@ -11610,24 +10921,25 @@ SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp,temp1,romptr=0;
 
-  temp = GetTVPtrIndex(SiS_Pr);
-  temp >>= 1;                  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
-  temp1 = temp;
+  temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1;   /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
 
-  if(ModeNo<=0x13)
+  if(ModeNo <= 0x13)
      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
   else
      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
 
-  if(ROMAddr && SiS_Pr->SiS_UseROM) {
+  if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
      if(HwInfo->jChipType >= SIS_661) {
-       romptr = ROMAddr[0x26c] | (ROMAddr[0x26d] << 8);
+        romptr = SISGETROMW(0x26c);
+        if(HwInfo->jChipType >= SIS_760) {
+          romptr = SISGETROMW(0x36c);
+       }
        temp1 = GetOEMTVPtr661(SiS_Pr);
         temp1 >>= 1;
      } else if(HwInfo->jChipType >= SIS_330) {
-        romptr = ROMAddr[0x1a4] | (ROMAddr[0x1a5] << 8);
+        romptr = SISGETROMW(0x1a4);
      } else {
-        romptr = ROMAddr[0x124] | (ROMAddr[0x125] << 8);
+        romptr = SISGETROMW(0x124);
      }
   }
 
@@ -11645,62 +10957,15 @@ static void
 SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
            USHORT ModeNo,USHORT ModeIdIndex)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT index, myindex, oldindex,temp, i, j, flag1 = 0, flag2 = 0, romptr = 0;
-  ULONG  lindex;
+  USHORT index, temp, i, j;
 
-  if(ModeNo<=0x13) {
-    index =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
+  if(ModeNo <= 0x13) {
+     index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
   } else {
-    index =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
-  }
-
-  oldindex = index;
-
-  if((HwInfo->jChipType >= SIS_661) && ROMAddr && SiS_Pr->SiS_UseROM) {
-     if(ModeNo > 0x13) {
-        index =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndexROM661;
-     }
-     lindex = GetOEMTVPtr661_2(SiS_Pr);
-     if(lindex & 0x00ff0000) flag1 = 1;
-     if(lindex & 0xff000000) flag2 = 1;
-     lindex &= 0xffff;
-
-     /* NTSC-J: Use PAL filters */
-     if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) lindex = 1;
-
-     romptr = ROMAddr[0x268] | (ROMAddr[0x269] << 8);
-     if(flag1) myindex = index * 7;
-     else      myindex = index << 2;
-
-     if(romptr) {
-        romptr += (lindex << 1);
-        romptr = (ROMAddr[romptr] | (ROMAddr[romptr+1] << 8)) + myindex;
-       if(romptr) {
-           if((!flag1) && (flag2)) {
-             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,0x00);
-             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,0x00);
-             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,0x00);
-             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,ROMAddr[romptr++]);
-           } else {
-             for(i=0x35; i<=0x38; i++) {
-                 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr++]);
-              }
-           }
-           if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-             for(j=0, i=0x48; i<=0x4a; i++, j++) {
-                 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr++]);
-              }
-           }
-           return;
-       }
-     }
+     index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
   }
 
-  index = oldindex;
-
-  temp = GetTVPtrIndex(SiS_Pr);
-  temp >>= 1;                          /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
+  temp = GetTVPtrIndex(SiS_Pr) >> 1;  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
 
   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)       temp = 1;  /* NTSC-J uses PAL */
   else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */
@@ -11734,21 +10999,11 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   /* NTSC-J data not in BIOS, and already set in SetGroup2 */
   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
 
-  if(HwInfo->jChipType >= SIS_661) {
-     lindex = GetOEMTVPtr661_2(SiS_Pr) & 0xffff;
+  if((HwInfo->jChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
+     lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
      lindex <<= 2;
-     if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-        romptr = ROMAddr[0x264] | (ROMAddr[0x265] << 8);
-     }
-     if(romptr) {
-       romptr += lindex;
-       for(j=0, i=0x31; i<=0x34; i++, j++) {
-           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
-        }
-     } else {
-        for(j=0, i=0x31; i<=0x34; i++, j++) {
-           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
-        }
+     for(j=0, i=0x31; i<=0x34; i++, j++) {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
      }
      return;
   }
@@ -11766,20 +11021,20 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,
    * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text
    */
-  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-     romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
+  if(SiS_Pr->SiS_UseROM) {
+     romptr = SISGETROMW(0x116);
      if(HwInfo->jChipType >= SIS_330) {
-        romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
+        romptr = SISGETROMW(0x196);
      }
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-        romptr = ROMAddr[0x11c] | (ROMAddr[0x11d] << 8);
+        romptr = SISGETROMW(0x11c);
        if(HwInfo->jChipType >= SIS_330) {
-          romptr = ROMAddr[0x19c] | (ROMAddr[0x19d] << 8);
+          romptr = SISGETROMW(0x19c);
        }
        if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
-          romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
+          romptr = SISGETROMW(0x116);
           if(HwInfo->jChipType >= SIS_330) {
-              romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
+              romptr = SISGETROMW(0x196);
            }
        }
      }
@@ -11832,7 +11087,7 @@ SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
       SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
       SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
       SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
-      if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+      if(SiS_Pr->SiS_VBType & VB_SIS301) {
          SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
       }
    }
@@ -11842,65 +11097,108 @@ static void
 SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
                 USHORT ModeIdIndex, USHORT RTI)
 {
-   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
    USHORT delay = 0, romptr = 0, index;
-   UCHAR  *myptr = NULL;
-   UCHAR  temp;
+   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
 
    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
       return;
 
-   delay = SiS_Pr->SiS_RefIndex[RTI].Ext_PDC;
+   /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
+
+   if(SiS_Pr->SiS_ROMNew) {
+      if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)                        ||
+         ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
+         (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+         index = 25;
+         if(SiS_Pr->UseCustomMode) {
+           index = SiS_Pr->CSRClock;
+         } else if(ModeNo > 0x13) {
+            index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI,HwInfo);
+            index = SiS_Pr->SiS_VCLKData[index].CLOCK;
+         }
+        if(index < 25) index = 25;
+         index = ((index / 25) - 1) << 1;
+         if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
+           index++;
+        }
+        romptr = SISGETROMW(0x104);  /* 0x4ae */
+         delay = ROMAddr[romptr + index];
+         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
+         } else {
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
+         }
+         return;
+      }
+   }
+
+   /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
 
-   delay &= 0xf0;
-   delay >>= 4;
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) delay <<= 12;  /* BIOS: 8, wrong */
+   if(SiS_Pr->UseCustomMode) delay = 0x04;
+   else if(ModeNo <= 0x13)   delay = 0x04;
+   else                      delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
+   delay |= (delay << 8);
 
    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+
+      /* 3. TV */
+
       index = GetOEMTVPtr661(SiS_Pr);
-      if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-         romptr = ROMAddr[0x25c] | (ROMAddr[0x25d] << 8);
-         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-            romptr = ROMAddr[0x25e] | (ROMAddr[0x25f] << 8);
-         }
-      }
-      if(romptr) myptr = &ROMAddr[romptr];
-      if(!myptr) {
-         myptr = (UCHAR *)SiS_TVDelay661_301;
-        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-           myptr = (UCHAR *)SiS_TVDelay661_301B;
-        }
+      if(SiS_Pr->SiS_ROMNew) {
+         romptr = SISGETROMW(0x106);  /* 0x4ba */
+         delay = ROMAddr[romptr + index];
+      } else {
+         delay = 0x04;
       }
-      delay = myptr[index];
-      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) delay >>= 4;  /* Should test dual edge */
+
    } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-      if(SiS_Pr->PDC) {
-         delay = SiS_Pr->PDC & 0x0f;
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-            delay |= (delay << 12);
+
+      /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
+
+      if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
+          ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
+
+        /* For LV, the BIOS must know about the correct value */
+        delay = ROMAddr[romptr + 0x0d];                /* LCD  */
+        delay |= (ROMAddr[romptr + 0x0c] << 8);        /* LCDA */
+
+      } else {
+
+         /* TMDS: Set our own, since BIOS has no idea - TODO: Find out about values */
+         if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+            if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
+              delay = 0x0404;
+            } else if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
+              delay = 0x0404;
+            } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
+              delay = 0x1004;
+            } else
+              delay = 0x0000;
+         }
+
+        /* Override by detected or user-set values */
+        /* (but only if, for some reason, we can't read value from BIOS) */
+         if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
+            delay = SiS_Pr->PDC & 0x1f;
          }
-      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) {
-         delay = 0x4444;  /* TEST THIS */
-      } else if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-         myptr = GetLCDStructPtr661(SiS_Pr, HwInfo);
-         if(myptr) delay = myptr[4];
-         else delay = 0x44;
-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-            delay |= (delay << 8);
+         if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
+            delay = (SiS_Pr->PDCA & 0x1f) << 8;
          }
+
       }
-   }
 
-   temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2d);
-   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToRAMDAC)) {
-      temp &= 0xf0;
-      temp |= (delay & 0x000f);
    }
+
    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-      temp &= 0x0f;
-      temp |= ((delay & 0xf000) >> 8);
+      delay >>= 8;
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
+   } else {
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
    }
-   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,temp);
 }
 
 static void
@@ -11909,38 +11207,50 @@ SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, US
    USHORT infoflag;
    UCHAR temp;
 
-   infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
-   if(ModeNo <= 0x13) {
-      infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
-   }
-   infoflag &= 0xc0;
    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+
+      if(ModeNo <= 0x13) {
+         infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
+      } else if(SiS_Pr->UseCustomMode) {
+         infoflag = SiS_Pr->CInfoFlag;
+      } else {
+         infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
+      }
+      infoflag &= 0xc0;
+
       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
-      if(temp & 0x20) infoflag = temp;
+      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+         temp &= 0x3f;
+        temp |= infoflag;
+      } else {
+         if(temp & 0x20) infoflag = temp;
+      }
       if(temp & 0x01) infoflag |= 0x01;
-   }
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-      temp = 0x0c;
-      if(infoflag & 0x01) temp ^= 0x14;  /* BIOS: 18, wrong */
-      temp |= (infoflag >> 6);
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
-   }
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-      temp = 0;
-      if(infoflag & 0x01) temp |= 0x80;
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
-      temp = 0x30;
-      if(infoflag & 0x01) temp = 0x20;
-      infoflag &= 0xc0;
-      temp |= infoflag;
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
+
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+         temp = 0x0c;
+         if(infoflag & 0x01) temp ^= 0x14;  /* BIOS: 18, wrong */
+         temp |= (infoflag >> 6);
+         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
+      } else {
+         temp = 0;
+         if(infoflag & 0x01) temp |= 0x80;
+         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
+         temp = 0x30;
+         if(infoflag & 0x01) temp = 0x20;
+         infoflag &= 0xc0;
+         temp |= infoflag;
+         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
+      }
+
    }
 }
 
 static void
 SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-   UCHAR *myptr;
+   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+   USHORT romptr, temp1, temp2;
 
    if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
       if(SiS_Pr->LVDSHL != -1) {
@@ -11948,16 +11258,24 @@ SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
       }
    }
 
-   myptr = GetLCDStructPtr661(SiS_Pr, HwInfo);
-   if(myptr) {
-      if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
-         if(SiS_Pr->LVDSHL == -1) {
-            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xE0,myptr[1] & 0x1f);
-        } else {
-           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xE3,myptr[1] & 0x1c);
+   if(SiS_Pr->SiS_ROMNew) {
+
+      if((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) {
+         if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
+            temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
+           temp2 = 0xfc;
+           if(SiS_Pr->LVDSHL != -1) {
+             temp1 &= 0xfc;
+             temp2 = 0xf3;
+           }
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
+         }
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+            temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
         }
       }
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0x3f,myptr[2] & 0xc0);
+
    }
 }
 
@@ -11978,7 +11296,7 @@ SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
          SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
          SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
          SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
-         if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+         if(SiS_Pr->SiS_VBType & VB_SIS301) {
             SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
          }
       }
@@ -12007,7 +11325,7 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      }
   }
 
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+  if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
   if(SiS_Pr->UseCustomMode) return;
 
   switch(SiS_Pr->SiS_CustomT) {
@@ -12037,7 +11355,7 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   }
 
   if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
         /* Maybe all panels? */
         if(SiS_Pr->LVDSHL == -1) {
            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
@@ -12048,7 +11366,7 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
   if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
           if(SiS_Pr->LVDSHL == -1) {
              /* Maybe all panels? */
               SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
@@ -12068,15 +11386,15 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   }
 
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-#ifdef SET_EMI
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
        if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
           SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+#ifdef SET_EMI
           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+#endif
           SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
        }
-#endif
-     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+     } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
         if(SiS_Pr->LVDSHL == -1) {
            /* Maybe ACER only? */
            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
@@ -12084,9 +11402,9 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      }
      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+       if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
-       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+       } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
           if(tempch == 0x03) {
              SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
              SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
@@ -12167,7 +11485,7 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
        tempbh >>= 4;
        tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
        tempbx = (tempbh << 8) | tempbl;
-       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
           if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
              if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
                 tempbx = 770;
@@ -12258,19 +11576,16 @@ GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
 
     tempbx = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
     }
-    if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+    if(SiS_Pr->SiS_UseROM) {
        if(ROMAddr[0x235] & 0x80) {
           tempbx = SiS_Pr->SiS_LCDTypeInfo;
           if(Flag) {
-            romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
-            if(romptr) {
-               tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
-            } else {
-               tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
-            }
+            romptr = SISGETROMW(0x255);
+            if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
+            else       tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
              if(tempbx == 0xFF) return 0xFFFF;
           }
          tempbx <<= 1;
@@ -12281,13 +11596,10 @@ GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
   } else {
 
     if(Flag) {
-       if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-          romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
-         if(romptr) {
-            tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
-         } else {
-            tempbx = 0xff;
-         }
+       if(SiS_Pr->SiS_UseROM) {
+          romptr = SISGETROMW(0x255);
+         if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
+         else       tempbx = 0xff;
        } else {
           tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
        }
@@ -12311,12 +11623,12 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp,romptr=0;
 
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+  if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
 
-  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+  if(SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x237] & 0x01)) return;
      if(!(ROMAddr[0x237] & 0x02)) return;
-     romptr = ROMAddr[0x24b] | (ROMAddr[0x24c] << 8);
+     romptr = SISGETROMW(0x24b);
   }
 
   /* The Panel Compensation Delay should be set according to tables
@@ -12326,7 +11638,7 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
    * Thus we don't set this if the user select a custom pdc or if
    * we otherwise detected a valid pdc.
    */
-  if(SiS_Pr->PDC) return;
+  if(SiS_Pr->PDC != -1) return;
 
   temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
 
@@ -12338,7 +11650,7 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   if(HwInfo->jChipType != SIS_300) {
      if(romptr) {
        romptr += (temp * 2);
-       romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+       romptr = SISGETROMW(romptr);
        romptr += index;
        temp = ROMAddr[romptr];
      } else {
@@ -12349,21 +11661,21 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
         }
      }
   } else {
-     if((ROMAddr) && SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
+     if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
        if(romptr) {
           romptr += (temp * 2);
-          romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+          romptr = SISGETROMW(romptr);
           romptr += index;
           temp = ROMAddr[romptr];
        } else {
           temp = SiS300_OEMLCDDelay5[temp][index];
        }
      } else {
-        if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+        if(SiS_Pr->SiS_UseROM) {
           romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
           if(romptr) {
              romptr += (temp * 2);
-             romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+             romptr = SISGETROMW(romptr);
              romptr += index;
              temp = ROMAddr[romptr];
           } else {
@@ -12386,7 +11698,7 @@ SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp;
 
-  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+  if((SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x237] & 0x01)) return;
      if(!(ROMAddr[0x237] & 0x04)) return;
      /* No rom pointer in BIOS header! */
@@ -12436,10 +11748,10 @@ SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp,romptr=0;
 
-  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+  if(SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x238] & 0x01)) return;
      if(!(ROMAddr[0x238] & 0x02)) return;
-     romptr = ROMAddr[0x241] | (ROMAddr[0x242] << 8);
+     romptr = SISGETROMW(0x241);
   }
 
   temp = GetOEMTVPtr(SiS_Pr);
@@ -12448,7 +11760,7 @@ SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 
   if(romptr) {
      romptr += (temp * 2);
-     romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+     romptr = SISGETROMW(romptr);
      romptr += index;
      temp = ROMAddr[romptr];
   } else {
@@ -12459,7 +11771,7 @@ SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
      }
   }
   temp &= 0x3c;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
 }
 
 static void
@@ -12469,10 +11781,10 @@ SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp,romptr=0;
 
-  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+  if(SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x238] & 0x01)) return;
      if(!(ROMAddr[0x238] & 0x04)) return;
-     romptr = ROMAddr[0x243] | (ROMAddr[0x244] << 8);
+     romptr = SISGETROMW(0x243);
   }
 
   temp = GetOEMTVPtr(SiS_Pr);
@@ -12481,14 +11793,14 @@ SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 
   if(romptr) {
      romptr += (temp * 2);
-     romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+     romptr = SISGETROMW(romptr);
      romptr += index;
      temp = ROMAddr[romptr];
   } else {
      temp = SiS300_OEMTVFlicker[temp][index];
   }
   temp &= 0x70;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);  /* index 0A D[6:4] */
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
 }
 
 static void
@@ -12502,10 +11814,10 @@ SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 
   if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
 
-  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+  if(SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x238] & 0x01)) return;
      if(!(ROMAddr[0x238] & 0x08)) return;
-     romptr = ROMAddr[0x245] | (ROMAddr[0x246] << 8);
+     romptr = SISGETROMW(0x245);
   }
 
   temp = GetOEMTVPtr(SiS_Pr);
@@ -12519,7 +11831,7 @@ SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   } else {
      if(romptr) {
         romptr += (temp * 2);
-       romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+       romptr = SISGETROMW(romptr);
        romptr += (index * 4);
         for(i=0x31, j=0; i<=0x34; i++, j++) {
           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
@@ -12541,10 +11853,10 @@ SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
 
-  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+  if(SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x238] & 0x01)) return;
      if(!(ROMAddr[0x238] & 0x10)) return;
-     romptr = ROMAddr[0x247] | (ROMAddr[0x248] << 8);
+     romptr = SISGETROMW(0x247);
   }
 
   temp = GetOEMTVPtr(SiS_Pr);
@@ -12565,7 +11877,7 @@ SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   } else {
       if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
          romptr += (temp * 2);
-        romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+        romptr = SISGETROMW(romptr);
         romptr += (index * 4);
         for(i=0x35, j=0; i<=0x38; i++, j++) {
                    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
index 62bf8df..72a3379 100644 (file)
@@ -1,4 +1,5 @@
 /* $XFree86$ */
+/* $XdotOrg$ */
 /*
  * Data and prototypes for init301.c
  *
  * * 2) Redistributions in binary form must reproduce the above copyright
  * *    notice, this list of conditions and the following disclaimer in the
  * *    documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * *    must display the following acknowledgement: "This product includes
- * *    software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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,
@@ -91,29 +89,41 @@ const UCHAR SiS_YPbPrTable[3][64] = {
     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
     0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
     0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
-    0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
-    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x53,
+    0x03,0x0a,0x65,0x9d /*0x8d*/,0x08,0x92,0x8f,0x40,
+    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x53 /*0x50*/,
     0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
   },
   {
     0x1d,0x11,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
     0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
-    0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,
+    0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4c /*0x4f*/,0x13,
     0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
-    0x51,0x5e,0x60,0x49,0x7d,0x92,0x0f,0x40,
+    0x51,0x5e,0x60,0x57 /*0x49*/,0x7b /*0x7d*/,0x92,0x0f,0x40,
     0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4b,
     0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00
   },
   {
+#if 1
     0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
     0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
-    0xed,0x50,0x70,0x9f,0x16,0x59,0x2b,0x13,
+    0xed,0x50,0x70,0x9f,0x16,0x59,0x21 /*0x2b*/,0x13,
     0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
-    0x4b,0x4b,0x6f,0x2f,0x63,0x92,0x0f,0x40,
+    0x4b,0x4b,0x65 /*0x6f*/,0x2f,0x63,0x92,0x0f,0x40,
     0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27,
     0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
+#endif
+#if 0
+    0x2a,0x14,0xe8,0x09,0x09,0xed,0x0c,0x0c,  /* TEST (0.93) - BAD */
+    0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
+    0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
+    0xed,0x50,0x70,0x9e,0x16,0x57,0x6c,0x13,
+    0x27,0x0b,0x27,0xfb,0x30,0x27,0x15,0xb0,
+    0x3b,0xdb,0x61,0x24,0x78,0x92,0x0f,0xff,
+    0xff,0xff,0xff,0xff,0xff,0xff,0x14,0x6f,
+    0x00,0x52,0xbb,0x00,0xd5,0xf7,0xa2,0x00
+#endif
   }
 };
 
@@ -139,7 +149,7 @@ const UCHAR SiS_HiTVGroup3_2[] = {
     0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
 };
 
-/* 301C / 302ELV (?) extended Part2 TV registers */
+/* 301C / 302ELV extended Part2 TV registers */
 
 static const UCHAR SiS_Part2CLVX_1[] = {
     0x00,0x00,
@@ -208,28 +218,84 @@ static const UCHAR SiS_Part2CLVX_6[] = {   /* 1080i */
     0x00,0x04,
     0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
     0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
-    0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x1D /* 0x7D? */ ,0x7C,0x0D,0x18,0x7F,
+    0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
     0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
     0xFF,0xFF,
 };
 
-
 #ifdef SIS315H
-/* 661 et al LCD data structure */
+/* 661 et al LCD data structure (0.94.0) */
 static const UCHAR SiS_LCDStruct661[] = {
-    /* 1600x1200 */
-    0x0B,0xEA,0x81,0x10,0x00,0xC0,0x03,0x21,0x5A,0x23,0x5A,0x23,0x02,
-    0x14,0x0A,0x02,0x00,0x30,0x10,0x5A,0x10,0x10,0x0A,0xC0,0x30,0x10,
-    /* 1400x1050 */
-    0x09,0xEA,0x81,0x80,0xA3,0x70,0x03,0x19,0xD2,0x2A,0xF8,0x2F,0x02,
-    0x14,0x0A,0x02,0x00,0x30,0x10,0x5A,0x10,0x10,0x0A,0xC0,0x30,0x10,
-    /* 1280x1024 */
-    0x03,0xEA,0x81,0x40,0xA1,0x70,0x03,0x19,0xD2,0x2A,0xF8,0x2F,0x02,
-    0x14,0x0A,0x02,0x00,0x30,0x10,0x5A,0x10,0x10,0x0A,0xC0,0x30,0x10,
     /* 1024x768 */
-    0x02,0xEA,0x80,0x00,0x11,0x88,0x06,0x0B,0xF5,0x6C,0x35,0x62,0x02,
-    0x14,0x0A,0x02,0x00,0x30,0x10,0x5A,0x10,0x10,0x0A,0xC0,0x28,0x10,
-    0xFF,
+/*  type|CR37|   HDE   |   VDE   |    HT   |    VT   |   hss    | hse   */
+    0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
+    0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
+    /*  | vss      |   vse  |clck|  clock  |CRT2DataP|CRT2DataP|idx     */
+    /*                                       VESA    non-VESA  noscale */
+    /* 1280x1024 */
+    0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
+    0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08,
+    /* 1400x1050 */
+    0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
+    0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
+    /* 1600x1200 */
+    0x0B,0xC0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
+    0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0B,
+    /* 1280x768 */
+    0x0A,0xC0,0x00,0x05,0x00,0x03,0x80,0x05,0x26,0x03,0x10,0x00,0x40,
+    0x00,0x03,0x00,0x06,0x00,0x44,0x63,0x46,0x00,0x00,0x00,0x00,0x06,
+    /* 1280x720 */
+    0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x02,
+    0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
+    /* 1280x800 */
+    0x0C,0xE0,0x00,0x05,0x20,0x03,0x80,0x05,0x30,0x03,0x10,0x00,0x40,
+    0x00,0x04,0x00,0x03,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x07,
+    /* 1680x1050 */
+    0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
+    0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
+    /* 1280x768 (not in 0.93) */
+    0x0A,0xC0,0x00,0x05,0x00,0x03,0x80,0x06,0x1E,0x03,0x40,0x00,0x80,
+    0x00,0x03,0x00,0x07,0x00,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x06
+};
+#endif
+
+#ifdef SIS300
+static UCHAR SiS300_TrumpionData[7][80] = {
+  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
+    0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
+    0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
+    0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05,
+    0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 },
+  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02,
+    0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23,
+    0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23,
+    0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05,
+    0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 },
+  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
+    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
+    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
+    0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
+    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 },
+  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
+    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
+    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
+    0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
+    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
+  { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
+    0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
+    0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
+    0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
+    0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
+  { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
+    0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
+    0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
+    0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
+    0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
+  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
+    0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
+    0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
+    0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
+    0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 }
 };
 #endif
 
@@ -271,46 +337,51 @@ void      SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 void           SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 void           SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
 #endif /* 315 */
+#ifdef SIS300
+void    SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
+USHORT  SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
+static  BOOLEAN SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr);
+#endif
 
-USHORT   SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
-void     SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
-USHORT   SiS_SetStart(SiS_Private *SiS_Pr);
-USHORT   SiS_SetStop(SiS_Private *SiS_Pr);
-void     SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
-USHORT   SiS_SetSCLKLow(SiS_Private *SiS_Pr);
-USHORT   SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
-USHORT   SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT   SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT   SiS_CheckACK(SiS_Private *SiS_Pr);
+USHORT  SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
+void    SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
+USHORT  SiS_SetStart(SiS_Private *SiS_Pr);
+USHORT  SiS_SetStop(SiS_Private *SiS_Pr);
+void    SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
+USHORT  SiS_SetSCLKLow(SiS_Private *SiS_Pr);
+USHORT  SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
+USHORT  SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT  SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT  SiS_CheckACK(SiS_Private *SiS_Pr);
 
-USHORT   SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
-                         USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
-USHORT   SiS_WriteDABDDC(SiS_Private *SiS_Pr);
-USHORT   SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
-USHORT   SiS_PrepareDDC(SiS_Private *SiS_Pr);
-void     SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
-USHORT   SiS_DoProbeDDC(SiS_Private *SiS_Pr);
-USHORT   SiS_ProbeDDC(SiS_Private *SiS_Pr);
-USHORT   SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer);
-USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
-                      USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
+USHORT  SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+                        USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
+USHORT  SiS_WriteDABDDC(SiS_Private *SiS_Pr);
+USHORT  SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
+USHORT  SiS_PrepareDDC(SiS_Private *SiS_Pr);
+void    SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
+USHORT  SiS_DoProbeDDC(SiS_Private *SiS_Pr);
+USHORT  SiS_ProbeDDC(SiS_Private *SiS_Pr);
+USHORT  SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer);
+USHORT  SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+                     USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
 #ifdef LINUX_XF86
-USHORT   SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
-USHORT   SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+USHORT  SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+USHORT  SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
 #endif
 
 #ifdef SIS315H
-void     SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                           USHORT ModeNo,USHORT ModeIdIndex);
-void     SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                           USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
-void     SiS_FinalizeLCD(SiS_Private *, USHORT, USHORT, PSIS_HW_INFO);
+void    SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                          USHORT ModeNo,USHORT ModeIdIndex);
+void    SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                          USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
+void    SiS_FinalizeLCD(SiS_Private *, USHORT, USHORT, PSIS_HW_INFO);
 #endif
 #ifdef SIS300
-void     SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                           USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
-void     SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                       USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
+void    SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                          USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
+void    SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                      USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
 #endif
 
 extern void     SiS_SetReg(SISIOADDRESS, USHORT, USHORT);
@@ -338,5 +409,6 @@ extern USHORT   SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdInd
 extern void     SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO,USHORT ModeNo,
                             USHORT ModeIdIndex);
 
+extern void    SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
 
 #endif
index 5ed6548..e030d3e 100644 (file)
@@ -1,4 +1,5 @@
 /* $XFree86$ */
+/* $XdotOrg$ */
 /*
  * Global definitions for init.c and init301.c
  *
  * * 2) Redistributions in binary form must reproduce the above copyright
  * *    notice, this list of conditions and the following disclaimer in the
  * *    documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * *    must display the following acknowledgement: "This product includes
- * *    software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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,
@@ -72,6 +70,8 @@
 #define IS_SIS650740660         (IS_SIS650 || IS_SIS740 || IS_SIS661741660760)
 #define IS_SIS550650740660      (IS_SIS550 || IS_SIS650740660)
 
+#define SISGETROMW(x)          (ROMAddr[(x)] | (ROMAddr[(x)+1] << 8))
+
 /* SiS_VBType */
 #define VB_SIS301              0x0001
 #define VB_SIS301B             0x0002
@@ -85,6 +85,8 @@
 #define VB_SIS301B302B          (VB_SIS301B|VB_SIS301C|VB_SIS302B)
 #define VB_SIS301LV302LV        (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
 #define VB_SISVB               (VB_SIS301 | VB_SIS301BLV302BLV)
+#define VB_SISTMDS             (VB_SIS301 | VB_SIS301B302B)
+#define VB_SISLVDS             VB_SIS301LV302LV
 
 /* VBInfo */
 #define SetSimuScanMode         0x0001   /* CR 30 */
 #define CRT2Mode                0x0800
 #define HalfDCLK                0x1000
 #define NoSupportSimuTV         0x2000
+#define NoSupportLCDScale      0x4000 /* TMDS: No scaling possible (no matter what panel) */
 #define DoubleScanMode          0x8000
 
 /* Infoflag */
 #define SupportCHTV            0x0800
 #define Support64048060Hz       0x0800  /* Special for 640x480 LCD */
 #define SupportHiVision         0x0010
-#define SupportYPbPr            0x1000  /* TODO */
+#define SupportYPbPr750p        0x1000
 #define SupportLCD              0x0020
 #define SupportRAMDAC2          0x0040 /* All           (<= 100Mhz) */
 #define SupportRAMDAC2_135      0x0100  /* All except DH (<= 135Mhz) */
 #define TVSetPALM              0x0004
 #define TVSetPALN              0x0008
 #define TVSetCHOverScan                0x0010
-#define TVSetYPbPr525i         0x0020
-#define TVSetYPbPr525p         0x0040
-#define TVSetYPbPr750p         0x0080
-#define TVSetHiVision          0x0100  /* = 1080i, software-wise identical */
-#define TVSetTVSimuMode                0x0800
-#define TVRPLLDIV2XO           0x1000
-#define TVSetNTSC1024          0x2000
-
-/* YPbPr flag (>=315, <661) */
-#define YPbPr525p               0x0001 /* 525p */
-#define YPbPr750p               0x0002 /* 750p */
-#define YPbPr525i               0x0004 /* 525p */
-#define YPbPrHiVision           0x0008 /* HiVision or 1080i (bridge type dependent) */
+#define TVSetYPbPr525i         0x0020 /* new 0x10 */
+#define TVSetYPbPr525p         0x0040 /* new 0x20 */
+#define TVSetYPbPr750p         0x0080 /* new 0x40 */
+#define TVSetHiVision          0x0100 /* new 0x80; = 1080i, software-wise identical */
+#define TVSetTVSimuMode                0x0200 /* new 0x200, prev. 0x800 */
+#define TVRPLLDIV2XO           0x0400 /* prev 0x1000 */
+#define TVSetNTSC1024          0x0800 /* new 0x100, prev. 0x2000 */
+#define TVAspect43             0x2000
+#define TVAspect169            0x4000
+#define TVAspect43LB           0x8000
+
+/* YPbPr flag (>=315, <661; converted to TVMode) */
+#define YPbPr525p               0x0001
+#define YPbPr750p               0x0002
+#define YPbPr525i               0x0004
+#define YPbPrHiVision           0x0008
 #define YPbPrModeMask           (YPbPr750p | YPbPr525p | YPbPr525i | YPbPrHiVision)
 
 /* SysFlags (to identify special versions) */
 #define SF_IsM661              0x0020
 #define SF_IsM741              0x0040
 #define SF_IsM760              0x0080
+#define SF_760LFB              0x8000  /* 760: We have LFB */
 
 /* CR32 (Newer 630, and 315 series)
 
 #define LCDRGB18Bit           0x0001
 #define LCDNonExpanding       0x0010
 #define LCDSync               0x0020
-#define LCDPass11             0x0100
+#define LCDPass11             0x0100   /* 0: center screen, 1: Pass 1:1 data */
 #define LCDDualLink          0x0200
 
 #define DontExpandLCD        LCDNonExpanding
 #define EnablePALMN             0x40   /* Romflag: 1 = Allow PALM/PALN */
 
 /* CR39 (650 only) */
-#define LCDPass1_1             0x01   /* LVDS only; set by driver to pass 1:1 data to LVDS output  */
+#define LCDPass1_1             0x01   /* 0: center screen, 1: pass 1:1 data output  */
 #define Enable302LV_DualLink    0x04   /* 302LV only; enable dual link */
 
 /* CR39 (661 and later)
 #define Panel300_1024x600       0x06
 #define Panel300_1152x768       0x07
 #define Panel300_1280x768       0x0a
-#define Panel300_320x480        0x0e   /* fstn - TW: This is fake, can be any */
+#define Panel300_320x480        0x0e   /* fstn - This is fake, can be any */
 #define Panel300_Custom                0x0f
 #define Panel300_Barco1366      0x10
 
 #define Panel310_320x480        0x0e    /* fstn - TW: This is fake, can be any */
 #define Panel310_Custom                0x0f
 
+#define Panel661_800x600        0x01
+#define Panel661_1024x768       0x02
+#define Panel661_1280x1024      0x03
+#define Panel661_640x480        0x04
+#define Panel661_1024x600       0x05
+#define Panel661_1152x864       0x06
+#define Panel661_1280x960       0x07
+#define Panel661_1152x768       0x08
+#define Panel661_1400x1050      0x09
+#define Panel661_1280x768       0x0a
+#define Panel661_1600x1200      0x0b
+#define Panel661_1280x800       0x0c
+#define Panel661_1680x1050      0x0d
+#define Panel661_1280x720       0x0e
+#define Panel661_Custom                0x0f
+
 #define Panel_800x600           0x01   /* Unified values */
-#define Panel_1024x768          0x02
+#define Panel_1024x768          0x02    /* MUST match BIOS values from 0-e */
 #define Panel_1280x1024         0x03
 #define Panel_640x480           0x04
 #define Panel_1024x600          0x05
 #define Panel_1280x960          0x07
 #define Panel_1152x768          0x08   /* LVDS only */
 #define Panel_1400x1050         0x09
-#define Panel_1280x768          0x0a    /* LVDS only */
+#define Panel_1280x768          0x0a    /* 30xB/C and LVDS only (BIOS: all) */
 #define Panel_1600x1200         0x0b
-#define Panel_640x480_2                0x0c
-#define Panel_640x480_3                0x0d
-#define Panel_320x480           0x0e    /* fstn - TW: This is fake, can be any */
-#define Panel_Custom           0x0f
-#define Panel_Barco1366         0x10
-#define Panel_848x480          0x11
-#define Panel_1280x800         0x12    /* 661etc: 0x0c */
-#define Panel_1680x1050         0x13    /* 661etc: 0x0d */
+#define Panel_1280x800         0x0c    /* 661etc  */
+#define Panel_1680x1050         0x0d    /* 661etc  */
+#define Panel_1280x720         0x0e    /* 661etc  */
+#define Panel_Custom           0x0f    /* MUST BE 0x0f (for DVI DDC detection */
+#define Panel_320x480           0x10    /* SiS 550 fstn - TW: This is fake, can be any */
+#define Panel_Barco1366         0x11
+#define Panel_848x480          0x12
+#define Panel_640x480_2                0x13    /* SiS 550 */
+#define Panel_640x480_3                0x14    /* SiS 550 */
+#define Panel_1280x768_2        0x15   /* 30xLV */
+#define Panel_1280x768_3        0x16    /* 30xLV */
 
 /* Index in ModeResInfo table */
 #define SIS_RI_320x200    0
 #define SIS_RI_856x480   19
 #define SIS_RI_1280x768  20
 #define SIS_RI_1400x1050 21
-#define SIS_RI_1152x864  22  /* Up to this SiS conforming */
+#define SIS_RI_1152x864  22  /* Up to here SiS conforming */
 #define SIS_RI_848x480   23
 #define SIS_RI_1360x768  24
 #define SIS_RI_1024x600  25
 #define SIS_RI_1152x768  26
 #define SIS_RI_768x576   27
 #define SIS_RI_1360x1024 28
+#define SIS_RI_1680x1050 29
+#define SIS_RI_1280x800  30
+#define SIS_RI_1920x1080 31
+#define SIS_RI_960x540   32
 
 /* CR5F */
 #define IsM650                  0x80
 #define VCLK108_3_300           0x42   /* Index in VCLKData table (300) */
 #define VCLK100_300             0x43   /* Index in VCLKData table (300) */
 #define VCLK34_300              0x3d   /* Index in VCLKData table (300) */
+#define VCLK_CUSTOM_300                0x46
 #define VCLK65_315              0x0b   /* Index in (VB)VCLKData table (315) */
 #define VCLK108_2_315           0x19   /* Index in (VB)VCLKData table (315) */
 #define VCLK81_315             0x5b   /* Index in (VB)VCLKData table (315) */
-#define VCLK162_315             0x21   /* Index in (VB)VCLKData table (315) */
+#define VCLK162_315             0x5e   /* Index in (VB)VCLKData table (315) */
 #define VCLK108_3_315           0x45   /* Index in VBVCLKData table (315) */
 #define VCLK100_315             0x46   /* Index in VBVCLKData table (315) */
-#define VCLK34_315              0x55   /* Index in VBVCLKData table (315) */
+#define VCLK34_315              0x55
 #define VCLK68_315             0x0d
+#define VCLK69_315             0x5c   /* deprecated ! Index in VBVCLKData table (315) */
+#define VCLK83_315             0x5c   /* Index in VBVCLKData table (315) */
+#define VCLK121_315            0x5d   /* Index in VBVCLKData table (315) */
+#define VCLK_1280x720          0x5f
+#define VCLK_1280x768_2                0x60
+#define VCLK_1280x768_3                0x61
+#define VCLK_CUSTOM_315                0x62
+#define VCLK_1280x720_2                0x63
+#define VCLK_720x480           0x67
+#define VCLK_720x576           0x68
+#define VCLK_768x576           0x68
+#define VCLK_848x480           0x65
+#define VCLK_856x480           0x66
+#define VCLK_800x480           0x65
+#define VCLK_1024x576          0x51
+#define VCLK_1152x864          0x64
+#define VCLK_1360x768          0x58
 
 #define TVCLKBASE_300          0x21   /* Indices on TV clocks in VCLKData table (300) */
 #define TVCLKBASE_315          0x3a   /* Indices on TV clocks in (VB)VCLKData table (315) */
 #define HiTVVCLK                0x03   /* Index relative to TVCLKBASE */
 #define HiTVSimuVCLK            0x04   /* Index relative to TVCLKBASE */
 #define HiTVTextVCLK            0x05   /* Index relative to TVCLKBASE */
-#define YPbPr750pVCLK          0x0f   /* NOT relative to TVCLKBASE ! */
+#define YPbPr750pVCLK          0x25   /* Index relative to TVCLKBASE; was 0x0f NOT relative */
 
 /* ------------------------------ */
 
 
 /*
   =============================================================
-                         for 315 series
+                 for 315 series (old data layout)
   =============================================================
 */
 #define SoftDRAMType        0x80
index e4928e2..d644464 100644 (file)
@@ -1,4 +1,5 @@
 /* $XFree86$ */
+/* $XdotOrg$ */
 /*
  * OEM Data for 300 series
  *
  * * 2) Redistributions in binary form must reproduce the above copyright
  * *    notice, this list of conditions and the following disclaimer in the
  * *    documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * *    must display the following acknowledgement: "This product includes
- * *    software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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,
index fad2fa0..4b6cbb7 100644 (file)
@@ -1,4 +1,5 @@
 /* $XFree86$ */
+/* $XdotOrg$ */
 /*
  * OEM Data for 315/330 series
  *
  * * 2) Redistributions in binary form must reproduce the above copyright
  * *    notice, this list of conditions and the following disclaimer in the
  * *    documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * *    must display the following acknowledgement: "This product includes
- * *    software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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,
@@ -91,7 +89,7 @@ static const UCHAR SiS310_LCDDelayCompensation_650301LV[] =           /* 650 + 30xLV *
                 0x02,0x02,0x02
 };
 
-static const UCHAR SiS310_LCDDelayCompensation_651301LV[] =      /* M650/651 301LV */
+static const UCHAR SiS310_LCDDelayCompensation_651301LV[] =            /* M650/651 301LV */
 {
                  0x33,0x33,0x33,    /*   800x600 (guessed) - new: PanelType, not PanelRes ! */
                 0x33,0x33,0x33,    /*  1024x768 */
@@ -110,7 +108,7 @@ static const UCHAR SiS310_LCDDelayCompensation_651301LV[] =   /* M650/651 301LV
                 0x33,0x33,0x33
 };
 
-static const UCHAR SiS310_LCDDelayCompensation_651302LV[] =       /* M650/651 302LV */
+static const UCHAR SiS310_LCDDelayCompensation_651302LV[] =            /* M650/651 302LV */
 {
                  0x33,0x33,0x33,    /*   800x600 (guessed) */
                 0x33,0x33,0x33,    /*  1024x768 */
@@ -129,7 +127,7 @@ static const UCHAR SiS310_LCDDelayCompensation_651302LV[] =    /* M650/651 302LV
                 0x33,0x33,0x33
 };
 
-static const UCHAR SiS310_LCDDelayCompensation_3xx301B[] =             /* 30xB,LV */
+static const UCHAR SiS310_LCDDelayCompensation_3xx301B[] =             /* 30xB */
 {
                 0x01,0x01,0x01,    /*   800x600 */
                 0x0C,0x0C,0x0C,    /*  1024x768 */
@@ -148,6 +146,25 @@ static const UCHAR SiS310_LCDDelayCompensation_3xx301B[] =         /* 30xB,LV */
                 0x02,0x02,0x02
 };
 
+static const UCHAR SiS310_LCDDelayCompensation_3xx301LV[] =            /* 315+30xLV */
+{
+                0x01,0x01,0x01,    /*   800x600 */
+                0x04,0x04,0x04,    /*  1024x768 (A531/BIOS 1.14.05f: 4 - works with 6 */
+                0x0C,0x0C,0x0C,    /* 1280x1024 */
+                 0x08,0x08,0x08,    /*   640x480 */
+                0x0C,0x0C,0x0C,    /*  1024x600 (guessed) */
+                0x0C,0x0C,0x0C,    /*  1152x864 (guessed) */
+                0x0C,0x0C,0x0C,    /*  1280x960 (guessed) */
+                0x0C,0x0C,0x0C,    /*  1152x768 (guessed) */
+                0x0C,0x0C,0x0C,    /* 1400x1050 (guessed) */
+                0x0C,0x0C,0x0C,    /*  1280x768 (guessed) */
+                0x0C,0x0C,0x0C,    /* 1600x1200 (guessed) */
+                0x02,0x02,0x02,
+                0x02,0x02,0x02,
+                0x02,0x02,0x02,
+                0x02,0x02,0x02
+};
+
 static const UCHAR SiS310_TVDelayCompensation_301[] =          /* 301 */
 {
                 0x02,0x02,    /* NTSC Enhanced, Standard */
@@ -169,13 +186,6 @@ static const UCHAR SiS310_TVDelayCompensation_740301B[] =  /* 740 + 30xB (30xLV?)
                 0x05,0x05
 };
 
-static const UCHAR SiS310_TVDelayCompensation_LVDS[] =         /* LVDS */
-{
-                0x0a,0x0a,
-                0x0a,0x0a,
-                0x0a,0x0a
-};
-
 static const UCHAR SiS310_TVDelayCompensation_651301LV[] =     /* M650, 651, 301LV */
 {
                 0x33,0x33,
@@ -210,6 +220,13 @@ static const UCHAR SiS_TVDelay661_301B[] =                 /* 661, 301B et al */
                 0x44,0x44
 };
 
+static const UCHAR SiS310_TVDelayCompensation_LVDS[] =         /* LVDS */
+{
+                0x0a,0x0a,
+                0x0a,0x0a,
+                0x0a,0x0a
+};
+
 static const UCHAR SiS310_TVAntiFlick1[6][2] =
 {
             {0x4,0x0},
@@ -412,141 +429,6 @@ static const SiS_LCDDataStruct  SiS310_ExtCompaq1280x1024Data[] =
        {    1,   1,1696,1066,1696,1066}
 };
 
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_1[] =
-{
- {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x35,0x1B,0xA0,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x45,0x1C,0x20,0x3F,0xFF,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x49,0x1C,0x40,0x7F,0xFF,0xAD,0x23,0x0A,0x07,0xF3,0x8A,0x12}},
- {{0x4C,0x1C,0x18,0x2F,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
-};
-
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_2[] =
-{
- {{0x2B,0x12,0xD9,0xE5,0xD5,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
- {{0x22,0x12,0xC0,0xCC,0xBC,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
- {{0x2B,0x12,0xD9,0xE5,0xD5,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
- {{0x22,0x12,0xC0,0xCC,0xBC,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
- {{0x33,0x13,0x01,0x0D,0xFD,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
- {{0x3F,0x1B,0x3D,0x49,0x39,0x54,0x23,0xC0,0x27,0x66,0x30,0x42}},
- {{0x33,0x1B,0x91,0x9D,0x8D,0x8C,0x23,0xF8,0x27,0x9E,0x68,0x42}},
- {{0x43,0x24,0x11,0x1D,0x0D,0xCC,0x23,0x38,0x37,0xDE,0xA8,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xEA,0x23,0x0A,0x07,0x32,0xC6,0x42}}
-};
-
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_3[] =
-{
- {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}}
-};
-
-/* LCDA CRT2 data is std */
-
-static const SiS_LVDSDesStruct Compaq1280x1024Des_1[] =
-{
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 }
-};
-
-static const SiS_LVDSDesStruct Compaq1280x1024Des_2[] =
-{
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 }
-};
-
-/* Clevo L285/287 (dual-link 1024x768) */
-
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Clevo1024x768_1[] =
-{
- {{0x25,0x12,0xC9,0xDC,0xB6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
- {{0x2C,0x12,0x9A,0xAE,0x88,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
- {{0x25,0x12,0xC9,0xDC,0xB6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x38,0x13,0x16,0x0C,0xE6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
- {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
- {{0x36,0x13,0x13,0x25,0xFF,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x25,0x12,0xC9,0xDC,0xB6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}
-};
-
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Clevo1024x768_2[] =
-{
- {{0x25,0x12,0x51,0x6E,0x48,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}},
- {{0x2C,0x12,0x38,0x55,0x2F,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}},
- {{0x25,0x12,0x51,0x6E,0x48,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}},
- {{0x2C,0x12,0x38,0x55,0x2F,0xE0,0x12,0xB1,0x47,0x30,0x71,0x33}},
- {{0x2D,0x12,0x79,0x96,0x70,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}},
- {{0x29,0x12,0xB5,0xD2,0xAC,0xF4,0x12,0xD9,0x47,0x44,0x99,0x33}},
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
-#if 0
- {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x2C,0x12,0x38,0x55,0x2F,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x2C,0x12,0x38,0x55,0x2F,0xC1,0x35,0xB1,0x47,0xE9,0x71,0x33}},
- {{0x2D,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x29,0x12,0xB5,0xD2,0xAC,0xE9,0x35,0xD9,0x47,0x11,0x99,0x33}},
- {{0x36,0x13,0x13,0x25,0xFF,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}
-#endif
-};
-
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Clevo1024x768_3[] =
-{
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}}, /* Corrected */
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x25,0x13,0xC9,0x25,0xFF,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}
-};
-
-/* CRT2 data is std */
-
-static const SiS_LVDSDesStruct Clevo1024x768Des_1[] =
-{
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 }
-};
-
-static const SiS_LVDSDesStruct Clevo1024x768Des_2[] =
-{
-  { 1184, 622 },
-  { 1184, 597 },
-  { 1184, 622 },
-  { 1184, 597 },
-  { 1152, 622 },
-  { 1232, 722 },
-  {    0,   0 }
-};
-
 /* Asus A2xxxH _2 */
 
 static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Asus1024x768_3[] =
@@ -562,52 +444,6 @@ static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Asus1024x768_3[] =
  {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
 };
 
-static const SiS_LVDSDesStruct Asus1024x768Des_1[] =
-{
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 }
-};
-
-static const SiS_LVDSDesStruct Asus1024x768Des_2[] =
-{
-  { 1184, 622 },
-  { 1184, 597 },
-  { 1184, 622 },
-  { 1184, 597 },
-  { 1152, 622 },
-  { 1232, 722 },
-  {    0,   0 }
-};
-
-/* CRT2 data is std */
-
-/* Uniwill N243S9, ECS A928 */
 
-static const SiS_LVDSDesStruct Uniwill1024x768Des_1[] =
-{
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 0 },
-  { 0, 805 }
-};
-
-static const SiS_LVDSDesStruct Uniwill1024x768Des_2[] =
-{
-  { 1184, 622 },
-  { 1184, 597 },
-  { 1184, 622 },
-  { 1184, 597 },
-  { 1152, 650 },
-  { 1232, 722 },
-  {    0, 805 },
-};
 
 
index 1bef56e..443ee39 100644 (file)
@@ -1,4 +1,5 @@
 /* $XFree86$ */
+/* $XdotOrg$ */
 /*
  * OS depending defines
  *
  * * 2) Redistributions in binary form must reproduce the above copyright
  * *    notice, this list of conditions and the following disclaimer in the
  * *    documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * *    must display the following acknowledgement: "This product includes
- * *    software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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,
  */
 
 /* The choices are: */
-
 #define LINUX_KERNEL      /* Kernel framebuffer */
 /* #define LINUX_XF86 */   /* XFree86 */
 
-/**********************************************************************/
-#ifdef LINUX_KERNEL  /* -------------------------- */
-#include <linux/config.h>
-#include <linux/version.h>
-
-#ifdef CONFIG_FB_SIS_300
-#define SIS300
-#endif
-
-#ifdef CONFIG_FB_SIS_315
-#define SIS315H
-#endif
-
-#if 1
-#define SISFBACCEL     /* Include 2D acceleration */
-#endif
-
-#endif
-
-#ifdef LINUX_XF86 /* ----------------------------- */
-#define SIS300
-#define SIS315H
-#endif
-
-/**********************************************************************/
-#ifdef LINUX_XF86
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
-#define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
-#endif
-
-#ifdef LINUX_KERNEL
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
-#define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
-#endif
-
-/**********************************************************************/
-
 #ifdef OutPortByte
 #undef OutPortByte
-#endif /* OutPortByte */
+#endif
 
 #ifdef OutPortWord
 #undef OutPortWord
-#endif /* OutPortWord */
+#endif
 
 #ifdef OutPortLong
 #undef OutPortLong
-#endif /* OutPortLong */
+#endif
 
 #ifdef InPortByte
 #undef InPortByte
-#endif /* InPortByte */
+#endif
 
 #ifdef InPortWord
 #undef InPortWord
-#endif /* InPortWord */
+#endif
 
 #ifdef InPortLong
 #undef InPortLong
-#endif /* InPortLong */
+#endif
 
 /**********************************************************************/
-/*  LINUX XF86                                                        */
+/*  LINUX KERNEL                                                      */
 /**********************************************************************/
 
-#ifdef LINUX_XF86
-#define OutPortByte(p,v) outb((CARD16)(p),(CARD8)(v))
-#define OutPortWord(p,v) outw((CARD16)(p),(CARD16)(v))
-#define OutPortLong(p,v) outl((CARD16)(p),(CARD32)(v))
-#define InPortByte(p)    inb((CARD16)(p))
-#define InPortWord(p)    inw((CARD16)(p))
-#define InPortLong(p)    inl((CARD16)(p))
+#ifdef LINUX_KERNEL
+#include <linux/config.h>
+
+#ifdef CONFIG_FB_SIS_300
+#define SIS300
+#endif
+
+#ifdef CONFIG_FB_SIS_315
+#define SIS315H
+#endif
+
+#if !defined(SIS300) && !defined(SIS315H)
+#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
+#warning sisfb will not work!
+#endif
+
+#define OutPortByte(p,v) outb((u8)(v),(SISIOADDRESS)(p))
+#define OutPortWord(p,v) outw((u16)(v),(SISIOADDRESS)(p))
+#define OutPortLong(p,v) outl((u32)(v),(SISIOADDRESS)(p))
+#define InPortByte(p)    inb((SISIOADDRESS)(p))
+#define InPortWord(p)    inw((SISIOADDRESS)(p))
+#define InPortLong(p)    inl((SISIOADDRESS)(p))
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset_io(MemoryAddress, value, MemorySize)
 #endif
 
 /**********************************************************************/
-/*  LINUX KERNEL                                                      */
+/*  XFree86, X.org                                                    */
 /**********************************************************************/
 
-#ifdef LINUX_KERNEL
-#define OutPortByte(p,v) outb((u8)(v),(u16)(p))
-#define OutPortWord(p,v) outw((u16)(v),(u16)(p))
-#define OutPortLong(p,v) outl((u32)(v),(u16)(p))
-#define InPortByte(p)    inb((u16)(p))
-#define InPortWord(p)    inw((u16)(p))
-#define InPortLong(p)    inl((u16)(p))
+#ifdef LINUX_XF86
+#define SIS300
+#define SIS315H
+
+#define OutPortByte(p,v) outb((IOADDRESS)(p),(CARD8)(v))
+#define OutPortWord(p,v) outw((IOADDRESS)(p),(CARD16)(v))
+#define OutPortLong(p,v) outl((IOADDRESS)(p),(CARD32)(v))
+#define InPortByte(p)    inb((IOADDRESS)(p))
+#define InPortWord(p)    inw((IOADDRESS)(p))
+#define InPortLong(p)    inl((IOADDRESS)(p))
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
 #endif
 
 
index 5fa107d..97599df 100644 (file)
+/*
+ * SiS 300/630/730/540/315/550/650/651/M650/661FX/M661FX/740/741/330/760
+ * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
+ *
+ * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
+ *
+ * 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 named License,
+ * or 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 _SIS_H
 #define _SIS_H
 
-#if 1
-#define TWDEBUG(x)
+#include <linux/config.h>
+#include <linux/version.h>
+
+#include "osdef.h"
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#include <video/sisfb.h>
 #else
+#include <linux/sisfb.h>
+#endif
+
+#include "vgatypes.h"
+#include "vstruct.h"
+
+#define VER_MAJOR                 1
+#define VER_MINOR                 7
+#define VER_LEVEL                 12
+
+#undef SIS_CONFIG_COMPAT
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#include <linux/spinlock.h>
+#ifdef CONFIG_COMPAT
+#include <linux/ioctl32.h>
+#define SIS_CONFIG_COMPAT
+#endif
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19)
+#ifdef __x86_64__
+/* Shouldn't we check for CONFIG_IA32_EMULATION here? */
+#include <asm/ioctl32.h>
+#define SIS_CONFIG_COMPAT
+#endif
+#endif
+
+#undef SISFBDEBUG
+
+#ifdef SISFBDEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
 #define TWDEBUG(x) printk(KERN_INFO x "\n");
+#else
+#define DPRINTK(fmt, args...)
+#define TWDEBUG(x)
+#endif
+
+#define SISFAIL(x) do { printk(x "\n"); return -EINVAL; } while(0)
+
+/* To be included in pci_ids.h */
+#ifndef PCI_DEVICE_ID_SI_650_VGA
+#define PCI_DEVICE_ID_SI_650_VGA  0x6325
+#endif
+#ifndef PCI_DEVICE_ID_SI_650
+#define PCI_DEVICE_ID_SI_650      0x0650
+#endif
+#ifndef PCI_DEVICE_ID_SI_651
+#define PCI_DEVICE_ID_SI_651      0x0651
+#endif
+#ifndef PCI_DEVICE_ID_SI_740
+#define PCI_DEVICE_ID_SI_740      0x0740
+#endif
+#ifndef PCI_DEVICE_ID_SI_330
+#define PCI_DEVICE_ID_SI_330      0x0330
+#endif
+#ifndef PCI_DEVICE_ID_SI_660_VGA
+#define PCI_DEVICE_ID_SI_660_VGA  0x6330
+#endif
+#ifndef PCI_DEVICE_ID_SI_661
+#define PCI_DEVICE_ID_SI_661      0x0661
+#endif
+#ifndef PCI_DEVICE_ID_SI_741
+#define PCI_DEVICE_ID_SI_741      0x0741
+#endif
+#ifndef PCI_DEVICE_ID_SI_660
+#define PCI_DEVICE_ID_SI_660      0x0660
+#endif
+#ifndef PCI_DEVICE_ID_SI_760
+#define PCI_DEVICE_ID_SI_760      0x0760
+#endif
+
+/* To be included in fb.h */
+#ifndef FB_ACCEL_SIS_GLAMOUR_2
+#define FB_ACCEL_SIS_GLAMOUR_2   40    /* SiS 315, 65x, 740, 661, 741  */
+#endif
+#ifndef FB_ACCEL_SIS_XABRE
+#define FB_ACCEL_SIS_XABRE        41   /* SiS 330 ("Xabre"), 760       */
+#endif
+
+#define MAX_ROM_SCAN              0x10000
+
+/* ivideo->caps */
+#define HW_CURSOR_CAP             0x80
+#define TURBO_QUEUE_CAP           0x40
+#define AGP_CMD_QUEUE_CAP         0x20
+#define VM_CMD_QUEUE_CAP          0x10
+#define MMIO_CMD_QUEUE_CAP        0x08
+
+/* For 300 series */
+#define TURBO_QUEUE_AREA_SIZE     0x80000 /* 512K */
+#define HW_CURSOR_AREA_SIZE_300   0x1000  /* 4K */
+
+/* For 315/Xabre series */
+#define COMMAND_QUEUE_AREA_SIZE   0x80000 /* 512K */
+#define COMMAND_QUEUE_THRESHOLD   0x1F
+#define HW_CURSOR_AREA_SIZE_315   0x4000  /* 16K */
+
+#define SIS_OH_ALLOC_SIZE         4000
+#define SENTINEL                  0x7fffffff
+
+#define SEQ_ADR                   0x14
+#define SEQ_DATA                  0x15
+#define DAC_ADR                   0x18
+#define DAC_DATA                  0x19
+#define CRTC_ADR                  0x24
+#define CRTC_DATA                 0x25
+#define DAC2_ADR                  (0x16-0x30)
+#define DAC2_DATA                 (0x17-0x30)
+#define VB_PART1_ADR              (0x04-0x30)
+#define VB_PART1_DATA             (0x05-0x30)
+#define VB_PART2_ADR              (0x10-0x30)
+#define VB_PART2_DATA             (0x11-0x30)
+#define VB_PART3_ADR              (0x12-0x30)
+#define VB_PART3_DATA             (0x13-0x30)
+#define VB_PART4_ADR              (0x14-0x30)
+#define VB_PART4_DATA             (0x15-0x30)
+
+#define SISSR                    ivideo->SiS_Pr.SiS_P3c4
+#define SISCR                     ivideo->SiS_Pr.SiS_P3d4
+#define SISDACA                   ivideo->SiS_Pr.SiS_P3c8
+#define SISDACD                   ivideo->SiS_Pr.SiS_P3c9
+#define SISPART1                  ivideo->SiS_Pr.SiS_Part1Port
+#define SISPART2                  ivideo->SiS_Pr.SiS_Part2Port
+#define SISPART3                  ivideo->SiS_Pr.SiS_Part3Port
+#define SISPART4                  ivideo->SiS_Pr.SiS_Part4Port
+#define SISPART5                  ivideo->SiS_Pr.SiS_Part5Port
+#define SISDAC2A                  SISPART5
+#define SISDAC2D                  (SISPART5 + 1)
+#define SISMISCR                  (ivideo->SiS_Pr.RelIO + 0x1c)
+#define SISMISCW                  ivideo->SiS_Pr.SiS_P3c2
+#define SISINPSTAT               (ivideo->SiS_Pr.RelIO + 0x2a)
+#define SISPEL                   ivideo->SiS_Pr.SiS_P3c6
+
+#define IND_SIS_PASSWORD          0x05  /* SRs */
+#define IND_SIS_COLOR_MODE        0x06
+#define IND_SIS_RAMDAC_CONTROL    0x07
+#define IND_SIS_DRAM_SIZE         0x14
+#define IND_SIS_MODULE_ENABLE     0x1E
+#define IND_SIS_PCI_ADDRESS_SET   0x20
+#define IND_SIS_TURBOQUEUE_ADR    0x26
+#define IND_SIS_TURBOQUEUE_SET    0x27
+#define IND_SIS_POWER_ON_TRAP     0x38
+#define IND_SIS_POWER_ON_TRAP2    0x39
+#define IND_SIS_CMDQUEUE_SET      0x26
+#define IND_SIS_CMDQUEUE_THRESHOLD  0x27
+
+#define IND_SIS_AGP_IO_PAD        0x48
+
+#define SIS_CRT2_WENABLE_300     0x24  /* Part1 */
+#define SIS_CRT2_WENABLE_315     0x2F
+
+#define SIS_PASSWORD              0x86  /* SR05 */
+#define SIS_INTERLACED_MODE       0x20  /* SR06 */
+#define SIS_8BPP_COLOR_MODE       0x0
+#define SIS_15BPP_COLOR_MODE      0x1
+#define SIS_16BPP_COLOR_MODE      0x2
+#define SIS_32BPP_COLOR_MODE      0x4
+
+#define SIS_ENABLE_2D             0x40  /* SR1E */
+
+#define SIS_MEM_MAP_IO_ENABLE     0x01  /* SR20 */
+#define SIS_PCI_ADDR_ENABLE       0x80
+
+#define SIS_AGP_CMDQUEUE_ENABLE   0x80  /* 315/330 series SR26 */
+#define SIS_VRAM_CMDQUEUE_ENABLE  0x40
+#define SIS_MMIO_CMD_ENABLE       0x20
+#define SIS_CMD_QUEUE_SIZE_512k   0x00
+#define SIS_CMD_QUEUE_SIZE_1M     0x04
+#define SIS_CMD_QUEUE_SIZE_2M     0x08
+#define SIS_CMD_QUEUE_SIZE_4M     0x0C
+#define SIS_CMD_QUEUE_RESET       0x01
+#define SIS_CMD_AUTO_CORR        0x02
+
+#define SIS_SIMULTANEOUS_VIEW_ENABLE  0x01  /* CR30 */
+#define SIS_MODE_SELECT_CRT2      0x02
+#define SIS_VB_OUTPUT_COMPOSITE   0x04
+#define SIS_VB_OUTPUT_SVIDEO      0x08
+#define SIS_VB_OUTPUT_SCART       0x10
+#define SIS_VB_OUTPUT_LCD         0x20
+#define SIS_VB_OUTPUT_CRT2        0x40
+#define SIS_VB_OUTPUT_HIVISION    0x80
+
+#define SIS_VB_OUTPUT_DISABLE     0x20  /* CR31 */
+#define SIS_DRIVER_MODE           0x40
+
+#define SIS_VB_COMPOSITE          0x01  /* CR32 */
+#define SIS_VB_SVIDEO             0x02
+#define SIS_VB_SCART              0x04
+#define SIS_VB_LCD                0x08
+#define SIS_VB_CRT2               0x10
+#define SIS_CRT1                  0x20
+#define SIS_VB_HIVISION           0x40
+#define SIS_VB_YPBPR              0x80
+#define SIS_VB_TV                 (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
+                                   SIS_VB_SCART | SIS_VB_HIVISION | SIS_VB_YPBPR)
+
+#define SIS_EXTERNAL_CHIP_MASK            0x0E  /* CR37 (< SiS 660) */
+#define SIS_EXTERNAL_CHIP_SIS301           0x01  /* in CR37 << 1 ! */
+#define SIS_EXTERNAL_CHIP_LVDS             0x02
+#define SIS_EXTERNAL_CHIP_TRUMPION         0x03
+#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL    0x04
+#define SIS_EXTERNAL_CHIP_CHRONTEL         0x05
+#define SIS310_EXTERNAL_CHIP_LVDS          0x02
+#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03
+
+#define SIS_AGP_2X                0x20  /* CR48 */
+
+#define HW_DEVICE_EXTENSION      SIS_HW_INFO
+#define PHW_DEVICE_EXTENSION      PSIS_HW_INFO
+
+/* Useful macros */
+#define inSISREG(base)          inb(base)
+#define outSISREG(base,val)     outb(val,base)
+#define orSISREG(base,val)      do { \
+                                  u8 __Temp = inb(base); \
+                                  outSISREG(base, __Temp | (val)); \
+                                } while (0)
+#define andSISREG(base,val)     do { \
+                                  u8 __Temp = inb(base); \
+                                  outSISREG(base, __Temp & (val)); \
+                                } while (0)
+#define inSISIDXREG(base,idx,var)   do { \
+                                      outb(idx,base); var=inb((base)+1); \
+                                    } while (0)
+#define outSISIDXREG(base,idx,val)  do { \
+                                      outb(idx,base); outb((val),(base)+1); \
+                                    } while (0)
+#define orSISIDXREG(base,idx,val)   do { \
+                                      u8 __Temp; \
+                                      outb(idx,base);   \
+                                      __Temp = inb((base)+1)|(val); \
+                                      outSISIDXREG(base,idx,__Temp); \
+                                    } while (0)
+#define andSISIDXREG(base,idx,and)  do { \
+                                      u8 __Temp; \
+                                      outb(idx,base);   \
+                                      __Temp = inb((base)+1)&(and); \
+                                      outSISIDXREG(base,idx,__Temp); \
+                                    } while (0)
+#define setSISIDXREG(base,idx,and,or)   do { \
+                                          u8 __Temp; \
+                                          outb(idx,base);   \
+                                          __Temp = (inb((base)+1)&(and))|(or); \
+                                          outSISIDXREG(base,idx,__Temp); \
+                                        } while (0)
+
+/* MMIO access macros */
+#define MMIO_IN8(base, offset)  readb((base+offset))
+#define MMIO_IN16(base, offset) readw((base+offset))
+#define MMIO_IN32(base, offset) readl((base+offset))
+
+#define MMIO_OUT8(base, offset, val)  writeb(((u8)(val)), (base+offset))
+#define MMIO_OUT16(base, offset, val) writew(((u16)(val)), (base+offset))
+#define MMIO_OUT32(base, offset, val) writel(((u32)(val)), (base+offset))
+
+/* Queue control MMIO registers */
+#define Q_BASE_ADDR            0x85C0  /* Base address of software queue */
+#define Q_WRITE_PTR            0x85C4  /* Current write pointer */
+#define Q_READ_PTR             0x85C8  /* Current read pointer */
+#define Q_STATUS               0x85CC  /* queue status */
+
+#define MMIO_QUEUE_PHYBASE      Q_BASE_ADDR
+#define MMIO_QUEUE_WRITEPORT    Q_WRITE_PTR
+#define MMIO_QUEUE_READPORT     Q_READ_PTR
+
+enum _SIS_CMDTYPE {
+       MMIO_CMD = 0,
+       AGP_CMD_QUEUE,
+       VM_CMD_QUEUE,
+};
+typedef unsigned int SIS_CMDTYPE;
+
+/* Our "par" */
+struct sis_video_info {
+       int             cardnumber;
+       struct fb_info  *memyselfandi;
+
+       SIS_HW_INFO     sishw_ext;
+       SiS_Private     SiS_Pr;
+
+       sisfb_info      sisfbinfo;      /* For ioctl SISFB_GET_INFO */
+
+       struct fb_var_screeninfo default_var;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+       struct fb_fix_screeninfo sisfb_fix;
+       u32             pseudo_palette[17];
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+       struct display           sis_disp;
+       struct display_switch    sisfb_sw;
+       struct {
+               u16 red, green, blue, pad;
+       }               sis_palette[256];
+       union {
+#ifdef FBCON_HAS_CFB16
+               u16 cfb16[16];
+#endif
+#ifdef FBCON_HAS_CFB32
+               u32 cfb32[16];
+#endif
+       }               sis_fbcon_cmap;
+#endif
+
+        struct sisfb_monitor {
+               u16 hmin;
+               u16 hmax;
+               u16 vmin;
+               u16 vmax;
+               u32 dclockmax;
+               u8  feature;
+               BOOLEAN datavalid;
+       }               sisfb_thismonitor;
+
+       int             chip_id;
+       char            myid[40];
+
+       struct pci_dev  *nbridge;
+
+       int             mni;    /* Mode number index */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+       int             currcon;
+#endif
+
+       unsigned long   video_size;
+       unsigned long   video_base;
+       unsigned long   mmio_size;
+       unsigned long   mmio_base;
+       unsigned long   vga_base;
+
+       unsigned long   video_vbase;
+       unsigned long   mmio_vbase;
+       char  *         bios_vbase;
+       char  *         bios_abase;
+
+       int             mtrr;
+
+       u32             sisfb_mem;
+
+       u32             sisfb_parm_mem;
+       int             sisfb_accel;
+       int             sisfb_ypan;
+       int             sisfb_max;
+       int             sisfb_userom;
+       int             sisfb_useoem;
+       int             sisfb_mode_idx;
+       int             sisfb_parm_rate;
+       int             sisfb_crt1off;
+       int             sisfb_forcecrt1;
+       int             sisfb_crt2type;
+       int             sisfb_crt2flags;
+       int             sisfb_dstn;
+       int             sisfb_fstn;
+       int             sisfb_tvplug;
+       int             sisfb_tvstd;
+       int             sisfb_filter;
+       int             sisfb_nocrt2rate;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+       int             sisfb_inverse;
+#endif
+
+       u32             heapstart;        /* offset  */
+       unsigned long   sisfb_heap_start; /* address */
+       unsigned long   sisfb_heap_end;   /* address */
+       u32             sisfb_heap_size;
+       int             havenoheap;
+#if 0
+       SIS_HEAP        sisfb_heap;
 #endif
 
+
+       int             video_bpp;
+       int             video_cmap_len;
+       int             video_width;
+       int             video_height;
+       unsigned int    refresh_rate;
+
+       unsigned int    chip;
+       u8              revision_id;
+
+       int             video_linelength;       /* real pitch */
+       int             scrnpitchCRT1;          /* pitch regarding interlace */
+
+        u16            DstColor;               /* For 2d acceleration */
+       u32             SiS310_AccelDepth;
+       u32             CommandReg;
+       int             cmdqueuelength;
+
+       spinlock_t      lockaccel;              /* Do not use outside of kernel! */
+
+        unsigned int           pcibus;
+       unsigned int    pcislot;
+       unsigned int    pcifunc;
+
+       int             accel;
+
+       u16             subsysvendor;
+       u16             subsysdevice;
+
+       u32             vbflags;                /* Replacing deprecated stuff from above */
+       u32             currentvbflags;
+
+       int             lcdxres, lcdyres;
+       int             lcddefmodeidx, tvdefmodeidx, defmodeidx;
+
+       int             current_bpp;
+       int             current_width;
+       int             current_height;
+       int             current_htotal;
+       int             current_vtotal;
+       int             current_linelength;
+       __u32           current_pixclock;
+       int             current_refresh_rate;
+
+       u8              mode_no;
+       u8              rate_idx;
+       int             modechanged;
+       unsigned char   modeprechange;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+       u8              sisfb_lastrates[128];
+#endif
+
+       int             newrom;
+       int             registered;
+#ifdef SIS_CONFIG_COMPAT
+       int             ioctl32registered;
+       int             ioctl32vblankregistered;
+#endif
+
+       int             sisvga_engine;
+       int             hwcursor_size;
+       int             CRT2_write_enable;
+       u8              caps;
+
+       u8              detectedpdc;
+       u8              detectedpdca;
+       u8              detectedlcda;
+
+       unsigned long   hwcursor_vbase;
+
+       int             chronteltype;
+       int             tvxpos, tvypos;
+       u8              p2_1f,p2_20,p2_2b,p2_42,p2_43,p2_01,p2_02;
+       int             tvx, tvy;
+
+       u8              sisfblocked;
+
+       struct sis_video_info *next;
+};
+
+typedef struct _SIS_OH {
+       struct _SIS_OH *poh_next;
+       struct _SIS_OH *poh_prev;
+       u32            offset;
+       u32            size;
+} SIS_OH;
+
+typedef struct _SIS_OHALLOC {
+       struct _SIS_OHALLOC *poha_next;
+       SIS_OH aoh[1];
+} SIS_OHALLOC;
+
+typedef struct _SIS_HEAP {
+       SIS_OH      oh_free;
+       SIS_OH      oh_used;
+       SIS_OH      *poh_freelist;
+       SIS_OHALLOC *poha_chain;
+       u32         max_freesize;
+       struct sis_video_info *vinfo;
+} SIS_HEAP;
+
 #endif
index 07e29d7..30e90a5 100644 (file)
@@ -18,9 +18,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * Based on the XFree86 driver's sis300_accel.c which is
- *     Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
- * and sis310_accel.c which is
+ * Based on the XFree86/X.org driver which is
  *     Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
  * Author: Thomas Winischhofer <thomas@winischhofer.net>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/console.h>
 #include <linux/selection.h>
 #include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/vt_kern.h>
 #include <linux/capability.h>
 #include <linux/fs.h>
-#include <linux/agp_backend.h>
-
 #include <linux/types.h>
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/sisfb.h>
-#else
-#include <video/sisfb.h>
-#endif
-
 #include <asm/io.h>
 
-#ifdef CONFIG_MTRR
-#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-cfb32.h>
 #endif
 
-#include "osdef.h"
-#include "vgatypes.h"
-#include "vstruct.h"
-#include "sis_accel.h"
 #include "sis.h"
+#include "sis_accel.h"
 
-extern struct     video_info ivideo;
-extern VGA_ENGINE sisvga_engine;
-extern int sisfb_accel;
-
-static const int sisALUConv[] =
+static const u8 sisALUConv[] =
 {
     0x00,       /* dest = 0;            0,      GXclear,        0 */
     0x88,       /* dest &= src;         DSa,    GXand,          0x1 */
@@ -101,7 +72,7 @@ static const int sisALUConv[] =
     0xFF,       /* dest = 0xFF;         1,      GXset,          0xF */
 };
 /* same ROP but with Pattern as Source */
-static const int sisPatALUConv[] =
+static const u8 sisPatALUConv[] =
 {
     0x00,       /* dest = 0;            0,      GXclear,        0 */
     0xA0,       /* dest &= src;         DPa,    GXand,          0x1 */
@@ -122,26 +93,26 @@ static const int sisPatALUConv[] =
 };
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
-static const unsigned char myrops[] = {
+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
 static void
-SiS300Sync(void)
+SiS300Sync(struct sis_video_info *ivideo)
 {
        SiS300Idle
 }
 
 static void
-SiS300SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
-                                unsigned int planemask, int trans_color)
+SiS300SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int xdir, int ydir,
+                                 int rop, int trans_color)
 {
-       SiS300SetupDSTColorDepth(ivideo.DstColor);
-       SiS300SetupSRCPitch(ivideo.video_linelength)
-       SiS300SetupDSTRect(ivideo.video_linelength, -1)
+       SiS300SetupDSTColorDepth(ivideo->DstColor);
+       SiS300SetupSRCPitch(ivideo->video_linelength)
+       SiS300SetupDSTRect(ivideo->video_linelength, 0xffff)
 
        if(trans_color != -1) {
                SiS300SetupROP(0x0A)
@@ -159,29 +130,28 @@ SiS300SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
 }
 
 static void
-SiS300SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
-                                int width, int height)
+SiS300SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x,
+                                  int src_y, int dst_x, int dst_y, int width, int height)
 {
-       long srcbase, dstbase;
+       u32 srcbase = 0, dstbase = 0;
 
-       srcbase = dstbase = 0;
-       if (src_y >= 2048) {
-               srcbase = ivideo.video_linelength * src_y;
+       if(src_y >= 2048) {
+               srcbase = ivideo->video_linelength * src_y;
                src_y = 0;
        }
-       if (dst_y >= 2048) {
-               dstbase = ivideo.video_linelength * dst_y;
+       if(dst_y >= 2048) {
+               dstbase = ivideo->video_linelength * dst_y;
                dst_y = 0;
        }
 
        SiS300SetupSRCBase(srcbase);
        SiS300SetupDSTBase(dstbase);
 
-       if(!(ivideo.CommandReg & X_INC))  {
+       if(!(ivideo->CommandReg & X_INC))  {
                src_x += width-1;
                dst_x += width-1;
        }
-       if(!(ivideo.CommandReg & Y_INC))  {
+       if(!(ivideo->CommandReg & Y_INC))  {
                src_y += height-1;
                dst_y += height-1;
        }
@@ -192,23 +162,22 @@ SiS300SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
 }
 
 static void
-SiS300SetupForSolidFill(int color, int rop, unsigned int planemask)
+SiS300SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop)
 {
        SiS300SetupPATFG(color)
-       SiS300SetupDSTRect(ivideo.video_linelength, -1)
-       SiS300SetupDSTColorDepth(ivideo.DstColor);
+       SiS300SetupDSTRect(ivideo->video_linelength, 0xffff)
+       SiS300SetupDSTColorDepth(ivideo->DstColor);
        SiS300SetupROP(sisPatALUConv[rop])
        SiS300SetupCMDFlag(PATFG)
 }
 
 static void
-SiS300SubsequentSolidFillRect(int x, int y, int w, int h)
+SiS300SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w, int h)
 {
-       long dstbase;
+       u32 dstbase = 0;
 
-       dstbase = 0;
        if(y >= 2048) {
-               dstbase = ivideo.video_linelength * y;
+               dstbase = ivideo->video_linelength * y;
                y = 0;
        }
        SiS300SetupDSTBase(dstbase)
@@ -223,19 +192,18 @@ SiS300SubsequentSolidFillRect(int x, int y, int w, int h)
 
 #ifdef CONFIG_FB_SIS_315
 static void
-SiS310Sync(void)
+SiS310Sync(struct sis_video_info *ivideo)
 {
        SiS310Idle
 }
 
 static void
-SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
-                                unsigned int planemask, int trans_color)
+SiS310SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int rop, int trans_color)
 {
-       SiS310SetupDSTColorDepth(ivideo.DstColor);
-       SiS310SetupSRCPitch(ivideo.video_linelength)
-       SiS310SetupDSTRect(ivideo.video_linelength, -1)
-       if (trans_color != -1) {
+       SiS310SetupDSTColorDepth(ivideo->DstColor);
+       SiS310SetupSRCPitch(ivideo->video_linelength)
+       SiS310SetupDSTRect(ivideo->video_linelength, 0xffff)
+       if(trans_color != -1) {
                SiS310SetupROP(0x0A)
                SiS310SetupSRCTrans(trans_color)
                SiS310SetupCMDFlag(TRANSPARENT_BITBLT)
@@ -244,20 +212,17 @@ SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
                /* Set command - not needed, both 0 */
                /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
        }
-       SiS310SetupCMDFlag(ivideo.SiS310_AccelDepth)
+       SiS310SetupCMDFlag(ivideo->SiS310_AccelDepth)
        /* The 315 series is smart enough to know the direction */
 }
 
 static void
-SiS310SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
-                                int width, int height)
+SiS310SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x, int src_y,
+                        int dst_x, int dst_y, int width, int height)
 {
-       long srcbase, dstbase;
-       int mymin, mymax;
-
-       srcbase = dstbase = 0;
-       mymin = min(src_y, dst_y);
-       mymax = max(src_y, dst_y);
+       u32 srcbase = 0, dstbase = 0;
+       int mymin = min(src_y, dst_y);
+       int mymax = max(src_y, dst_y);
        
        /* Although the chip knows the direction to use
         * if the source and destination areas overlap, 
@@ -271,18 +236,18 @@ SiS310SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
         */
        if((mymax - mymin) < height) { 
           if((src_y >= 2048) || (dst_y >= 2048)) {           
-             srcbase = ivideo.video_linelength * mymin;
-             dstbase = ivideo.video_linelength * mymin;
+             srcbase = ivideo->video_linelength * mymin;
+             dstbase = ivideo->video_linelength * mymin;
              src_y -= mymin;
              dst_y -= mymin;
           }
        } else {
           if(src_y >= 2048) {
-             srcbase = ivideo.video_linelength * src_y;
+             srcbase = ivideo->video_linelength * src_y;
              src_y = 0;
           }
           if(dst_y >= 2048) {
-             dstbase = ivideo.video_linelength * dst_y;
+             dstbase = ivideo->video_linelength * dst_y;
              dst_y = 0;
           }
        }
@@ -296,23 +261,22 @@ SiS310SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
 }
 
 static void
-SiS310SetupForSolidFill(int color, int rop, unsigned int planemask)
+SiS310SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop)
 {
        SiS310SetupPATFG(color)
-       SiS310SetupDSTRect(ivideo.video_linelength, -1)
-       SiS310SetupDSTColorDepth(ivideo.DstColor);
+       SiS310SetupDSTRect(ivideo->video_linelength, 0xffff)
+       SiS310SetupDSTColorDepth(ivideo->DstColor);
        SiS310SetupROP(sisPatALUConv[rop])
-       SiS310SetupCMDFlag(PATFG | ivideo.SiS310_AccelDepth)
+       SiS310SetupCMDFlag(PATFG | ivideo->SiS310_AccelDepth)
 }
 
 static void
-SiS310SubsequentSolidFillRect(int x, int y, int w, int h)
+SiS310SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w, int h)
 {
-       long dstbase;
+       u32 dstbase = 0;
 
-       dstbase = 0;
        if(y >= 2048) {
-               dstbase = ivideo.video_linelength * y;
+               dstbase = ivideo->video_linelength * y;
                y = 0;
        }
        SiS310SetupDSTBase(dstbase)
@@ -327,23 +291,23 @@ SiS310SubsequentSolidFillRect(int x, int y, int w, int h)
 
 /* The exported routines */
 
-int sisfb_initaccel(void)
+int sisfb_initaccel(struct sis_video_info *ivideo)
 {
 #ifdef SISFB_USE_SPINLOCKS
-    spin_lock_init(&ivideo.lockaccel);
+    spin_lock_init(&ivideo->lockaccel);
 #endif
     return(0);
 }
 
-void sisfb_syncaccel(void)
+void sisfb_syncaccel(struct sis_video_info *ivideo)
 {
-    if(sisvga_engine == SIS_300_VGA) {
+    if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
-       SiS300Sync();
+       SiS300Sync(ivideo);
 #endif
     } else {
 #ifdef CONFIG_FB_SIS_315
-       SiS310Sync();
+       SiS310Sync(ivideo);
 #endif
     }
 }
@@ -352,18 +316,19 @@ void sisfb_syncaccel(void)
 
 int fbcon_sis_sync(struct fb_info *info)
 {
+   struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
    CRITFLAGS
 
-   if(!ivideo.accel)
+   if(!ivideo->accel)
        return 0;
 
-   if(sisvga_engine == SIS_300_VGA) {
+   if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
-      SiS300Sync();
+      SiS300Sync(ivideo);
 #endif
    } else {
 #ifdef CONFIG_FB_SIS_315
-      SiS310Sync();
+      SiS310Sync(ivideo);
 #endif
    }
    CRITEND
@@ -372,42 +337,53 @@ int fbcon_sis_sync(struct fb_info *info)
 
 void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
-   int col=0;
+   struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+   u32 col = 0;
+   u32 vxres = info->var.xres_virtual;
+   u32 vyres = info->var.yres_virtual;
+   int width, height;
    CRITFLAGS
 
-   TWDEBUG("Inside sis_fillrect");
-   if(!rect->width || !rect->height)
-       return;
+   if(info->state != FBINFO_STATE_RUNNING) {
+       return;
+   }
 
-   if(!ivideo.accel) {
+   if(!ivideo->accel) {
        cfb_fillrect(info, rect);
        return;
    }
    
+   if(!rect->width || !rect->height || rect->dx >= vxres || rect->dy >= vyres) {
+       return;
+   }
+
+   /* Clipping */
+   width = ((rect->dx + rect->width) > vxres) ? (vxres - rect->dx) : rect->width;
+   height = ((rect->dy + rect->height) > vyres) ? (vyres - rect->dy) : rect->height;
+
    switch(info->var.bits_per_pixel) {
        case 8:  col = rect->color;
                 break;
-       case 16: col = ((u32 *)(info->pseudo_palette))[rect->color];
-                break;
+       case 16:
        case 32: col = ((u32 *)(info->pseudo_palette))[rect->color];
                 break;
    }
 
-   if(sisvga_engine == SIS_300_VGA) {
+   if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
       CRITBEGIN
-      SiS300SetupForSolidFill(col, myrops[rect->rop], 0);
-      SiS300SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
+      SiS300SetupForSolidFill(ivideo, col, myrops[rect->rop]);
+      SiS300SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
       CRITEND
-      SiS300Sync();
+      SiS300Sync(ivideo);
 #endif
    } else {
 #ifdef CONFIG_FB_SIS_315
       CRITBEGIN
-      SiS310SetupForSolidFill(col, myrops[rect->rop], 0);
-      SiS310SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
+      SiS310SetupForSolidFill(ivideo, col, myrops[rect->rop]);
+      SiS310SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
       CRITEND
-      SiS310Sync();
+      SiS310Sync(ivideo);
 #endif
    }
 
@@ -415,38 +391,58 @@ 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)
 {
-   int xdir, ydir;
+   struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+   u32 vxres = info->var.xres_virtual;
+   u32 vyres = info->var.yres_virtual;
+   int width = area->width;
+   int height = area->height;
    CRITFLAGS
 
-   TWDEBUG("Inside sis_copyarea");
-   if(!ivideo.accel) {
+   if(info->state != FBINFO_STATE_RUNNING) {
+       return;
+   }
+
+   if(!ivideo->accel) {
        cfb_copyarea(info, area);
        return;
    }
 
-   if(!area->width || !area->height)
+   if(!width || !height ||
+      area->sx >= vxres || area->sy >= vyres ||
+      area->dx >= vxres || area->dy >= vyres) {
        return;
+   }
 
-   if(area->sx < area->dx) xdir = 0;
-   else                    xdir = 1;
-   if(area->sy < area->dy) ydir = 0;
-   else                    ydir = 1;
+   /* Clipping */
+   if((area->sx + width) > vxres) width = vxres - area->sx;
+   if((area->dx + width) > vxres) width = vxres - area->dx;
+   if((area->sy + height) > vyres) height = vyres - area->sy;
+   if((area->dy + height) > vyres) height = vyres - area->dy;
 
-   if(sisvga_engine == SIS_300_VGA) {
+   if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
+      int xdir, ydir;
+
+      if(area->sx < area->dx) xdir = 0;
+      else                    xdir = 1;
+      if(area->sy < area->dy) ydir = 0;
+      else                    ydir = 1;
+
       CRITBEGIN
-      SiS300SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
-      SiS300SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height);
+      SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
+      SiS300SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
+                                        width, height);
       CRITEND
-      SiS300Sync();
+      SiS300Sync(ivideo);
 #endif
    } else {
 #ifdef CONFIG_FB_SIS_315
       CRITBEGIN
-      SiS310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
-      SiS310SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height);
+      SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
+      SiS310SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
+                                        width, height);
       CRITEND
-      SiS310Sync();
+      SiS310Sync(ivideo);
 #endif
    }
 }
@@ -458,11 +454,12 @@ void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
                            int dsty, int dstx, int height, int width)
 {
-        int xdir, ydir;
+       struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
+
        CRITFLAGS
 
-       if(!ivideo.accel) {
-           switch(ivideo.video_bpp) {
+       if(!ivideo->accel) {
+           switch(ivideo->video_bpp) {
            case 8:
 #ifdef FBCON_HAS_CFB8
               fbcon_cfb8_bmove(p, srcy, srcx, dsty, dstx, height, width);
@@ -489,30 +486,28 @@ void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
        width *= fontwidth(p);
        height *= fontheight(p);
 
-       if(srcx < dstx) xdir = 0;
-       else            xdir = 1;
-       if(srcy < dsty) ydir = 0;
-       else            ydir = 1;
-
-       if(sisvga_engine == SIS_300_VGA) {
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
+          int xdir, ydir;
+
+          if(srcx < dstx) xdir = 0;
+          else            xdir = 1;
+          if(srcy < dsty) ydir = 0;
+          else            ydir = 1;
+
           CRITBEGIN
-          SiS300SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
-          SiS300SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
+          SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
+          SiS300SubsequentScreenToScreenCopy(ivideo, srcx, srcy, dstx, dsty, width, height);
           CRITEND
-          SiS300Sync();
+          SiS300Sync(ivideo);
 #endif
        } else {
 #ifdef CONFIG_FB_SIS_315
           CRITBEGIN
-          SiS310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
-          SiS310SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
+          SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
+          SiS310SubsequentScreenToScreenCopy(ivideo, srcx, srcy, dstx, dsty, width, height);
           CRITEND
-          SiS310Sync();
-#if 0
-          printk(KERN_INFO "sis_bmove sx %d sy %d dx %d dy %d w %d h %d\n",
-               srcx, srcy, dstx, dsty, width, height);
-#endif
+          SiS310Sync(ivideo);
 #endif
        }
 }
@@ -520,6 +515,7 @@ void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
 static void fbcon_sis_clear(struct vc_data *conp, struct display *p,
                        int srcy, int srcx, int height, int width, int color)
 {
+        struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
        CRITFLAGS
 
        srcx *= fontwidth(p);
@@ -527,21 +523,21 @@ static void fbcon_sis_clear(struct vc_data *conp, struct display *p,
        width *= fontwidth(p);
        height *= fontheight(p);
 
-       if(sisvga_engine == SIS_300_VGA) {
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
           CRITBEGIN
-          SiS300SetupForSolidFill(color, 3, 0);
-          SiS300SubsequentSolidFillRect(srcx, srcy, width, height);
+          SiS300SetupForSolidFill(ivideo, color, 3);
+          SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, width, height);
           CRITEND
-          SiS300Sync();
+          SiS300Sync(ivideo);
 #endif
        } else {
 #ifdef CONFIG_FB_SIS_315
           CRITBEGIN
-          SiS310SetupForSolidFill(color, 3, 0);
-          SiS310SubsequentSolidFillRect(srcx, srcy, width, height);
+          SiS310SetupForSolidFill(ivideo, color, 3);
+          SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, width, height);
           CRITEND
-          SiS310Sync();
+          SiS310Sync(ivideo);
 #endif
        }
 }
@@ -549,9 +545,10 @@ static void fbcon_sis_clear(struct vc_data *conp, struct display *p,
 void fbcon_sis_clear8(struct vc_data *conp, struct display *p,
                        int srcy, int srcx, int height, int width)
 {
+       struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
        u32 bgx;
 
-       if(!ivideo.accel) {
+       if(!ivideo->accel) {
 #ifdef FBCON_HAS_CFB8
            fbcon_cfb8_clear(conp, p, srcy, srcx, height, width);
 #endif
@@ -565,8 +562,10 @@ void fbcon_sis_clear8(struct vc_data *conp, struct display *p,
 void fbcon_sis_clear16(struct vc_data *conp, struct display *p,
                        int srcy, int srcx, int height, int width)
 {
+        struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
        u32 bgx;
-       if(!ivideo.accel) {
+
+       if(!ivideo->accel) {
 #ifdef FBCON_HAS_CFB16
            fbcon_cfb16_clear(conp, p, srcy, srcx, height, width);
 #endif
@@ -580,9 +579,10 @@ void fbcon_sis_clear16(struct vc_data *conp, struct display *p,
 void fbcon_sis_clear32(struct vc_data *conp, struct display *p,
                        int srcy, int srcx, int height, int width)
 {
+       struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
        u32 bgx;
 
-       if(!ivideo.accel) {
+       if(!ivideo->accel) {
 #ifdef FBCON_HAS_CFB32
            fbcon_cfb32_clear(conp, p, srcy, srcx, height, width);
 #endif
@@ -595,10 +595,11 @@ void fbcon_sis_clear32(struct vc_data *conp, struct display *p,
 
 void fbcon_sis_revc(struct display *p, int srcx, int srcy)
 {
+       struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
        CRITFLAGS
 
-       if(!ivideo.accel) {
-           switch(ivideo.video_bpp) {
+       if(!ivideo->accel) {
+           switch(ivideo->video_bpp) {
            case 16:
 #ifdef FBCON_HAS_CFB16
               fbcon_cfb16_revc(p, srcx, srcy);
@@ -616,59 +617,59 @@ void fbcon_sis_revc(struct display *p, int srcx, int srcy)
        srcx *= fontwidth(p);
        srcy *= fontheight(p);
 
-       if(sisvga_engine == SIS_300_VGA) {
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
           CRITBEGIN
-          SiS300SetupForSolidFill(0, 0x0a, 0);
-          SiS300SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
+          SiS300SetupForSolidFill(ivideo, 0, 0x0a);
+          SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
           CRITEND
-          SiS300Sync();
+          SiS300Sync(ivideo);
 #endif
        } else {
 #ifdef CONFIG_FB_SIS_315
           CRITBEGIN
-          SiS310SetupForSolidFill(0, 0x0a, 0);
-          SiS310SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
+          SiS310SetupForSolidFill(ivideo, 0, 0x0a);
+          SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
           CRITEND
-          SiS310Sync();
+          SiS310Sync(ivideo);
 #endif
        }
 }
 
 #ifdef FBCON_HAS_CFB8
 struct display_switch fbcon_sis8 = {
-       .setup                  = fbcon_cfb8_setup,
-       .bmove                  = fbcon_sis_bmove,
-       .clear                  = fbcon_sis_clear8,
-       .putc                   = fbcon_cfb8_putc,
-       .putcs                  = fbcon_cfb8_putcs,
-       .revc                   = fbcon_cfb8_revc,
-       .clear_margins          = fbcon_cfb8_clear_margins,
-       .fontwidthmask          = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+       .setup          = fbcon_cfb8_setup,
+       .bmove          = fbcon_sis_bmove,
+       .clear          = fbcon_sis_clear8,
+       .putc           = fbcon_cfb8_putc,
+       .putcs          = fbcon_cfb8_putcs,
+       .revc           = fbcon_cfb8_revc,
+       .clear_margins  = fbcon_cfb8_clear_margins,
+       .fontwidthmask  = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 #ifdef FBCON_HAS_CFB16
 struct display_switch fbcon_sis16 = {
-       .setup                  = fbcon_cfb16_setup,
-       .bmove                  = fbcon_sis_bmove,
-       .clear                  = fbcon_sis_clear16,
-       .putc                   = fbcon_cfb16_putc,
-       .putcs                  = fbcon_cfb16_putcs,
-       .revc                   = fbcon_sis_revc,
-       .clear_margins          = fbcon_cfb16_clear_margins,
-       .fontwidthmask          = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+       .setup          = fbcon_cfb16_setup,
+       .bmove          = fbcon_sis_bmove,
+       .clear          = fbcon_sis_clear16,
+       .putc           = fbcon_cfb16_putc,
+       .putcs          = fbcon_cfb16_putcs,
+       .revc           = fbcon_sis_revc,
+       .clear_margins  = fbcon_cfb16_clear_margins,
+       .fontwidthmask  = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 #ifdef FBCON_HAS_CFB32
 struct display_switch fbcon_sis32 = {
-       .setup                  = fbcon_cfb32_setup,
-       .bmove                  = fbcon_sis_bmove,
-       .clear                  = fbcon_sis_clear32,
-       .putc                   = fbcon_cfb32_putc,
-       .putcs                  = fbcon_cfb32_putcs,
-       .revc                   = fbcon_sis_revc,
-       .clear_margins          = fbcon_cfb32_clear_margins,
-       .fontwidthmask          = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+       .setup          = fbcon_cfb32_setup,
+       .bmove          = fbcon_sis_bmove,
+       .clear          = fbcon_sis_clear32,
+       .putc           = fbcon_cfb32_putc,
+       .putcs          = fbcon_cfb32_putcs,
+       .revc           = fbcon_sis_revc,
+       .clear_margins  = fbcon_cfb32_clear_margins,
+       .fontwidthmask  = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 
index f922968..bb28f33 100644 (file)
@@ -36,8 +36,8 @@
 
 #ifdef SISFB_USE_SPINLOCKS
 #include <linux/spinlock.h>
-#define CRITBEGIN  spin_lock_irqsave(&ivideo.lockaccel), critflags);
-#define CRITEND           spin_unlock_irqrestore(&ivideo.lockaccel), critflags);
+#define CRITBEGIN  spin_lock_irqsave(&ivideo->lockaccel, critflags);
+#define CRITEND           spin_unlock_irqrestore(&ivideo->lockaccel, critflags);
 #define CRITFLAGS  unsigned long critflags;
 #else
 #define CRITBEGIN
@@ -65,7 +65,6 @@
 #define A3D_FUNCTION           0x00000008  /* 3D command ? */
 #define        CLEAR_Z_BUFFER          0x00000009  /* ? */
 #define GRADIENT_FILL          0x0000000A  /* Gradient fill */
-#define STRETCH_BITBLT         0x0000000B  /* Stretched Blit */
 
 /* source select */
 #define SRCVIDEO                0x00000000  /* source is video RAM */
 #define DSTAGP                  0x02000000
 #define DSTVIDEO                0x02000000
 
-/* Line */
-#define LINE_STYLE              0x00800000
-#define NO_RESET_COUNTER        0x00400000
-#define NO_LAST_PIXEL           0x00200000
-
 /* Subfunctions for Color/Enhanced Color Expansion (315 only) */
 #define COLOR_TO_MONO          0x00100000
 #define AA_TEXT                        0x00200000
 
 #define PATTERN_REG            0x8300  /* 384 bytes pattern buffer */
 
-/* Line registers */
-#define LINE_X0                        SRC_Y
-#define LINE_X1                        DST_Y
-#define LINE_Y0                        SRC_X
-#define LINE_Y1                        DST_X
-#define LINE_COUNT             RECT_WIDTH
-#define LINE_STYLE_PERIOD      RECT_HEIGHT
-#define LINE_STYLE_0           MONO_MASK
-#define LINE_STYLE_1           0x8230
-#define LINE_XN                        PATTERN_REG
-#define LINE_YN                        PATTERN_REG+2
-
 /* Transparent bitblit registers */
 #define TRANS_DST_KEY_HIGH     PAT_FGCOLOR
 #define TRANS_DST_KEY_LOW      PAT_BGCOLOR
 #define TRANS_SRC_KEY_HIGH     SRC_FGCOLOR
 #define TRANS_SRC_KEY_LOW      SRC_BGCOLOR
 
-/* Queue */
-#define Q_BASE_ADDR            0x85C0  /* Base address of software queue (?) */
-#define Q_WRITE_PTR            0x85C4  /* Current write pointer (?) */
-#define Q_READ_PTR             0x85C8  /* Current read pointer (?) */
-#define Q_STATUS               0x85CC  /* queue status */
-
-
-#define MMIO_IN8(base, offset) \
-       *(volatile u8 *)(((u8*)(base)) + (offset))
-#define MMIO_IN16(base, offset) \
-       *(volatile u16 *)(void *)(((u8*)(base)) + (offset))
-#define MMIO_IN32(base, offset) \
-       *(volatile u32 *)(void *)(((u8*)(base)) + (offset))
-#define MMIO_OUT8(base, offset, val) \
-       *(volatile u8 *)(((u8*)(base)) + (offset)) = (val)
-#define MMIO_OUT16(base, offset, val) \
-       *(volatile u16 *)(void *)(((u8*)(base)) + (offset)) = (val)
-#define MMIO_OUT32(base, offset, val) \
-       *(volatile u32 *)(void *)(((u8*)(base)) + (offset)) = (val)
+/* Store queue length in par */
+#define CmdQueLen ivideo->cmdqueuelength
 
 /* ------------- SiS 300 series -------------- */
 
-/* Macros to do useful things with the SIS BitBLT engine */
-
-/* BR(16) (0x8420):
+/* BR(16) (0x8240):
 
    bit 31 2D engine: 1 is idle,
    bit 30 3D engine: 1 is idle,
    bit 29 Command queue: 1 is empty
-
    bits 28:24: Current CPU driven BitBlt buffer stage bit[4:0]
-
    bits 15:0:  Current command queue length
 
 */
 
-/* TW: BR(16)+2 = 0x8242 */
-
-int     CmdQueLen;
-
 #define SiS300Idle \
   { \
-  while( (MMIO_IN16(ivideo.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
-  while( (MMIO_IN16(ivideo.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
-  while( (MMIO_IN16(ivideo.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
-  CmdQueLen=MMIO_IN16(ivideo.mmio_vbase, 0x8240); \
+       while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
+       while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
+       while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
+       CmdQueLen = MMIO_IN16(ivideo->mmio_vbase, 0x8240); \
   }
-/* TW: (do three times, because 2D engine seems quite unsure about whether or not it's idle) */
+/* (do three times, because 2D engine seems quite unsure about whether or not it's idle) */
 
 #define SiS300SetupSRCBase(base) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(0), base);\
-                CmdQueLen --;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(0), base);\
+       CmdQueLen--;
 
 #define SiS300SetupSRCPitch(pitch) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT16(ivideo.mmio_vbase, BR(1), pitch);\
-                CmdQueLen --;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT16(ivideo->mmio_vbase, BR(1), pitch);\
+       CmdQueLen--;
 
 #define SiS300SetupSRCXY(x,y) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(2), (x)<<16 | (y) );\
-                CmdQueLen --;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(2), (x)<<16 | (y) );\
+       CmdQueLen--;
 
 #define SiS300SetupDSTBase(base) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(4), base);\
-                CmdQueLen --;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(4), base);\
+       CmdQueLen--;
 
 #define SiS300SetupDSTXY(x,y) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(3), (x)<<16 | (y) );\
-                CmdQueLen --;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(3), (x)<<16 | (y) );\
+       CmdQueLen--;
 
 #define SiS300SetupDSTRect(x,y) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(5), (y)<<16 | (x) );\
-                CmdQueLen --;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(5), (y)<<16 | (x) );\
+       CmdQueLen--;
 
 #define SiS300SetupDSTColorDepth(bpp) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT16(ivideo.mmio_vbase, BR(1)+2, bpp);\
-                CmdQueLen --;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT16(ivideo->mmio_vbase, BR(1)+2, bpp);\
+       CmdQueLen--;
 
 #define SiS300SetupRect(w,h) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(6), (h)<<16 | (w) );\
-                CmdQueLen --;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(6), (h)<<16 | (w) );\
+       CmdQueLen--;
 
 #define SiS300SetupPATFG(color) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(7), color);\
-                CmdQueLen --;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(7), color);\
+       CmdQueLen--;
 
 #define SiS300SetupPATBG(color) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(8), color);\
-                CmdQueLen --;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(8), color);\
+       CmdQueLen--;
 
 #define SiS300SetupSRCFG(color) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(9), color);\
-                CmdQueLen --;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(9), color);\
+       CmdQueLen--;
 
 #define SiS300SetupSRCBG(color) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(10), color);\
-                CmdQueLen --;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(10), color);\
+       CmdQueLen--;
 
 /* 0x8224 src colorkey high */
 /* 0x8228 src colorkey low */
 /* 0x821c dest colorkey high */
 /* 0x8220 dest colorkey low */
 #define SiS300SetupSRCTrans(color) \
-                if (CmdQueLen <= 1)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, 0x8224, color);\
-               MMIO_OUT32(ivideo.mmio_vbase, 0x8228, color);\
-               CmdQueLen -= 2;
+       if(CmdQueLen <= 1) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, 0x8224, color);\
+       MMIO_OUT32(ivideo->mmio_vbase, 0x8228, color);\
+       CmdQueLen -= 2;
 
 #define SiS300SetupDSTTrans(color) \
-               if (CmdQueLen <= 1)  SiS300Idle;\
-               MMIO_OUT32(ivideo.mmio_vbase, 0x821C, color); \
-               MMIO_OUT32(ivideo.mmio_vbase, 0x8220, color); \
-                CmdQueLen -= 2;
+       if(CmdQueLen <= 1) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, 0x821C, color); \
+       MMIO_OUT32(ivideo->mmio_vbase, 0x8220, color); \
+       CmdQueLen -= 2;
 
 #define SiS300SetupMONOPAT(p0,p1) \
-                if (CmdQueLen <= 1)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(11), p0);\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(12), p1);\
-                CmdQueLen -= 2;
+       if(CmdQueLen <= 1) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(11), p0);\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(12), p1);\
+       CmdQueLen -= 2;
 
 #define SiS300SetupClipLT(left,top) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(13), ((left) & 0xFFFF) | (top)<<16 );\
-                CmdQueLen--;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(13), ((left) & 0xFFFF) | (top)<<16 );\
+       CmdQueLen--;
 
 #define SiS300SetupClipRB(right,bottom) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(14), ((right) & 0xFFFF) | (bottom)<<16 );\
-                CmdQueLen--;
+       if(CmdQueLen <= 0) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(14), ((right) & 0xFFFF) | (bottom)<<16 );\
+       CmdQueLen--;
 
 /* General */
 #define SiS300SetupROP(rop) \
-                ivideo.CommandReg = (rop) << 8;
+       ivideo->CommandReg = (rop) << 8;
 
 #define SiS300SetupCMDFlag(flags) \
-                ivideo.CommandReg |= (flags);
+       ivideo->CommandReg |= (flags);
 
 #define SiS300DoCMD \
-                if (CmdQueLen <= 1)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(15), ivideo.CommandReg); \
-                MMIO_OUT32(ivideo.mmio_vbase, BR(16), 0);\
-                CmdQueLen -= 2;
-
-/* Line */
-#define SiS300SetupX0Y0(x,y) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(2), (y)<<16 | (x) );\
-                CmdQueLen--;
-
-#define SiS300SetupX1Y1(x,y) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(3), (y)<<16 | (x) );\
-                CmdQueLen--;
-
-#define SiS300SetupLineCount(c) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT16(ivideo.mmio_vbase, BR(6), c);\
-                CmdQueLen--;
+       if(CmdQueLen <= 1) SiS300Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, BR(15), ivideo->CommandReg); \
+       MMIO_OUT32(ivideo->mmio_vbase, BR(16), 0);\
+       CmdQueLen -= 2;
 
-#define SiS300SetupStylePeriod(p) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT16(ivideo.mmio_vbase, BR(6)+2, p);\
-                CmdQueLen--;
-
-#define SiS300SetupStyleLow(ls) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(11), ls);\
-                CmdQueLen--;
-
-#define SiS300SetupStyleHigh(ls) \
-                if (CmdQueLen <= 0)  SiS300Idle;\
-                MMIO_OUT32(ivideo.mmio_vbase, BR(12), ls);\
-                CmdQueLen--;
-
-
-
-/* -------------- SiS 315 series --------------- */
+/* -------------- SiS 315/330 series --------------- */
 
 /* Q_STATUS:
    bit 31 = 1: All engines idle and all queues empty
@@ -353,179 +277,131 @@ int     CmdQueLen;
    bits 23:16: 2D counter 3
    bits 15:8:  2D counter 2
    bits 7:0:   2D counter 1
-
-   Where is the command queue length (current amount of commands the queue
-   can accept) on the 315 series?
 */
 
-/* TW: FIXME: CmdQueLen is... where....? */
-/* We assume a length of 4 bytes per command; since 512K of
- * of RAM are allocated, the number of commands is easily
- * calculated (assuming that there is no 3D support yet)
- * We calculate it very cautiously (128K only) and let the
- * rest to the (never?)-to-come (?) 3D engine. (The 3D engine
- * can use a similar technique, using the remaining 384K,
- * hence a queue overflow is avoided)
- * UPDATE: This technique causes a terrible system latency
- * on integrated chipsets. Disable the queue handling for
- * now.
- */
 #define SiS310Idle \
   { \
-  while( (MMIO_IN16(ivideo.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
-  while( (MMIO_IN16(ivideo.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
-  CmdQueLen = 0; \
-  /*CmdQueLen = ((128 * 1024) / 4) - 64; */ \
+       while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+       while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+       CmdQueLen = 0; \
   }
 
 #define SiS310SetupSRCBase(base) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, SRC_ADDR, base);\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, SRC_ADDR, base);\
+       CmdQueLen--;
 
 #define SiS310SetupSRCPitch(pitch) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT16(ivideo.mmio_vbase, SRC_PITCH, pitch);\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT16(ivideo->mmio_vbase, SRC_PITCH, pitch);\
+       CmdQueLen--;
 
 #define SiS310SetupSRCXY(x,y) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, SRC_Y, (x)<<16 | (y) );\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, SRC_Y, (x)<<16 | (y) );\
+       CmdQueLen--;
 
 #define SiS310SetupDSTBase(base) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, DST_ADDR, base);\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, DST_ADDR, base);\
+       CmdQueLen--;
 
 #define SiS310SetupDSTXY(x,y) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, DST_Y, (x)<<16 | (y) );\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, DST_Y, (x)<<16 | (y) );\
+       CmdQueLen--;
 
 #define SiS310SetupDSTRect(x,y) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, DST_PITCH, (y)<<16 | (x) );\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, DST_PITCH, (y)<<16 | (x) );\
+       CmdQueLen--;
 
 #define SiS310SetupDSTColorDepth(bpp) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT16(ivideo.mmio_vbase, AGP_BASE, bpp);\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT16(ivideo->mmio_vbase, AGP_BASE, bpp);\
+       CmdQueLen--;
 
 #define SiS310SetupRect(w,h) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, RECT_WIDTH, (h)<<16 | (w) );\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, RECT_WIDTH, (h)<<16 | (w) );\
+       CmdQueLen--;
 
 #define SiS310SetupPATFG(color) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, PAT_FGCOLOR, color);\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, PAT_FGCOLOR, color);\
+       CmdQueLen--;
 
 #define SiS310SetupPATBG(color) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, PAT_BGCOLOR, color);\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, PAT_BGCOLOR, color);\
+       CmdQueLen--;
 
 #define SiS310SetupSRCFG(color) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, SRC_FGCOLOR, color);\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, SRC_FGCOLOR, color);\
+       CmdQueLen--;
 
 #define SiS310SetupSRCBG(color) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, SRC_BGCOLOR, color);\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, SRC_BGCOLOR, color);\
+       CmdQueLen--;
 
 #define SiS310SetupSRCTrans(color) \
-      if (CmdQueLen <= 1)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, TRANS_SRC_KEY_HIGH, color);\
-      MMIO_OUT32(ivideo.mmio_vbase, TRANS_SRC_KEY_LOW, color);\
-      CmdQueLen -= 2;
+       if(CmdQueLen <= 1) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, TRANS_SRC_KEY_HIGH, color);\
+       MMIO_OUT32(ivideo->mmio_vbase, TRANS_SRC_KEY_LOW, color);\
+       CmdQueLen -= 2;
 
 #define SiS310SetupDSTTrans(color) \
-      if (CmdQueLen <= 1)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, TRANS_DST_KEY_HIGH, color); \
-      MMIO_OUT32(ivideo.mmio_vbase, TRANS_DST_KEY_LOW, color); \
-      CmdQueLen -= 2;
+       if(CmdQueLen <= 1) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, TRANS_DST_KEY_HIGH, color); \
+       MMIO_OUT32(ivideo->mmio_vbase, TRANS_DST_KEY_LOW, color); \
+       CmdQueLen -= 2;
 
 #define SiS310SetupMONOPAT(p0,p1) \
-      if (CmdQueLen <= 1)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, MONO_MASK, p0);\
-      MMIO_OUT32(ivideo.mmio_vbase, MONO_MASK+4, p1);\
-      CmdQueLen -= 2;
+       if(CmdQueLen <= 1) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, MONO_MASK, p0);\
+       MMIO_OUT32(ivideo->mmio_vbase, MONO_MASK+4, p1);\
+       CmdQueLen -= 2;
 
 #define SiS310SetupClipLT(left,top) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16 );\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16 );\
+       CmdQueLen--;
 
 #define SiS310SetupClipRB(right,bottom) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16 );\
-      CmdQueLen--;
+       if(CmdQueLen <= 0) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16 );\
+       CmdQueLen--;
 
 #define SiS310SetupROP(rop) \
-      ivideo.CommandReg = (rop) << 8;
+       ivideo->CommandReg = (rop) << 8;
 
 #define SiS310SetupCMDFlag(flags) \
-      ivideo.CommandReg |= (flags);
+       ivideo->CommandReg |= (flags);
 
 #define SiS310DoCMD \
-      if (CmdQueLen <= 1)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, COMMAND_READY, ivideo.CommandReg); \
-      MMIO_OUT32(ivideo.mmio_vbase, FIRE_TRIGGER, 0); \
-      CmdQueLen -= 2;
-
-#define SiS310SetupX0Y0(x,y) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, LINE_X0, (y)<<16 | (x) );\
-      CmdQueLen--;
-
-#define SiS310SetupX1Y1(x,y) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, LINE_X1, (y)<<16 | (x) );\
-      CmdQueLen--;
-
-#define SiS310SetupLineCount(c) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT16(ivideo.mmio_vbase, LINE_COUNT, c);\
-      CmdQueLen--;
-
-#define SiS310SetupStylePeriod(p) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT16(ivideo.mmio_vbase, LINE_STYLE_PERIOD, p);\
-      CmdQueLen--;
-
-#define SiS310SetupStyleLow(ls) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, LINE_STYLE_0, ls);\
-      CmdQueLen--;
-
-#define SiS310SetupStyleHigh(ls) \
-      if (CmdQueLen <= 0)  SiS310Idle;\
-      MMIO_OUT32(ivideo.mmio_vbase, LINE_STYLE_1, ls);\
-      CmdQueLen--;
-
-int  sisfb_initaccel(void);
-void sisfb_syncaccel(void);
-
-extern struct video_info ivideo;
+       if(CmdQueLen <= 1) SiS310Idle;\
+       MMIO_OUT32(ivideo->mmio_vbase, COMMAND_READY, ivideo->CommandReg); \
+       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);
+                       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);
+                       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);
+                       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);
+                       int srcx, int height, int width);
 #endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
-extern int sisfb_accel;
 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
index 960cdbb..aa1f313 100644 (file)
@@ -1,6 +1,7 @@
 /*
- * SiS 300/630/730/540/315/550/650/651/M650/661FX/M661FX/740/741/M741/330/760
- * frame buffer driver for Linux kernels 2.4.x and 2.5.x
+ * SiS 300/305/540/630(S)/730(S)
+ * SiS 315(H/PRO)/55x/(M)65x/(M)661(F/M)X/740/741(GX)/330/(M)760
+ * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
  *
  * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
  *
@@ -20,8 +21,8 @@
  *
  * Author:     Thomas Winischhofer <thomas@winischhofer.net>
  *
- * Author of code base:
- *             SiS (www.sis.com.tw)
+ * Author of (practically wiped) code base:
+ *             SiS (www.sis.com)
  *             Copyright (C) 1999 Silicon Integrated Systems, Inc.
  *
  * See http://www.winischhofer.net/ for more information and updates
 #include <linux/config.h>
 #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/spinlock.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 #include <linux/vmalloc.h>
-#endif
 #include <linux/vt_kern.h>
 #include <linux/capability.h>
 #include <linux/fs.h>
-#include <linux/agp_backend.h>
 #include <linux/types.h>
 #include <asm/uaccess.h>
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#include <linux/spinlock.h>
-#endif
-
-#include "osdef.h"
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#include <video/sisfb.h>
-#else
-#include <linux/sisfb.h>
-#endif
-
 #include <asm/io.h>
 #ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
 #include <video/fbcon-cfb32.h>
 #endif
 
-#include "vgatypes.h"
-#include "sis_main.h"
 #include "sis.h"
+#include "sis_main.h"
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#error "This version of sisfb requires at least 2.6.0"
-#else
-#if 0
-#define NEWFBDEV               /* Define this as soon as new fvdev code has been merged */
-#endif
-#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3)
+#error "This version of sisfb requires at least 2.6.3"
 #endif
-
-/* -------------------- Macro definitions ---------------------------- */
-
-#undef SISFBDEBUG      /* TW: no debugging */
-
-#ifdef SISFBDEBUG
-#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
-#else
-#define DPRINTK(fmt, args...)
 #endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#ifdef SISFBACCEL
 #ifdef FBCON_HAS_CFB8
 extern struct display_switch fbcon_sis8;
 #endif
@@ -118,174 +91,289 @@ extern struct display_switch fbcon_sis16;
 extern struct display_switch fbcon_sis32;
 #endif
 #endif
-#endif
 
-/* --------------- Hardware Access Routines -------------------------- */
+/* ------------------ Internal helper routines ----------------- */
 
-void sisfb_set_reg4(u16 port, unsigned long data)
+static void __init
+sisfb_setdefaultparms(void)
 {
-       outl((u32) (data & 0xffffffff), port);
+       sisfb_off               = 0;
+       sisfb_parm_mem          = 0;
+       sisfb_accel             = -1;
+       sisfb_ypan              = -1;
+       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;
+       sisfb_crt2type          = -1;
+       sisfb_crt2flags         = 0;
+       sisfb_pdc               = 0xff;
+       sisfb_pdca              = 0xff;
+       sisfb_scalelcd          = -1;
+       sisfb_specialtiming     = CUT_NONE;
+       sisfb_lvdshl            = -1;
+       sisfb_dstn              = 0;
+       sisfb_fstn              = 0;
+       sisfb_tvplug            = -1;
+       sisfb_tvstd             = -1;
+       sisfb_tvxposoffset      = 0;
+       sisfb_tvyposoffset      = 0;
+       sisfb_filter            = -1;
+       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;
+#endif
 }
 
-u32 sisfb_get_reg3(u16 port)
+static void __init
+sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
 {
-       u32 data;
+       int i = 0, j = 0;
 
-       data = inl(port);
-       return (data);
-}
+       /* BEWARE: 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;
+       }
+
+       vesamode &= 0x1dff;  /* Clean VESA mode number from other flags */
 
-/* ------------ Interface for init & mode switching code ------------- */
+       while(sisbios_mode[i++].mode_no[0] != 0) {
+               if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
+                   (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
+                   if(sisfb_fstn) {
+                      if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
+                         sisbios_mode[i-1].mode_no[1] == 0x56 ||
+                         sisbios_mode[i-1].mode_no[1] == 0x53) continue;
+                   } else {
+                      if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
+                         sisbios_mode[i-1].mode_no[1] == 0x5b) continue;
+                   }
+                   sisfb_mode_idx = i - 1;
+                   j = 1;
+                   break;
+               }
+       }
+       if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
+}
 
-BOOLEAN
-sisfb_query_VGA_config_space(PSIS_HW_INFO psishw_ext,
-       unsigned long offset, unsigned long set, unsigned long *value)
+static void
+sisfb_search_mode(char *name, BOOLEAN quiet)
 {
-       static struct pci_dev *pdev = NULL;
-       static unsigned char init = 0, valid_pdev = 0;
+       int i = 0;
+       unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
+       char strbuf[16], strbuf1[20];
+       char *nameptr = name;
 
-       if (!set)
-               DPRINTK("sisfb: Get VGA offset 0x%lx\n", offset);
-       else
-               DPRINTK("sisfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
+       /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
 
-       if (!init) {
-               init = TRUE;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
-               pci_for_each_dev(pdev) {
-#else
-               while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
-#endif
-                       DPRINTK("sisfb: Current: 0x%x, target: 0x%x\n",
-                                pdev->device, ivideo.chip_id);
-                       if ((pdev->vendor == PCI_VENDOR_ID_SI)
-                                  && (pdev->device == ivideo.chip_id)) {
-                               valid_pdev = TRUE;
-                               break;
-                       }
-               }
+       if(name == NULL) {
+          if(!quiet) {
+             printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
+          }
+          sisfb_mode_idx = DEFAULT_MODE;
+          return;
        }
 
-       if (!valid_pdev) {
-               printk(KERN_DEBUG "sisfb: Can't find SiS %d VGA device.\n",
-                               ivideo.chip_id);
-               return FALSE;
+#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");
+          }
+          sisfb_mode_idx = DEFAULT_MODE;
+          return;
        }
+#endif
+       if(strlen(name) <= 19) {
+          strcpy(strbuf1, name);
+          for(i=0; i<strlen(strbuf1); i++) {
+             if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
+          }
 
-       if (set == 0)
-               pci_read_config_dword(pdev, offset, (u32 *)value);
-       else
-               pci_write_config_dword(pdev, offset, (u32)(*value));
+          /* This does some fuzzy mode naming detection */
+          if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
+             if((rate <= 32) || (depth > 32)) {
+                j = rate; rate = depth; depth = j;
+             }
+             sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
+             nameptr = strbuf;
+             sisfb_parm_rate = rate;
+          } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
+             sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
+             nameptr = strbuf;
+          } else {
+             xres = 0;
+             if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
+                sprintf(strbuf, "%ux%ux8", xres, yres);
+                nameptr = strbuf;
+             } else {
+                sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
+                return;
+             }
+          }
+       }
 
-       return TRUE;
+       i = 0; j = 0;
+       while(sisbios_mode[i].mode_no[0] != 0) {
+               if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
+                       if(sisfb_fstn) {
+                               if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
+                                  sisbios_mode[i-1].mode_no[1] == 0x56 ||
+                                  sisbios_mode[i-1].mode_no[1] == 0x53) continue;
+                       } else {
+                               if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
+                                  sisbios_mode[i-1].mode_no[1] == 0x5b) continue;
+                       }
+                       sisfb_mode_idx = i - 1;
+                       j = 1;
+                       break;
+               }
+       }
+       if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
 }
 
-BOOLEAN sisfb_query_north_bridge_space(PSIS_HW_INFO psishw_ext,
-       unsigned long offset, unsigned long set, unsigned long *value)
+#ifndef MODULE
+static void __devinit
+sisfb_get_vga_mode_from_kernel(void)
 {
-       static struct pci_dev *pdev = NULL;
-       static unsigned char init = 0, valid_pdev = 0;
-       u16 nbridge_id = 0;
+#if (defined(__i386__) || defined(__x86_64__)) && defined(CONFIG_VIDEO_SELECT)
+       char mymode[32];
+       int  mydepth = screen_info.lfb_depth;
 
-       if (!init) {
-               init = TRUE;
-               switch (ivideo.chip) {
-#ifdef CONFIG_FB_SIS_300
-               case SIS_540:
-                       nbridge_id = PCI_DEVICE_ID_SI_540;
-                       break;
-               case SIS_630:
-                       nbridge_id = PCI_DEVICE_ID_SI_630;
-                       break;
-               case SIS_730:
-                       nbridge_id = PCI_DEVICE_ID_SI_730;
-                       break;
+       if(screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) return;
+
+       if( (screen_info.lfb_width >= 320) && (screen_info.lfb_width <= 2048) &&
+           (screen_info.lfb_height >= 200) && (screen_info.lfb_height <= 1536) &&
+           (mydepth >= 8) && (mydepth <= 32) ) {
+
+           if(mydepth == 24) mydepth = 32;
+
+           sprintf(mymode, "%ux%ux%u", screen_info.lfb_width,
+                                       screen_info.lfb_height,
+                                       mydepth);
+
+           printk(KERN_DEBUG "sisfb: Using vga mode %s pre-set by kernel as default\n", mymode);
+
+           sisfb_search_mode(mymode, TRUE);
+       }
 #endif
-#ifdef CONFIG_FB_SIS_315
-               case SIS_550:
-                       nbridge_id = PCI_DEVICE_ID_SI_550;
-                       break;
-               case SIS_650:
-                       nbridge_id = PCI_DEVICE_ID_SI_650;
-                       break;
-               case SIS_740:
-                       nbridge_id = PCI_DEVICE_ID_SI_740;
-                       break;
-               case SIS_661:
-                       nbridge_id = PCI_DEVICE_ID_SI_660;
-                       break;
-               case SIS_741:
-                       nbridge_id = PCI_DEVICE_ID_SI_741;
-                       break;
-               case SIS_660:
-                       nbridge_id = PCI_DEVICE_ID_SI_660;
-                       break;
-               case SIS_760:
-                       nbridge_id = PCI_DEVICE_ID_SI_760;
-                       break;
+       return;
+}
 #endif
-               default:
-                       nbridge_id = 0;
-                       break;
-               }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
-               pci_for_each_dev(pdev) {
-#else
-               while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
-#endif
-                       DPRINTK("Current: 0x%x, target: 0x%x\n",
-                                       pdev->device, ivideo.chip_id);
-                       if ((pdev->vendor == PCI_VENDOR_ID_SI)
-                                       && (pdev->device == nbridge_id)) {
-                               valid_pdev = TRUE;
-                               break;
-                       }
-               }
-       }
+static void __init
+sisfb_search_crt2type(const char *name)
+{
+       int i = 0;
+
+       /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
 
-       if (!valid_pdev) {
-               printk(KERN_DEBUG "sisfb: Can't find SiS %d North Bridge device.\n",
-                               nbridge_id);
-               return FALSE;
+       if(name == NULL) return;
+
+       while(sis_crt2type[i].type_no != -1) {
+               if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
+                       sisfb_crt2type = sis_crt2type[i].type_no;
+                       sisfb_tvplug = sis_crt2type[i].tvplug_no;
+                       sisfb_crt2flags = sis_crt2type[i].flags;
+                       break;
+               }
+               i++;
        }
 
-       if (set == 0)
-               pci_read_config_dword(pdev, offset, (u32 *)value);
-       else
-               pci_write_config_dword(pdev, offset, (u32)(*value));
+       sisfb_dstn = (sisfb_crt2flags & FL_550_DSTN) ? 1 : 0;
+       sisfb_fstn = (sisfb_crt2flags & FL_550_FSTN) ? 1 : 0;
 
-       return TRUE;
+       if(sisfb_crt2type < 0) {
+               printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
+       }
 }
 
-/* ------------------ Internal helper routines ----------------- */
-
-static BOOLEAN sisfb_verify_rate(struct sisfb_monitor *monitor, int mode_idx, int rate_idx, int rate)
+static void __init
+sisfb_search_tvstd(const char *name)
 {
-       int htotal, vtotal;
-       unsigned int dclock, hsync;
-
-       if(!monitor->datavalid) return TRUE;
+       int i = 0;
 
-       if(mode_idx < 0) return FALSE;
+       /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
 
-       if(rate < (monitor->vmin - 1)) return FALSE;
-       if(rate > (monitor->vmax + 1)) return FALSE;
+       if(name == NULL) return;
 
-       if(sisfb_gettotalfrommode(&SiS_Pr, &sishw_ext, sisbios_mode[mode_idx].mode_no,
-                                 &htotal, &vtotal, rate_idx)) {
-               dclock = (htotal * vtotal * rate) / 1000;
-               if(dclock > (monitor->dclockmax + 1000)) return FALSE;
-               hsync = dclock / htotal;
-               if(hsync < (monitor->hmin - 1)) return FALSE;
-               if(hsync > (monitor->hmax + 1)) return FALSE;
-        } else {
-               return FALSE;
+       while(sis_tvtype[i].type_no != -1) {
+               if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
+                       sisfb_tvstd = sis_tvtype[i].type_no;
+                       break;
+               }
+               i++;
        }
-       return TRUE;
-};
+}
+
+static void __init
+sisfb_search_specialtiming(const char *name)
+{
+       int i = 0;
+       BOOLEAN found = FALSE;
+
+       /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
+
+       if(name == NULL) return;
+
+       if(!strnicmp(name, "none", 4)) {
+               sisfb_specialtiming = CUT_FORCENONE;
+               printk(KERN_DEBUG "sisfb: Special timing disabled\n");
+       } else {
+          while(mycustomttable[i].chipID != 0) {
+             if(!strnicmp(name,mycustomttable[i].optionName, strlen(mycustomttable[i].optionName))) {
+                sisfb_specialtiming = mycustomttable[i].SpecialID;
+                found = TRUE;
+                printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n",
+                       mycustomttable[i].vendorName, mycustomttable[i].cardName,
+                       mycustomttable[i].optionName);
+                break;
+             }
+             i++;
+          }
+          if(!found) {
+             printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
+             printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
+             i = 0;
+             while(mycustomttable[i].chipID != 0) {
+                printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
+                    mycustomttable[i].optionName,
+                    mycustomttable[i].vendorName,
+                    mycustomttable[i].cardName);
+                i++;
+             }
+           }
+       }
+}
 
-static BOOLEAN sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
+static BOOLEAN __devinit
+sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
 {
        int i, j, xres, yres, refresh, index;
        u32 emodes;
@@ -385,7 +473,8 @@ static BOOLEAN sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
        return(monitor->datavalid);
 }
 
-static void sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno)
+static void __devinit
+sisfb_handle_ddc(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, int crtno)
 {
        USHORT  temp, i, realcrtno = crtno;
        u8      buffer[256];
@@ -393,14 +482,15 @@ static void sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno)
        monitor->datavalid = FALSE;
 
        if(crtno) {
-                  if(ivideo.vbflags & CRT2_LCD)      realcrtno = 1;
-          else if(ivideo.vbflags & CRT2_VGA) realcrtno = 2;
+                  if(ivideo->vbflags & CRT2_LCD)      realcrtno = 1;
+          else if(ivideo->vbflags & CRT2_VGA) realcrtno = 2;
           else return;
        }
 
-       if((sisfb_crt1off) && (!crtno)) return;
+       if((ivideo->sisfb_crt1off) && (!crtno)) return;
 
-       temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine, realcrtno, 0, &buffer[0]);
+       temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
+                               realcrtno, 0, &buffer[0]);
        if((!temp) || (temp == 0xffff)) {
           printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
           return;
@@ -415,7 +505,7 @@ static void sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno)
           if(temp & 0x02) {
              i = 3;  /* Number of retrys */
              do {
-                temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine,
+                temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
                                     realcrtno, 1, &buffer[0]);
              } while((temp) && i--);
               if(!temp) {
@@ -435,194 +525,117 @@ static void sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno)
        }
 }
 
-static void sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
+static BOOLEAN
+sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
+               int mode_idx, int rate_idx, int rate)
 {
-       int i = 0, j = 0;
+       int htotal, vtotal;
+       unsigned int dclock, hsync;
 
-       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: Mode 'none' not supported anymore. Using default.\n");
-               sisfb_mode_idx = DEFAULT_MODE;
+       if(!monitor->datavalid) return TRUE;
+
+       if(mode_idx < 0) return FALSE;
+
+       /* Skip for 320x200, 320x240, 640x400 */
+       switch(sisbios_mode[mode_idx].mode_no[ivideo->mni]) {
+       case 0x59:
+       case 0x41:
+       case 0x4f:
+       case 0x50:
+       case 0x56:
+       case 0x53:
+       case 0x2f:
+       case 0x5d:
+       case 0x5e:
+               return TRUE;
+#ifdef CONFIG_FB_SIS_315
+       case 0x5a:
+       case 0x5b:
+               if(ivideo->sisvga_engine == SIS_315_VGA) return TRUE;
 #endif
-               return;
-       }
+       }
 
-       vesamode &= 0x1dff;  /* Clean VESA mode number from other flags */
+       if(rate < (monitor->vmin - 1)) return FALSE;
+       if(rate > (monitor->vmax + 1)) return FALSE;
 
-       while(sisbios_mode[i++].mode_no != 0) {
-               if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
-                   (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
-                   if(sisfb_fstn) {
-                      if(sisbios_mode[i-1].mode_no == 0x50 ||
-                         sisbios_mode[i-1].mode_no == 0x56 ||
-                         sisbios_mode[i-1].mode_no == 0x53) continue;
-                   } else {
-                      if(sisbios_mode[i-1].mode_no == 0x5a ||
-                         sisbios_mode[i-1].mode_no == 0x5b) continue;
-                   }
-                   sisfb_mode_idx = i - 1;
-                   j = 1;
-                   break;
-               }
+       if(sisfb_gettotalfrommode(&ivideo->SiS_Pr, &ivideo->sishw_ext,
+                                 sisbios_mode[mode_idx].mode_no[ivideo->mni],
+                                 &htotal, &vtotal, rate_idx)) {
+               dclock = (htotal * vtotal * rate) / 1000;
+               if(dclock > (monitor->dclockmax + 1000)) return FALSE;
+               hsync = dclock / htotal;
+               if(hsync < (monitor->hmin - 1)) return FALSE;
+               if(hsync > (monitor->hmax + 1)) return FALSE;
+        } else {
+               return FALSE;
        }
-       if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
+       return TRUE;
 }
 
-static void sisfb_search_mode(char *name, BOOLEAN quiet)
+static int
+sisfb_validate_mode(struct sis_video_info *ivideo, int myindex, u32 vbflags)
 {
-       int i = 0;
-       unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
-       char strbuf[16], strbuf1[20];
-       char *nameptr = name;
-
-       if(name == NULL) {
-          if(!quiet)
-             printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
-          sisfb_mode_idx = DEFAULT_MODE;
-          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");
-          sisfb_mode_idx = DEFAULT_MODE;
-          return;
-       }
-#endif
-       if(strlen(name) <= 19) {
-          strcpy(strbuf1, name);
-          for(i=0; i<strlen(strbuf1); i++) {
-             if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
-          }
-
-          /* This does some fuzzy mode naming detection */
-          if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
-             if((rate <= 32) || (depth > 32)) {
-                j = rate; rate = depth; depth = j;
-             }
-             sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
-             nameptr = strbuf;
-             ivideo.refresh_rate = sisfb_parm_rate = rate;
-          } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
-             sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
-             nameptr = strbuf;
-          } else {
-             xres = 0;
-             if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
-                sprintf(strbuf, "%ux%ux8", xres, yres);
-                nameptr = strbuf;
-             } else {
-                sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
-                return;
-             }
-          }
-       }
-
-       i = 0; j = 0;
-       while(sisbios_mode[i].mode_no != 0) {
-               if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
-                  if(sisfb_fstn) {
-                     if(sisbios_mode[i-1].mode_no == 0x50 ||
-                        sisbios_mode[i-1].mode_no == 0x56 ||
-                        sisbios_mode[i-1].mode_no == 0x53) continue;
-                  } else {
-                     if(sisbios_mode[i-1].mode_no == 0x5a ||
-                        sisbios_mode[i-1].mode_no == 0x5b) continue;
-                  }
-                  sisfb_mode_idx = i - 1;
-                  j = 1;
-                  break;
-               }
-       }
-       if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
-
-}
-
-static int sisfb_validate_mode(int myindex, unsigned long vbflags)
-{
-   u16 xres, yres, myres;
+   u16 xres=0, yres, myres;
 
 #ifdef CONFIG_FB_SIS_300
-   if(sisvga_engine == SIS_300_VGA) {
+   if(ivideo->sisvga_engine == SIS_300_VGA) {
       if(!(sisbios_mode[myindex].chipset & MD_SIS300)) return(-1);
    }
 #endif
 #ifdef CONFIG_FB_SIS_315
-   if(sisvga_engine == SIS_315_VGA) {
+   if(ivideo->sisvga_engine == SIS_315_VGA) {
       if(!(sisbios_mode[myindex].chipset & MD_SIS315)) return(-1);
    }
 #endif
 
    myres = sisbios_mode[myindex].yres;
 
-   switch (vbflags & VB_DISPTYPE_DISP2) {
+   switch(vbflags & VB_DISPTYPE_DISP2) {
+
      case CRT2_LCD:
-       switch (sishw_ext.ulCRT2LCDType) {
-       case LCD_640x480:  xres =  640; yres =  480;  break;
-       case LCD_800x600:  xres =  800; yres =  600;  break;
-        case LCD_1024x600: xres = 1024; yres =  600;  break;
-       case LCD_1024x768: xres = 1024; yres =  768;  break;
-       case LCD_1152x768: xres = 1152; yres =  768;  break;
-       case LCD_1280x960: xres = 1280; yres =  960;  break;
-       case LCD_1280x768: xres = 1280; yres =  768;  break;
-       case LCD_1280x1024:xres = 1280; yres = 1024;  break;
-       case LCD_1400x1050:xres = 1400; yres = 1050;  break;
-       case LCD_1600x1200:xres = 1600; yres = 1200;  break;
-       case LCD_320x480:  xres =  320; yres =  480;  break; /* FSTN (old) */
-       case LCD_640x480_2:
-       case LCD_640x480_3:xres =  640; yres =  480;  break; /* FSTN (new) */
-       default:           xres =    0; yres =    0;  break;
-       }
-
-       if(SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
-          xres = 1360; yres = 1024;
-       }
-
-       if(SiS_Pr.SiS_CustomT == CUT_PANEL848) {
-          xres = 848;  yres =  480;
-       } else {
-          if(sisbios_mode[myindex].xres > xres) return(-1);
-           if(myres > yres) return(-1);
+
+        xres = ivideo->lcdxres; yres = ivideo->lcdyres;
+
+       if(ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL848) {
+               if(sisbios_mode[myindex].xres > xres) return(-1);
+               if(myres > yres) return(-1);
        }
 
        if(vbflags & (VB_LVDS | VB_30xBDH)) {
           if(sisbios_mode[myindex].xres == 320) {
              if((myres == 240) || (myres == 480)) {
-                if(!sisfb_fstn) {
-                   if(sisbios_mode[myindex].mode_no == 0x5a ||
-                      sisbios_mode[myindex].mode_no == 0x5b)
+                if(!ivideo->sisfb_fstn) {
+                   if(sisbios_mode[myindex].mode_no[1] == 0x5a ||
+                      sisbios_mode[myindex].mode_no[1] == 0x5b)
                       return(-1);
                 } else {
-                   if(sisbios_mode[myindex].mode_no == 0x50 ||
-                      sisbios_mode[myindex].mode_no == 0x56 ||
-                      sisbios_mode[myindex].mode_no == 0x53)
+                   if(sisbios_mode[myindex].mode_no[1] == 0x50 ||
+                      sisbios_mode[myindex].mode_no[1] == 0x56 ||
+                      sisbios_mode[myindex].mode_no[1] == 0x53)
                       return(-1);
                 }
              }
           }
        }
 
-       if(SiS_GetModeID_LCD(sisvga_engine, vbflags, sisbios_mode[myindex].xres, sisbios_mode[myindex].yres,
-                            0, sisfb_fstn, SiS_Pr.SiS_CustomT, xres, yres) < 0x14) {
-          return(-1);
+       if(SiS_GetModeID_LCD(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+                            sisbios_mode[myindex].yres, 0, ivideo->sisfb_fstn,
+                            ivideo->SiS_Pr.SiS_CustomT, xres, yres) < 0x14) {
+               return(-1);
        }
        break;
 
      case CRT2_TV:
-       if(SiS_GetModeID_TV(sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+       if(SiS_GetModeID_TV(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
                            sisbios_mode[myindex].yres, 0) < 0x14) {
-          return(-1);
+               return(-1);
        }
        break;
 
      case CRT2_VGA:
-        if(SiS_GetModeID_VGA2(sisvga_engine, vbflags, sisbios_mode[myindex].xres,
-                           sisbios_mode[myindex].yres, 0) < 0x14) {
-          return(-1);
+        if(SiS_GetModeID_VGA2(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+                             sisbios_mode[myindex].yres, 0) < 0x14) {
+               return(-1);
        }
        break;
      }
@@ -630,49 +643,8 @@ static int sisfb_validate_mode(int myindex, unsigned long vbflags)
      return(myindex);
 }
 
-static void sisfb_search_crt2type(const char *name)
-{
-       int i = 0;
-
-       if(name == NULL)
-               return;
-
-       while(sis_crt2type[i].type_no != -1) {
-               if (!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
-                       sisfb_crt2type = sis_crt2type[i].type_no;
-                       sisfb_tvplug = sis_crt2type[i].tvplug_no;
-                       sisfb_dstn = (sis_crt2type[i].flags & FL_550_DSTN) ? 1 : 0;
-                       sisfb_fstn = (sis_crt2type[i].flags & FL_550_FSTN) ? 1 : 0;
-                       break;
-               }
-               i++;
-       }
-       if(sisfb_crt2type < 0)
-               printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
-        if(ivideo.chip != SIS_550) {
-          sisfb_dstn = sisfb_fstn = 0;
-       }
-}
-
-static void sisfb_search_queuemode(const char *name)
-{
-       int i = 0;
-
-       if(name == NULL)
-               return;
-
-       while (sis_queuemode[i].type_no != -1) {
-               if (!strnicmp(name, sis_queuemode[i].name, strlen(sis_queuemode[i].name))) {
-                       sisfb_queuemode = sis_queuemode[i].type_no;
-                       break;
-               }
-               i++;
-       }
-       if (sisfb_queuemode < 0)
-               printk(KERN_ERR "sisfb: Invalid queuemode type: %s\n", name);
-}
-
-static u8 sisfb_search_refresh_rate(unsigned int rate, int mode_idx)
+static u8
+sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int mode_idx)
 {
        u16 xres, yres;
        int i = 0;
@@ -680,116 +652,64 @@ static u8 sisfb_search_refresh_rate(unsigned int rate, int mode_idx)
        xres = sisbios_mode[mode_idx].xres;
        yres = sisbios_mode[mode_idx].yres;
 
-       sisfb_rate_idx = 0;
-       while ((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
-               if ((sisfb_vrate[i].xres == xres) && (sisfb_vrate[i].yres == yres)) {
-                       if (sisfb_vrate[i].refresh == rate) {
-                               sisfb_rate_idx = sisfb_vrate[i].idx;
+       ivideo->rate_idx = 0;
+       while((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
+               if((sisfb_vrate[i].xres == xres) && (sisfb_vrate[i].yres == yres)) {
+                       if(sisfb_vrate[i].refresh == rate) {
+                               ivideo->rate_idx = sisfb_vrate[i].idx;
                                break;
-                       } else if (sisfb_vrate[i].refresh > rate) {
-                               if ((sisfb_vrate[i].refresh - rate) <= 3) {
+                       } else if(sisfb_vrate[i].refresh > rate) {
+                               if((sisfb_vrate[i].refresh - rate) <= 3) {
                                        DPRINTK("sisfb: Adjusting rate from %d up to %d\n",
                                                rate, sisfb_vrate[i].refresh);
-                                       sisfb_rate_idx = sisfb_vrate[i].idx;
-                                       ivideo.refresh_rate = sisfb_vrate[i].refresh;
-                               } else if (((rate - sisfb_vrate[i-1].refresh) <= 2)
+                                       ivideo->rate_idx = sisfb_vrate[i].idx;
+                                       ivideo->refresh_rate = sisfb_vrate[i].refresh;
+                               } else if(((rate - sisfb_vrate[i-1].refresh) <= 2)
                                                && (sisfb_vrate[i].idx != 1)) {
                                        DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
                                                rate, sisfb_vrate[i-1].refresh);
-                                       sisfb_rate_idx = sisfb_vrate[i-1].idx;
-                                       ivideo.refresh_rate = sisfb_vrate[i-1].refresh;
+                                       ivideo->rate_idx = sisfb_vrate[i-1].idx;
+                                       ivideo->refresh_rate = sisfb_vrate[i-1].refresh;
                                } 
                                break;
                        } else if((rate - sisfb_vrate[i].refresh) <= 2) {
                                DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
                                                rate, sisfb_vrate[i].refresh);
-                               sisfb_rate_idx = sisfb_vrate[i].idx;
+                               ivideo->rate_idx = sisfb_vrate[i].idx;
                                break;
                        }
                }
                i++;
        }
-       if (sisfb_rate_idx > 0) {
-               return sisfb_rate_idx;
+       if(ivideo->rate_idx > 0) {
+               return ivideo->rate_idx;
        } else {
-               printk(KERN_INFO
-                       "sisfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
+               printk(KERN_INFO "sisfb: Unsupported rate %d for %dx%d\n",
+                               rate, xres, yres);
                return 0;
        }
 }
 
-static void sisfb_search_tvstd(const char *name)
-{
-       int i = 0;
-
-       if(name == NULL)
-               return;
-
-       while (sis_tvtype[i].type_no != -1) {
-               if (!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
-                       ivideo.vbflags |= sis_tvtype[i].type_no;
-                       break;
-               }
-               i++;
-       }
-}
-
-static void sisfb_search_specialtiming(const char *name)
-{
-       int i = 0;
-       BOOLEAN found = FALSE;
-
-       if(name == NULL)
-               return;
-
-       if(!strnicmp(name, "none", 4)) {
-               SiS_Pr.SiS_CustomT = CUT_FORCENONE;
-               printk(KERN_DEBUG "sisfb: Special timing disabled\n");
-       } else {
-          while(mycustomttable[i].chipID != 0) {
-             if(!strnicmp(name,mycustomttable[i].optionName, strlen(mycustomttable[i].optionName))) {
-                SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
-                found = TRUE;
-                printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n",
-                       mycustomttable[i].vendorName, mycustomttable[i].cardName,
-                       mycustomttable[i].optionName);
-                break;
-             }
-             i++;
-          }
-          if(!found) {
-             printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
-             printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
-             i = 0;
-             while(mycustomttable[i].chipID != 0) {
-                printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
-                    mycustomttable[i].optionName,
-                    mycustomttable[i].vendorName,
-                    mycustomttable[i].cardName);
-                i++;
-             }
-           }
-       }
-}
-
-static BOOLEAN sisfb_bridgeisslave(void)
+static BOOLEAN
+sisfb_bridgeisslave(struct sis_video_info *ivideo)
 {
    unsigned char P1_00;
 
-   if(!(ivideo.vbflags & VB_VIDEOBRIDGE)) return FALSE;
+   if(!(ivideo->vbflags & VB_VIDEOBRIDGE)) return FALSE;
 
    inSISIDXREG(SISPART1,0x00,P1_00);
-   if( ((sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
-       ((sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
+   if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
+       ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
           return TRUE;
    } else {
            return FALSE;
    }
 }
 
-static BOOLEAN sisfballowretracecrt1(void)
+static BOOLEAN
+sisfballowretracecrt1(struct sis_video_info *ivideo)
 {
-   unsigned char temp;
+   u8 temp;
 
    inSISIDXREG(SISCR,0x17,temp);
    if(!(temp & 0x80)) return FALSE;
@@ -800,20 +720,21 @@ static BOOLEAN sisfballowretracecrt1(void)
    return TRUE;
 }
 
-static BOOLEAN sisfbcheckvretracecrt1(void)
+static BOOLEAN
+sisfbcheckvretracecrt1(struct sis_video_info *ivideo)
 {
-
-   if(!sisfballowretracecrt1()) return FALSE;
+   if(!sisfballowretracecrt1(ivideo)) return FALSE;
 
    if(inSISREG(SISINPSTAT) & 0x08) return TRUE;
    else                           return FALSE;
 }
 
-static void sisfbwaitretracecrt1(void)
+static void
+sisfbwaitretracecrt1(struct sis_video_info *ivideo)
 {
    int watchdog;
 
-   if(!sisfballowretracecrt1()) return;
+   if(!sisfballowretracecrt1(ivideo)) return;
 
    watchdog = 65536;
    while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog);
@@ -821,19 +742,15 @@ static void sisfbwaitretracecrt1(void)
    while((inSISREG(SISINPSTAT) & 0x08) && --watchdog);
 }
 
-static BOOLEAN sisfbcheckvretracecrt2(void)
+static BOOLEAN
+sisfbcheckvretracecrt2(struct sis_video_info *ivideo)
 {
    unsigned char temp, reg;
 
-   switch(sisvga_engine) {
-   case SIS_300_VGA:
-       reg = 0x25;
-       break;
-   case SIS_315_VGA:
-       reg = 0x30;
-       break;
-   default:
-        return FALSE;
+   switch(ivideo->sisvga_engine) {
+   case SIS_300_VGA: reg = 0x25; break;
+   case SIS_315_VGA: reg = 0x30; break;
+   default:          return FALSE;
    }
 
    inSISIDXREG(SISPART1, reg, temp);
@@ -841,19 +758,67 @@ static BOOLEAN sisfbcheckvretracecrt2(void)
    else           return TRUE;
 }
 
-static BOOLEAN sisfb_CheckVBRetrace(void)
+static BOOLEAN
+sisfb_CheckVBRetrace(struct sis_video_info *ivideo)
 {
-   if(ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
-      if(sisfb_bridgeisslave()) {
-         return(sisfbcheckvretracecrt1());
+   if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
+      if(sisfb_bridgeisslave(ivideo)) {
+         return(sisfbcheckvretracecrt1(ivideo));
       } else {
-         return(sisfbcheckvretracecrt2());
+         return(sisfbcheckvretracecrt2(ivideo));
       }
    } 
-   return(sisfbcheckvretracecrt1());
+   return(sisfbcheckvretracecrt1(ivideo));
+}
+
+static u32
+sisfb_setupvbblankflags(struct sis_video_info *ivideo, u32 *vcount, u32 *hcount)
+{
+   u8 idx, reg1, reg2, reg3, reg4;
+   u32 ret = 0;
+
+   (*vcount) = (*hcount) = 0;
+
+   if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!(sisfb_bridgeisslave(ivideo)))) {
+      ret |= (FB_VBLANK_HAVE_VSYNC  |
+             FB_VBLANK_HAVE_HBLANK |
+              FB_VBLANK_HAVE_VBLANK |
+             FB_VBLANK_HAVE_VCOUNT |
+             FB_VBLANK_HAVE_HCOUNT);
+      switch(ivideo->sisvga_engine) {
+         case SIS_300_VGA: idx = 0x25; break;
+        default:
+         case SIS_315_VGA: idx = 0x30; break;
+      }
+      inSISIDXREG(SISPART1,(idx+0),reg1); /* 30 */
+      inSISIDXREG(SISPART1,(idx+1),reg2); /* 31 */
+      inSISIDXREG(SISPART1,(idx+2),reg3); /* 32 */
+      inSISIDXREG(SISPART1,(idx+3),reg4); /* 33 */
+      if(!(reg1 & 0x01)) ret |= FB_VBLANK_VBLANKING;
+      if(!(reg1 & 0x02)) ret |= FB_VBLANK_VSYNCING;
+      if(!(reg4 & 0x80)) ret |= FB_VBLANK_HBLANKING;
+      (*vcount) = reg3 | ((reg4 & 0x70) << 4);
+      (*hcount) = reg2 | ((reg4 & 0x0f) << 8);
+   } else if(sisfballowretracecrt1(ivideo)) {
+      ret |= (FB_VBLANK_HAVE_VSYNC  |
+              FB_VBLANK_HAVE_VBLANK |
+             FB_VBLANK_HAVE_VCOUNT |
+             FB_VBLANK_HAVE_HCOUNT);
+      reg1 = inSISREG(SISINPSTAT);
+      if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING;
+      if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
+      inSISIDXREG(SISCR,0x20,reg1);
+      inSISIDXREG(SISCR,0x1b,reg1);
+      inSISIDXREG(SISCR,0x1c,reg2);
+      inSISIDXREG(SISCR,0x1d,reg3);
+      (*vcount) = reg2 | ((reg3 & 0x07) << 8);
+      (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3;
+   }
+   return ret;
 }
 
-static int sisfb_myblank(int blank)
+static int
+sisfb_myblank(struct sis_video_info *ivideo, int blank)
 {
    u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
    BOOLEAN backlight = TRUE;
@@ -908,63 +873,64 @@ static int sisfb_myblank(int blank)
       return 1;
    }
 
-   if(ivideo.currentvbflags & VB_DISPTYPE_CRT1) {
+   if(ivideo->currentvbflags & VB_DISPTYPE_CRT1) {
 
-      setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
+      if( (!ivideo->sisfb_thismonitor.datavalid) ||
+          ((ivideo->sisfb_thismonitor.datavalid) &&
+           (ivideo->sisfb_thismonitor.feature & 0xe0))) {
 
-      if( (!sisfb_thismonitor.datavalid) ||
-          ((sisfb_thismonitor.datavalid) &&
-           (sisfb_thismonitor.feature & 0xe0))) {
-
-        if(sisvga_engine == SIS_315_VGA) {
-           setSISIDXREG(SISCR, SiS_Pr.SiS_MyCR63, 0xbf, cr63);
+        if(ivideo->sisvga_engine == SIS_315_VGA) {
+           setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63);
         }
 
-        setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
+        if(!(sisfb_bridgeisslave(ivideo))) {
+           setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
+           setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
+        }
       }
 
    }
 
-   if(ivideo.currentvbflags & CRT2_LCD) {
+   if(ivideo->currentvbflags & CRT2_LCD) {
 
-      if(ivideo.vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
+      if(ivideo->vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
         if(backlight) {
-           SiS_SiS30xBLOn(&SiS_Pr, &sishw_ext);
+           SiS_SiS30xBLOn(&ivideo->SiS_Pr, &ivideo->sishw_ext);
         } else {
-           SiS_SiS30xBLOff(&SiS_Pr, &sishw_ext);
+           SiS_SiS30xBLOff(&ivideo->SiS_Pr, &ivideo->sishw_ext);
         }
-      } else if(sisvga_engine == SIS_315_VGA) {
-        if(ivideo.vbflags & VB_CHRONTEL) {
+      } else if(ivideo->sisvga_engine == SIS_315_VGA) {
+        if(ivideo->vbflags & VB_CHRONTEL) {
            if(backlight) {
-              SiS_Chrontel701xBLOn(&SiS_Pr,&sishw_ext);
+              SiS_Chrontel701xBLOn(&ivideo->SiS_Pr,&ivideo->sishw_ext);
            } else {
-              SiS_Chrontel701xBLOff(&SiS_Pr);
+              SiS_Chrontel701xBLOff(&ivideo->SiS_Pr);
            }
         }
       }
 
-      if(((sisvga_engine == SIS_300_VGA) &&
-          (ivideo.vbflags & (VB_301|VB_30xBDH|VB_LVDS))) ||
-         ((sisvga_engine == SIS_315_VGA) &&
-          ((ivideo.vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
+      if(((ivideo->sisvga_engine == SIS_300_VGA) &&
+          (ivideo->vbflags & (VB_301|VB_30xBDH|VB_LVDS))) ||
+         ((ivideo->sisvga_engine == SIS_315_VGA) &&
+          ((ivideo->vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
           setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
       }
 
-      if(sisvga_engine == SIS_300_VGA) {
-         if((ivideo.vbflags & (VB_301B|VB_301C|VB_302B)) &&
-            (!(ivideo.vbflags & VB_30xBDH))) {
+      if(ivideo->sisvga_engine == SIS_300_VGA) {
+         if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) &&
+            (!(ivideo->vbflags & VB_30xBDH))) {
            setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
         }
-      } else if(sisvga_engine == SIS_315_VGA) {
-         if((ivideo.vbflags & (VB_301B|VB_301C|VB_302B)) &&
-            (!(ivideo.vbflags & VB_30xBDH))) {
+      } else if(ivideo->sisvga_engine == SIS_315_VGA) {
+         if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) &&
+            (!(ivideo->vbflags & VB_30xBDH))) {
            setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
         }
       }
 
-   } else if(ivideo.currentvbflags & CRT2_VGA) {
+   } else if(ivideo->currentvbflags & CRT2_VGA) {
 
-      if(ivideo.vbflags & (VB_301B|VB_301C|VB_302B)) {
+      if(ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) {
          setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
       }
 
@@ -975,35 +941,122 @@ static int sisfb_myblank(int blank)
 
 /* ----------- FBDev related routines for all series ----------- */
 
-static void sisfb_set_vparms(void)
+static int
+sisfb_get_cmap_len(const struct fb_var_screeninfo *var)
 {
-   switch(ivideo.video_bpp) {
-   case 8:
-               ivideo.DstColor = 0x0000;
-       ivideo.SiS310_AccelDepth = 0x00000000;
-       ivideo.video_cmap_len = 256;
-               break;
-   case 16:
-               ivideo.DstColor = 0x8000;
-               ivideo.SiS310_AccelDepth = 0x00010000;
-       ivideo.video_cmap_len = 16;
-               break;
-   case 32:
-               ivideo.DstColor = 0xC000;
-       ivideo.SiS310_AccelDepth = 0x00020000;
-       ivideo.video_cmap_len = 16;
-               break;
-   default:
-       ivideo.video_cmap_len = 16;
-       printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
-       ivideo.accel = 0;
-       break;
-   }
+       return (var->bits_per_pixel == 8) ? 256 : 16;
+}
+
+static void
+sisfb_set_vparms(struct sis_video_info *ivideo)
+{
+       switch(ivideo->video_bpp) {
+       case 8:
+               ivideo->DstColor = 0x0000;
+               ivideo->SiS310_AccelDepth = 0x00000000;
+               ivideo->video_cmap_len = 256;
+               break;
+       case 16:
+               ivideo->DstColor = 0x8000;
+               ivideo->SiS310_AccelDepth = 0x00010000;
+               ivideo->video_cmap_len = 16;
+               break;
+       case 32:
+               ivideo->DstColor = 0xC000;
+               ivideo->SiS310_AccelDepth = 0x00020000;
+               ivideo->video_cmap_len = 16;
+               break;
+       default:
+               ivideo->video_cmap_len = 16;
+               printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo->video_bpp);
+               ivideo->accel = 0;
+               break;
+       }
+}
+
+static int
+sisfb_calc_maxyres(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
+{
+       int maxyres = ivideo->heapstart / (var->xres_virtual * (var->bits_per_pixel >> 3));
+
+       if(maxyres > 32767) maxyres = 32767;
+
+       return maxyres;
+}
+
+static void
+sisfb_calc_pitch(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
+{
+       ivideo->video_linelength = var->xres_virtual * (var->bits_per_pixel >> 3);
+       ivideo->scrnpitchCRT1 = ivideo->video_linelength;
+       if(!(ivideo->currentvbflags & CRT1_LCDA)) {
+               if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+                       ivideo->scrnpitchCRT1 <<= 1;
+               }
+       }
+
+}
+
+static void
+sisfb_set_pitch(struct sis_video_info *ivideo)
+{
+       BOOLEAN isslavemode = FALSE;
+       unsigned short HDisplay1 = ivideo->scrnpitchCRT1 >> 3;
+       unsigned short HDisplay2 = ivideo->video_linelength >> 3;
+
+       if(sisfb_bridgeisslave(ivideo)) isslavemode = TRUE;
+
+       /* We need to set pitch for CRT1 if bridge is in slave mode, too */
+       if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) {
+               outSISIDXREG(SISCR,0x13,(HDisplay1 & 0xFF));
+               setSISIDXREG(SISSR,0x0E,0xF0,(HDisplay1 >> 8));
+       }
+
+       /* We must not set the pitch for CRT2 if bridge is in slave mode */
+       if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) {
+               orSISIDXREG(SISPART1,ivideo->CRT2_write_enable,0x01);
+               outSISIDXREG(SISPART1,0x07,(HDisplay2 & 0xFF));
+               setSISIDXREG(SISPART1,0x09,0xF0,(HDisplay2 >> 8));
+       }
+}
+
+static void
+sisfb_bpp_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
+{
+       ivideo->video_cmap_len = sisfb_get_cmap_len(var);
+
+       switch(var->bits_per_pixel) {
+       case 8:
+               var->red.offset = var->green.offset = var->blue.offset = 0;
+               var->red.length = var->green.length = var->blue.length = 6;
+               break;
+       case 16:
+               var->red.offset = 11;
+               var->red.length = 5;
+               var->green.offset = 5;
+               var->green.length = 6;
+               var->blue.offset = 0;
+               var->blue.length = 5;
+               var->transp.offset = 0;
+               var->transp.length = 0;
+               break;
+       case 32:
+               var->red.offset = 16;
+               var->red.length = 8;
+               var->green.offset = 8;
+               var->green.length = 8;
+               var->blue.offset = 0;
+               var->blue.length = 8;
+               var->transp.offset = 24;
+               var->transp.length = 8;
+               break;
+       }
 }
 
-static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
-                     struct fb_info *info)
+static int
+sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *info)
 {
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
        unsigned int htotal = 0, vtotal = 0;
        unsigned int drate = 0, hrate = 0;
        int found_mode = 0;
@@ -1033,52 +1086,51 @@ static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
        }
 
        if(pixclock && htotal && vtotal) {
-          drate = 1000000000 / pixclock;
-          hrate = (drate * 1000) / htotal;
-          ivideo.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
-       } else ivideo.refresh_rate = 60;
-
-#if 0
-       printk(KERN_DEBUG "sisfb: Change mode to %dx%dx%d-%dHz\n",
-               var->xres,var->yres,var->bits_per_pixel,ivideo.refresh_rate);
-#endif
+               drate = 1000000000 / pixclock;
+               hrate = (drate * 1000) / htotal;
+               ivideo->refresh_rate = (unsigned int) (hrate * 2 / vtotal);
+       } else {
+               ivideo->refresh_rate = 60;
+       }
 
-       old_mode = sisfb_mode_idx;
-       sisfb_mode_idx = 0;
+       old_mode = ivideo->sisfb_mode_idx;
+       ivideo->sisfb_mode_idx = 0;
 
-       while( (sisbios_mode[sisfb_mode_idx].mode_no != 0) &&
-              (sisbios_mode[sisfb_mode_idx].xres <= var->xres) ) {
-               if( (sisbios_mode[sisfb_mode_idx].xres == var->xres) &&
-                   (sisbios_mode[sisfb_mode_idx].yres == var->yres) &&
-                   (sisbios_mode[sisfb_mode_idx].bpp == var->bits_per_pixel)) {
-                       sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
+       while( (sisbios_mode[ivideo->sisfb_mode_idx].mode_no[0] != 0) &&
+              (sisbios_mode[ivideo->sisfb_mode_idx].xres <= var->xres) ) {
+               if( (sisbios_mode[ivideo->sisfb_mode_idx].xres == var->xres) &&
+                   (sisbios_mode[ivideo->sisfb_mode_idx].yres == var->yres) &&
+                   (sisbios_mode[ivideo->sisfb_mode_idx].bpp == var->bits_per_pixel)) {
+                       ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
                        found_mode = 1;
                        break;
                }
-               sisfb_mode_idx++;
+               ivideo->sisfb_mode_idx++;
        }
 
-       if(found_mode)
-               sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx, ivideo.currentvbflags);
-       else
-               sisfb_mode_idx = -1;
+       if(found_mode) {
+               ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo,
+                               ivideo->sisfb_mode_idx, ivideo->currentvbflags);
+       } else {
+               ivideo->sisfb_mode_idx = -1;
+       }
 
-               if(sisfb_mode_idx < 0) {
+               if(ivideo->sisfb_mode_idx < 0) {
                printk(KERN_ERR "sisfb: Mode %dx%dx%d not supported\n", var->xres,
                       var->yres, var->bits_per_pixel);
-               sisfb_mode_idx = old_mode;
+               ivideo->sisfb_mode_idx = old_mode;
                return -EINVAL;
        }
 
-       if(sisfb_search_refresh_rate(ivideo.refresh_rate, sisfb_mode_idx) == 0) {
-               sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
-               ivideo.refresh_rate = 60;
+       if(sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx) == 0) {
+               ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx;
+               ivideo->refresh_rate = 60;
        }
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       if(sisfb_thismonitor.datavalid) {
-          if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
-                                sisfb_rate_idx, ivideo.refresh_rate)) {
+       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");
           }
        }
@@ -1089,64 +1141,77 @@ static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 #else
        if(isactive) {
 #endif
-               sisfb_pre_setmode();
+               sisfb_pre_setmode(ivideo);
 
-               if(SiSSetMode(&SiS_Pr, &sishw_ext, sisfb_mode_no) == 0) {
-                       printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", sisfb_mode_no);
+               if(SiSSetMode(&ivideo->SiS_Pr, &ivideo->sishw_ext, ivideo->mode_no) == 0) {
+                       printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no);
                        return -EINVAL;
                }
 
                outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
 
-               ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
-               ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
-               ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
-               ivideo.org_x = ivideo.org_y = 0;
-               ivideo.video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
-               ivideo.accel = 0;
-               if(sisfb_accel) {
-                  ivideo.accel = (var->accel_flags & FB_ACCELF_TEXT) ? -1 : 0;
-               }
+               sisfb_post_setmode(ivideo);
 
-               sisfb_set_vparms();
+               ivideo->video_bpp    = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
+               ivideo->video_width  = sisbios_mode[ivideo->sisfb_mode_idx].xres;
+               ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
 
-               ivideo.current_width = ivideo.video_width;
-               ivideo.current_height = ivideo.video_height;
-               ivideo.current_bpp = ivideo.video_bpp;
-               ivideo.current_htotal = htotal;
-               ivideo.current_vtotal = vtotal;
-               ivideo.current_pixclock = var->pixclock;
-               ivideo.current_refresh_rate = ivideo.refresh_rate;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-                sisfb_lastrates[sisfb_mode_no] = ivideo.refresh_rate;
+               sisfb_calc_pitch(ivideo, var);
+               sisfb_set_pitch(ivideo);
+
+               ivideo->accel = 0;
+#if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)
+#ifdef STUPID_ACCELF_TEXT_SHIT
+               if(var->accel_flags & FB_ACCELF_TEXT) {
+                       info->flags &= ~FBINFO_HWACCEL_DISABLED;
+               } else {
+                       info->flags |= FBINFO_HWACCEL_DISABLED;
+               }
+#endif
+               if(!(info->flags & FBINFO_HWACCEL_DISABLED)) ivideo->accel = -1;
+#else
+               if(var->accel_flags & FB_ACCELF_TEXT) ivideo->accel = -1;
 #endif
 
-               sisfb_post_setmode();
+               sisfb_set_vparms(ivideo);
 
+               ivideo->current_width = ivideo->video_width;
+               ivideo->current_height = ivideo->video_height;
+               ivideo->current_bpp = ivideo->video_bpp;
+               ivideo->current_htotal = htotal;
+               ivideo->current_vtotal = vtotal;
+               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;
 }
 
-static int sisfb_pan_var(struct fb_var_screeninfo *var)
+static int
+sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
 {
        unsigned int base;
 
-       if (var->xoffset > (var->xres_virtual - var->xres)) {
+       if(var->xoffset > (var->xres_virtual - var->xres)) {
                return -EINVAL;
        }
        if(var->yoffset > (var->yres_virtual - var->yres)) {
                return -EINVAL;
        }
 
-       base = var->yoffset * var->xres_virtual + var->xoffset;
+       base = (var->yoffset * var->xres_virtual) + var->xoffset;
 
         /* calculate base bpp dep. */
         switch(var->bits_per_pixel) {
+       case 32:
+               break;
         case 16:
                base >>= 1;
                break;
-       case 32:
-               break;
        case 8:
         default:
                base >>= 2;
@@ -1158,81 +1223,27 @@ static int sisfb_pan_var(struct fb_var_screeninfo *var)
         outSISIDXREG(SISCR, 0x0D, base & 0xFF);
        outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
        outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
-       if(sisvga_engine == SIS_315_VGA) {
+       if(ivideo->sisvga_engine == SIS_315_VGA) {
                setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
        }
-        if(ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
-               orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
+        if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
+               orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);
                outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
                outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
                outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF));
-               if(sisvga_engine == SIS_315_VGA) {
+               if(ivideo->sisvga_engine == SIS_315_VGA) {
                        setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
                }
         }
        return 0;
 }
 
-static void sisfb_bpp_to_var(struct fb_var_screeninfo *var)
-{
-       switch(var->bits_per_pixel) {
-          case 8:
-               var->red.offset = var->green.offset = var->blue.offset = 0;
-               var->red.length = var->green.length = var->blue.length = 6;
-               ivideo.video_cmap_len = 256;
-               break;
-          case 16:
-               var->red.offset = 11;
-               var->red.length = 5;
-               var->green.offset = 5;
-               var->green.length = 6;
-               var->blue.offset = 0;
-               var->blue.length = 5;
-               var->transp.offset = 0;
-               var->transp.length = 0;
-               ivideo.video_cmap_len = 16;
-               break;
-          case 32:
-               var->red.offset = 16;
-               var->red.length = 8;
-               var->green.offset = 8;
-               var->green.length = 8;
-               var->blue.offset = 0;
-               var->blue.length = 8;
-               var->transp.offset = 24;
-               var->transp.length = 8;
-               ivideo.video_cmap_len = 16;
-               break;
-       }
-}
-
-void sis_dispinfo(struct ap_data *rec)
-{
-       rec->minfo.bpp      = ivideo.video_bpp;
-       rec->minfo.xres     = ivideo.video_width;
-       rec->minfo.yres     = ivideo.video_height;
-       rec->minfo.v_xres   = ivideo.video_vwidth;
-       rec->minfo.v_yres   = ivideo.video_vheight;
-       rec->minfo.org_x    = ivideo.org_x;
-       rec->minfo.org_y    = ivideo.org_y;
-       rec->minfo.vrate    = ivideo.refresh_rate;
-       rec->iobase         = ivideo.vga_base - 0x30;
-       rec->mem_size       = ivideo.video_size;
-       rec->disp_state     = ivideo.disp_state;
-       rec->version        = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
-       rec->hasVB          = ivideo.hasVB;
-       rec->TV_type        = ivideo.TV_type;
-       rec->TV_plug        = ivideo.TV_plug;
-       rec->chip           = ivideo.chip;
-       rec->vbflags        = ivideo.vbflags;
-       rec->currentvbflags = ivideo.currentvbflags;
-}
-
-/* ------------ FBDev related routines for 2.4 series ----------- */
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-
-static void sisfb_crtc_to_var(struct fb_var_screeninfo *var)
+/* ------------ FBDev related routines for 2.4 series ----------- */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+
+static void
+sisfb_crtc_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
 {
        u16 VRE, VBE, VRS, VBS, VDE, VT;
        u16 HRE, HBE, HRS, HBS, HDE, HT;
@@ -1247,50 +1258,55 @@ static void sisfb_crtc_to_var(struct fb_var_screeninfo *var)
        else
           var->vmode = FB_VMODE_NONINTERLACED;
 
-       switch ((sr_data & 0x1C) >> 2) {
-          case SIS_8BPP_COLOR_MODE:
+       switch((sr_data & 0x1C) >> 2) {
+       case SIS_8BPP_COLOR_MODE:
                var->bits_per_pixel = 8;
                break;
-          case SIS_16BPP_COLOR_MODE:
+       case SIS_16BPP_COLOR_MODE:
                var->bits_per_pixel = 16;
                break;
-          case SIS_32BPP_COLOR_MODE:
+       case SIS_32BPP_COLOR_MODE:
                var->bits_per_pixel = 32;
                break;
        }
 
-       sisfb_bpp_to_var(var);
+       sisfb_bpp_to_var(ivideo, var);
        
        inSISIDXREG(SISSR, 0x0A, sr_data);
-
         inSISIDXREG(SISCR, 0x06, cr_data);
-
         inSISIDXREG(SISCR, 0x07, cr_data2);
 
-       VT = (cr_data & 0xFF) | ((u16) (cr_data2 & 0x01) << 8) |
-            ((u16) (cr_data2 & 0x20) << 4) | ((u16) (sr_data & 0x01) << 10);
+       VT = (cr_data & 0xFF) |
+            ((u16) (cr_data2 & 0x01) << 8) |
+            ((u16) (cr_data2 & 0x20) << 4) |
+            ((u16) (sr_data  & 0x01) << 10);
        A = VT + 2;
 
        inSISIDXREG(SISCR, 0x12, cr_data);
 
-       VDE = (cr_data & 0xff) | ((u16) (cr_data2 & 0x02) << 7) |
-             ((u16) (cr_data2 & 0x40) << 3) | ((u16) (sr_data & 0x02) << 9);
+       VDE = (cr_data & 0xff) |
+             ((u16) (cr_data2 & 0x02) << 7) |
+             ((u16) (cr_data2 & 0x40) << 3) |
+             ((u16) (sr_data  & 0x02) << 9);
        E = VDE + 1;
 
        inSISIDXREG(SISCR, 0x10, cr_data);
 
-       VRS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x04) << 6) |
-             ((u16) (cr_data2 & 0x80) << 2) | ((u16) (sr_data & 0x08) << 7);
+       VRS = (cr_data & 0xff) |
+             ((u16) (cr_data2 & 0x04) << 6) |
+             ((u16) (cr_data2 & 0x80) << 2) |
+             ((u16) (sr_data  & 0x08) << 7);
        F = VRS + 1 - E;
 
        inSISIDXREG(SISCR, 0x15, cr_data);
-
        inSISIDXREG(SISCR, 0x09, cr_data3);
 
        if(cr_data3 & 0x80) var->vmode = FB_VMODE_DOUBLE;
 
-       VBS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x08) << 5) |
-             ((u16) (cr_data3 & 0x20) << 4) | ((u16) (sr_data & 0x04) << 8);
+       VBS = (cr_data & 0xff) |
+             ((u16) (cr_data2 & 0x08) << 5) |
+             ((u16) (cr_data3 & 0x20) << 4) |
+             ((u16) (sr_data & 0x04) << 8);
 
        inSISIDXREG(SISCR, 0x16, cr_data);
 
@@ -1324,7 +1340,6 @@ static void sisfb_crtc_to_var(struct fb_var_screeninfo *var)
        }
 
        inSISIDXREG(SISSR, 0x0b, sr_data);
-
        inSISIDXREG(SISCR, 0x00, cr_data);
 
        HT = (cr_data & 0xff) | ((u16) (sr_data & 0x03) << 8);
@@ -1345,13 +1360,12 @@ static void sisfb_crtc_to_var(struct fb_var_screeninfo *var)
        HBS = (cr_data & 0xff) | ((u16) (sr_data & 0x30) << 4);
 
        inSISIDXREG(SISSR, 0x0c, sr_data);
-
        inSISIDXREG(SISCR, 0x03, cr_data);
-
        inSISIDXREG(SISCR, 0x05, cr_data2);
 
-       HBE = (cr_data & 0x1f) | ((u16) (cr_data2 & 0x80) >> 2) |
-             ((u16) (sr_data & 0x03) << 6);
+       HBE = (cr_data & 0x1f) |
+             ((u16) (cr_data2 & 0x80) >> 2) |
+             ((u16) (sr_data  & 0x03) << 6);
        HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
 
        temp = HBE - ((E - 1) & 255);
@@ -1362,7 +1376,10 @@ static void sisfb_crtc_to_var(struct fb_var_screeninfo *var)
 
        D = B - F - C;
 
-       var->xres = var->xres_virtual = E * 8;
+       var->xres = E * 8;
+       if(var->xres_virtual < var->xres) {
+               var->xres_virtual = var->xres;
+       }
 
        if((var->xres == 320) &&
           (var->yres == 200 || var->yres == 240)) {
@@ -1399,14 +1416,13 @@ static void sisfb_crtc_to_var(struct fb_var_screeninfo *var)
        if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
           VT <<= 1;
        }
-       hrate = ivideo.refresh_rate * VT / 2;
+       hrate = ivideo->refresh_rate * VT / 2;
        drate = (hrate * HT) / 1000;
        var->pixclock = (u32) (1000000000 / drate);
 
-       if(sisfb_ypan) {
-          maxyres = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
-          if(maxyres > 32767) maxyres = 32767;
-          if(sisfb_max) {
+       if(ivideo->sisfb_ypan) {
+          maxyres = sisfb_calc_maxyres(ivideo, var);
+          if(ivideo->sisfb_max) {
              var->yres_virtual = maxyres;
           } else {
              if(var->yres_virtual > maxyres) {
@@ -1416,42 +1432,48 @@ static void sisfb_crtc_to_var(struct fb_var_screeninfo *var)
           if(var->yres_virtual <= var->yres) {
              var->yres_virtual = var->yres;
           }
-       } else
+       } else {
           var->yres_virtual = var->yres;
+       }
 
 }
 
-static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
-                        unsigned *transp, struct fb_info *fb_info)
+static int
+sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
+                        unsigned *transp, struct fb_info *info)
 {
-       if (regno >= ivideo.video_cmap_len)
-               return 1;
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+
+       if(regno >= ivideo->video_cmap_len) return 1;
 
-       *red sis_palette[regno].red;
-       *green = sis_palette[regno].green;
-       *blue sis_palette[regno].blue;
+       *red   = ivideo->sis_palette[regno].red;
+       *green = ivideo->sis_palette[regno].green;
+       *blue  = ivideo->sis_palette[regno].blue;
        *transp = 0;
+
        return 0;
 }
 
-static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
-                           unsigned transp, struct fb_info *fb_info)
+static int
+sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+                           unsigned transp, struct fb_info *info)
 {
-       if (regno >= ivideo.video_cmap_len)
-               return 1;
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
 
-       sis_palette[regno].red = red;
-       sis_palette[regno].green = green;
-       sis_palette[regno].blue = blue;
+       if(regno >= ivideo->video_cmap_len) return 1;
 
-       switch (ivideo.video_bpp) {
+       ivideo->sis_palette[regno].red   = red;
+       ivideo->sis_palette[regno].green = green;
+       ivideo->sis_palette[regno].blue  = blue;
+
+       switch(ivideo->video_bpp) {
 #ifdef FBCON_HAS_CFB8
        case 8:
                outSISREG(SISDACA, regno);
                outSISREG(SISDACD, (red >> 10));
                outSISREG(SISDACD, (green >> 10));
                outSISREG(SISDACD, (blue >> 10));
-               if (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+               if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
                        outSISREG(SISDAC2A, regno);
                        outSISREG(SISDAC2D, (red >> 8));
                        outSISREG(SISDAC2D, (green >> 8));
@@ -1461,317 +1483,250 @@ static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigne
 #endif
 #ifdef FBCON_HAS_CFB16
        case 16:
-               sis_fbcon_cmap.cfb16[regno] =
+               ivideo->sis_fbcon_cmap.cfb16[regno] =
                    ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
                break;
 #endif
 #ifdef FBCON_HAS_CFB32
        case 32:
-               red >>= 8;
+               red   >>= 8;
                green >>= 8;
-               blue >>= 8;
-               sis_fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);
+               blue  >>= 8;
+               ivideo->sis_fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);
                break;
 #endif
        }
+
        return 0;
 }
 
-static void sisfb_set_disp(int con, struct fb_var_screeninfo *var,
-                           struct fb_info *info)
+static void
+sisfb_set_disp(int con, struct fb_var_screeninfo *var, struct fb_info *info)
 {
+       struct sis_video_info    *ivideo = (struct sis_video_info *)info->par;
+       struct display           *display;
+       struct display_switch    *sw;
        struct fb_fix_screeninfo fix;
        long   flags;
-       struct display *display;
-       struct display_switch *sw;
 
-       if(con >= 0)
-               display = &fb_display[con];
-       else
-               display = &sis_disp;
+       display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
 
-       sisfb_get_fix(&fix, con, 0);
+       sisfb_get_fix(&fix, con, info);
 
-       display->screen_base = ivideo.video_vbase;
+       display->var = *var;
+       display->screen_base = (char *)ivideo->video_vbase;
        display->visual = fix.visual;
        display->type = fix.type;
        display->type_aux = fix.type_aux;
        display->ypanstep = fix.ypanstep;
        display->ywrapstep = fix.ywrapstep;
        display->line_length = fix.line_length;
-       display->next_line = fix.line_length;
        display->can_soft_blank = 1;
-       display->inverse = sisfb_inverse;
-       display->var = *var;
+       display->inverse = ivideo->sisfb_inverse;
+       display->next_line = fix.line_length;
 
        save_flags(flags);
 
-       switch (ivideo.video_bpp) {
+       switch(ivideo->video_bpp) {
 #ifdef FBCON_HAS_CFB8
-          case 8:
-#ifdef SISFBACCEL
-               sw = ivideo.accel ? &fbcon_sis8 : &fbcon_cfb8;
-#else
-               sw = &fbcon_cfb8;
-#endif
+       case 8: sw = ivideo->accel ? &fbcon_sis8 : &fbcon_cfb8;
                break;
 #endif
 #ifdef FBCON_HAS_CFB16
-          case 16:
-#ifdef SISFBACCEL
-               sw = ivideo.accel ? &fbcon_sis16 : &fbcon_cfb16;
-#else
-               sw = &fbcon_cfb16;
-#endif
-               display->dispsw_data = sis_fbcon_cmap.cfb16;
+       case 16:sw = ivideo->accel ? &fbcon_sis16 : &fbcon_cfb16;
+               display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb16;
                break;
 #endif
 #ifdef FBCON_HAS_CFB32
-          case 32:
-#ifdef SISFBACCEL
-               sw = ivideo.accel ? &fbcon_sis32 : &fbcon_cfb32;
-#else
-               sw = &fbcon_cfb32;
-#endif
-               display->dispsw_data = sis_fbcon_cmap.cfb32;
+       case 32:sw = ivideo->accel ? &fbcon_sis32 : &fbcon_cfb32;
+               display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb32;
                break;
 #endif
-          default:
-               sw = &fbcon_dummy;
-               return;
+       default:sw = &fbcon_dummy;
+               break;
        }
-       memcpy(&sisfb_sw, sw, sizeof(*sw));
-       display->dispsw = &sisfb_sw;
+       memcpy(&ivideo->sisfb_sw, sw, sizeof(*sw));
+       display->dispsw = &ivideo->sisfb_sw;
+
        restore_flags(flags);
 
-        if(sisfb_ypan) {
+        if(ivideo->sisfb_ypan) {
            /* display->scrollmode = 0;  */
        } else {
            display->scrollmode = SCROLL_YREDRAW;
-           sisfb_sw.bmove = fbcon_redraw_bmove;
+           ivideo->sisfb_sw.bmove = fbcon_redraw_bmove;
        }
 }
 
-static void sisfb_do_install_cmap(int con, struct fb_info *info)
+static void
+sisfb_do_install_cmap(int con, struct fb_info *info)
 {
-        if (con != currcon)
-               return;
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+
+        if(con != ivideo->currcon) return;
 
-        if (fb_display[con].cmap.len)
+        if(fb_display[con].cmap.len) {
                fb_set_cmap(&fb_display[con].cmap, 1, sisfb_setcolreg, info);
-        else
-               fb_set_cmap(fb_default_cmap(ivideo.video_cmap_len), 1,
-                           sisfb_setcolreg, info);
+        } else {
+               int size = sisfb_get_cmap_len(&fb_display[con].var);
+               fb_set_cmap(fb_default_cmap(size), 1, sisfb_setcolreg, info);
+       }
 }
 
-
-static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
-                        struct fb_info *info)
+static int
+sisfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
 {
-       if(con == -1)
-               memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
-       else
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+
+       if(con == -1) {
+               memcpy(var, &ivideo->default_var, sizeof(struct fb_var_screeninfo));
+       } else {
                *var = fb_display[con].var;
+       }
 
-       if(sisfb_fstn) {
-          if (var->xres == 320 && var->yres == 480)
-               var->yres = 240;
+       if(ivideo->sisfb_fstn) {
+               if(var->xres == 320 && var->yres == 480) var->yres = 240;
         }
 
        return 0;
 }
 
-static int sisfb_set_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)
 {
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
        int err;
-       unsigned int cols, rows;
 
        fb_display[con].var.activate = FB_ACTIVATE_NOW;
-        if(sisfb_do_set_var(var, con == currcon, info)) {
-               sisfb_crtc_to_var(var);
+
+        if(sisfb_do_set_var(var, con == ivideo->currcon, info)) {
+               sisfb_crtc_to_var(ivideo, var);
                return -EINVAL;
        }
 
-       sisfb_crtc_to_var(var);
+       sisfb_crtc_to_var(ivideo, var);
 
        sisfb_set_disp(con, var, info);
 
-       if(info->changevar)
-               (*info->changevar) (con);
+       if(info->changevar) {
+               (*info->changevar)(con);
+       }
 
-       if((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0)))
+       if((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0))) {
                return err;
+       }
 
        sisfb_do_install_cmap(con, info);
 
-       cols = sisbios_mode[sisfb_mode_idx].cols;
-       rows = sisbios_mode[sisfb_mode_idx].rows;
-#if 0
-       /* Why was this called here? */
+#if 0  /* Why was this called here? */
+       unsigned int cols, rows;
+       cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;
+       rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;
        vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
 #endif
-
        return 0;
 }
 
-static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-                         struct fb_info *info)
+static int
+sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
 {
-        if (con == currcon)
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+       struct display *display;
+
+       display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
+
+        if(con == ivideo->currcon) {
+
                return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
 
-       else if (fb_display[con].cmap.len)
-               fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-       else
-               fb_copy_cmap(fb_default_cmap(ivideo.video_cmap_len), cmap, kspc ? 0 : 2);
+       } else if(display->cmap.len) {
 
-       return 0;
-}
+               fb_copy_cmap(&display->cmap, cmap, kspc ? 0 : 2);
 
-static int sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-                         struct fb_info *info)
-{
-       int err;
+       } else {
 
-       if (!fb_display[con].cmap.len) {
-               err = fb_alloc_cmap(&fb_display[con].cmap, ivideo.video_cmap_len, 0);
-               if (err)
-                       return err;
-       }
-        
-       if (con == currcon)
-               return fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);
+               int size = sisfb_get_cmap_len(&display->var);
+               fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
 
-       else
-               fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+       }
 
        return 0;
 }
 
-static int sisfb_pan_display(struct fb_var_screeninfo *var, int con,
-                            struct fb_info* info)
+static int
+sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
 {
-       int err;
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+       struct display *display;
+       int err, size;
 
-       if (var->vmode & FB_VMODE_YWRAP) {
-               if (var->yoffset < 0 || var->yoffset >= fb_display[con].var.yres_virtual || var->xoffset)
-                       return -EINVAL;
-       } else {
-               if (var->xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual ||
-                   var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)
-                       return -EINVAL;
-       }
+       display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
 
-        if(con == currcon) {
-          if((err = sisfb_pan_var(var)) < 0) return err;
+       size = sisfb_get_cmap_len(&display->var);
+       if(display->cmap.len != size) {
+               err = fb_alloc_cmap(&display->cmap, size, 0);
+               if(err) return err;
+       }
+        
+       if(con == ivideo->currcon) {
+               return fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);
+       } else {
+               fb_copy_cmap(cmap, &display->cmap, kspc ? 0 : 1);
        }
-
-       fb_display[con].var.xoffset = var->xoffset;
-       fb_display[con].var.yoffset = var->yoffset;
-       if (var->vmode & FB_VMODE_YWRAP)
-               fb_display[con].var.vmode |= FB_VMODE_YWRAP;
-       else
-               fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
 
        return 0;
 }
 
-static int sisfb_mmap(struct fb_info *info, struct file *file,
-                     struct vm_area_struct *vma)
+static int
+sisfb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info* info)
 {
-       struct fb_var_screeninfo var;
-       unsigned long start;
-       unsigned long off;
-       u32 len, mmio_off;
-
-       if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT))  return -EINVAL;
-
-       off = vma->vm_pgoff << PAGE_SHIFT;
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+       int err;
 
-       start = (unsigned long) ivideo.video_base;
-       len = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.video_size);
-#if 0
-       if (off >= len) {
-               off -= len;
-#endif
-       /* By Jake Page: Treat mmap request with offset beyond heapstart
-        *               as request for mapping the mmio area 
-        */
-       mmio_off = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.heapstart);
-       if(off >= mmio_off) {
-               off -= mmio_off;                
-               sisfb_get_var(&var, currcon, info);
-               if(var.accel_flags) return -EINVAL;
+       if(var->vmode & FB_VMODE_YWRAP) return -EINVAL;
 
-               start = (unsigned long) ivideo.mmio_base;
-               len = PAGE_ALIGN((start & ~PAGE_MASK) + sisfb_mmio_size);
+       if((var->xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual) ||
+          (var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)) {
+               return -EINVAL;
        }
 
-       start &= PAGE_MASK;
-       if((vma->vm_end - vma->vm_start + off) > len)   return -EINVAL;
-
-       off += start;
-       vma->vm_pgoff = off >> PAGE_SHIFT;
-       vma->vm_flags |= VM_IO;   /* by Jake Page; is that really needed? */
+        if(con == ivideo->currcon) {
+               if((err = sisfb_pan_var(ivideo, var)) < 0) return err;
+       }
 
-#if defined(__i386__) || defined(__x86_64__)
-       if (boot_cpu_data.x86 > 3)
-               pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
-#endif
-        /* RedHat requires vma as the first paramater to the following call */
-       if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start,
-                               vma->vm_page_prot))
-               return -EAGAIN;
+       fb_display[con].var.xoffset = var->xoffset;
+       fb_display[con].var.yoffset = var->yoffset;
 
        return 0;
 }
 
-static void sis_get_glyph(struct fb_info *info, SIS_GLYINFO *gly)
+static int
+sisfb_update_var(int con, struct fb_info *info)
 {
-       struct display *p = &fb_display[currcon];
-       u16 c;
-       u8 *cdat;
-       int widthb;
-       u8 *gbuf = gly->gmask;
-       int size;
-
-       gly->fontheight = fontheight(p);
-       gly->fontwidth = fontwidth(p);
-       widthb = (fontwidth(p) + 7) / 8;
-
-       c = gly->ch & p->charmask;
-       if (fontwidth(p) <= 8)
-               cdat = p->fontdata + c * fontheight(p);
-       else
-               cdat = p->fontdata + (c * fontheight(p) << 1);
-
-       size = fontheight(p) * widthb;
-       memcpy(gbuf, cdat, size);
-       gly->ngmask = size;
-}
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
 
-static int sisfb_update_var(int con, struct fb_info *info)
-{
-        return(sisfb_pan_var(&fb_display[con].var));
+        return(sisfb_pan_var(ivideo, &fb_display[con].var));
 }
 
-static int sisfb_switch(int con, struct fb_info *info)
+static int
+sisfb_switch(int con, struct fb_info *info)
 {
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
        int cols, rows;
 
-        if(fb_display[currcon].cmap.len)
-               fb_get_cmap(&fb_display[currcon].cmap, 1, sis_getcolreg, info);
+        if(fb_display[ivideo->currcon].cmap.len) {
+               fb_get_cmap(&fb_display[ivideo->currcon].cmap, 1, sis_getcolreg, info);
+       }
 
        fb_display[con].var.activate = FB_ACTIVATE_NOW;
 
-       if(!memcmp(&fb_display[con].var, &fb_display[currcon].var,
-                                  sizeof(struct fb_var_screeninfo))) {
-               currcon = con;
+       if(!memcmp(&fb_display[con].var, &fb_display[ivideo->currcon].var,
+                                       sizeof(struct fb_var_screeninfo))) {
+               ivideo->currcon = con;
                return 1;
        }
 
-       currcon = con;
+       ivideo->currcon = con;
 
        sisfb_do_set_var(&fb_display[con].var, 1, info);
 
@@ -1779,8 +1734,8 @@ static int sisfb_switch(int con, struct fb_info *info)
 
        sisfb_do_install_cmap(con, info);
 
-       cols = sisbios_mode[sisfb_mode_idx].cols;
-       rows = sisbios_mode[sisfb_mode_idx].rows;
+       cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;
+       rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;
        vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
 
        sisfb_update_var(con, info);
@@ -1788,55 +1743,46 @@ static int sisfb_switch(int con, struct fb_info *info)
        return 1;
 }
 
-static void sisfb_blank(int blank, struct fb_info *info)
+static void
+sisfb_blank(int blank, struct fb_info *info)
 {
-       sisfb_myblank(blank);
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+
+       sisfb_myblank(ivideo, blank);
 }
 #endif
 
-/* ------------ FBDev related routines for 2.5 series ----------- */
+/* ------------ 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)
+static int
+sisfb_open(struct fb_info *info, int user)
 {
-    return 0;
+       return 0;
 }
 
-static int sisfb_release(struct fb_info *info, int user)
+static int
+sisfb_release(struct fb_info *info, int user)
 {
-    return 0;
+       return 0;
 }
 
-static int sisfb_get_cmap_len(const struct fb_var_screeninfo *var)
+static int
+sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+               unsigned transp, struct fb_info *info)
 {
-       int rc = 16;            
-
-       switch(var->bits_per_pixel) {
-       case 8:
-               rc = 256;       
-               break;
-       case 16:
-       case 32:
-               rc = 16;
-               break;
-       }
-       return rc;
-}
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
 
-static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
-                           unsigned transp, struct fb_info *info)
-{
-       if (regno >= sisfb_get_cmap_len(&info->var))
-               return 1;
+       if(regno >= sisfb_get_cmap_len(&info->var)) return 1;
 
-       switch (info->var.bits_per_pixel) {
+       switch(info->var.bits_per_pixel) {
        case 8:
                outSISREG(SISDACA, regno);
                outSISREG(SISDACD, (red >> 10));
                outSISREG(SISDACD, (green >> 10));
                outSISREG(SISDACD, (blue >> 10));
-               if (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+               if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
                        outSISREG(SISDAC2A, regno);
                        outSISREG(SISDAC2D, (red >> 8));
                        outSISREG(SISDAC2D, (green >> 8));
@@ -1851,28 +1797,31 @@ static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigne
                red >>= 8;
                green >>= 8;
                blue >>= 8;
-               ((u32 *) (info->pseudo_palette))[regno] =
-                       (red << 16) | (green << 8) | (blue);
+               ((u32 *)(info->pseudo_palette))[regno] =
+                               (red << 16) | (green << 8) | (blue);
                break;
        }
        return 0;
 }
 
-static int sisfb_set_par(struct fb_info *info)
+static int
+sisfb_set_par(struct fb_info *info)
 {
        int err;
 
-        if((err = sisfb_do_set_var(&info->var, 1, info)))
+        if((err = sisfb_do_set_var(&info->var, 1, info))) {
                return err;
+       }
 
        sisfb_get_fix(&info->fix, info->currcon, info);
 
        return 0;
 }
 
-static int sisfb_check_var(struct fb_var_screeninfo *var,
-                           struct fb_info *info)
+static int
+sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
        unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
        unsigned int drate = 0, hrate = 0, maxyres;
        int found_mode = 0;
@@ -1902,12 +1851,12 @@ static int sisfb_check_var(struct fb_var_screeninfo *var,
        }
 
        search_idx = 0;
-       while( (sisbios_mode[search_idx].mode_no != 0) &&
+       while( (sisbios_mode[search_idx].mode_no[0] != 0) &&
               (sisbios_mode[search_idx].xres <= var->xres) ) {
                if( (sisbios_mode[search_idx].xres == var->xres) &&
                    (sisbios_mode[search_idx].yres == var->yres) &&
                    (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {
-                       if(sisfb_validate_mode(search_idx, ivideo.currentvbflags) > 0) {
+                       if(sisfb_validate_mode(ivideo, search_idx, ivideo->currentvbflags) > 0) {
                           found_mode = 1;
                           break;
                        }
@@ -1916,13 +1865,12 @@ static int sisfb_check_var(struct fb_var_screeninfo *var,
        }
 
        if(!found_mode) {
-
                 search_idx = 0;
-               while(sisbios_mode[search_idx].mode_no != 0) {
+               while(sisbios_mode[search_idx].mode_no[0] != 0) {
                   if( (var->xres <= sisbios_mode[search_idx].xres) &&
                       (var->yres <= sisbios_mode[search_idx].yres) &&
                       (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {
-                         if(sisfb_validate_mode(search_idx, ivideo.currentvbflags) > 0) {
+                         if(sisfb_validate_mode(ivideo,search_idx, ivideo->currentvbflags) > 0) {
                             found_mode = 1;
                             break;
                          }
@@ -1946,24 +1894,25 @@ static int sisfb_check_var(struct fb_var_screeninfo *var,
                }
        }
 
-       if( ((ivideo.vbflags & VB_LVDS) ||                      /* Slave modes on LVDS and 301B-DH */
-            ((ivideo.vbflags & VB_30xBDH) && (ivideo.currentvbflags & CRT2_LCD))) &&
+       if( ((ivideo->vbflags & VB_LVDS) ||                     /* Slave modes on LVDS and 301B-DH */
+            ((ivideo->vbflags & VB_30xBDH) && (ivideo->currentvbflags & CRT2_LCD))) &&
            (var->bits_per_pixel == 8) ) {
                refresh_rate = 60;
                recalc_clock = TRUE;
-       } else if( (ivideo.current_htotal == htotal) &&         /* x=x & y=y & c=c -> assume depth change */
-                  (ivideo.current_vtotal == vtotal) &&
-                  (ivideo.current_pixclock == pixclock) ) {
+       } else if( (ivideo->current_htotal == htotal) &&        /* x=x & y=y & c=c -> assume depth change */
+                  (ivideo->current_vtotal == vtotal) &&
+                  (ivideo->current_pixclock == pixclock) ) {
                drate = 1000000000 / pixclock;
                hrate = (drate * 1000) / htotal;
                refresh_rate = (unsigned int) (hrate * 2 / vtotal);
-       } else if( ( (ivideo.current_htotal != htotal) ||       /* x!=x | y!=y & c=c -> invalid pixclock */
-                    (ivideo.current_vtotal != vtotal) ) &&
-                  (ivideo.current_pixclock == var->pixclock) ) {
-               if(sisfb_lastrates[sisbios_mode[search_idx].mode_no]) {
-                       refresh_rate = sisfb_lastrates[sisbios_mode[search_idx].mode_no];
-               } else if(sisfb_parm_rate != -1) {
-                       refresh_rate = sisfb_parm_rate;
+       } else if( ( (ivideo->current_htotal != htotal) ||      /* x!=x | y!=y & c=c -> invalid pixclock */
+                    (ivideo->current_vtotal != vtotal) ) &&
+                  (ivideo->current_pixclock == var->pixclock) ) {
+               if(ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]]) {
+                       refresh_rate = ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]];
+               } else if(ivideo->sisfb_parm_rate != -1) {
+                       /* Sic, sisfb_parm_rate - want to know originally desired rate here */
+                       refresh_rate = ivideo->sisfb_parm_rate;
                } else {
                        refresh_rate = 60;
                }
@@ -1972,56 +1921,51 @@ static int sisfb_check_var(struct fb_var_screeninfo *var,
                drate = 1000000000 / pixclock;
                hrate = (drate * 1000) / htotal;
                refresh_rate = (unsigned int) (hrate * 2 / vtotal);
-       } else if(ivideo.current_refresh_rate) {
-               refresh_rate = ivideo.current_refresh_rate;
+       } else if(ivideo->current_refresh_rate) {
+               refresh_rate = ivideo->current_refresh_rate;
                recalc_clock = TRUE;
        } else {
                refresh_rate = 60;
                recalc_clock = TRUE;
        }
 
-       myrateindex = sisfb_search_refresh_rate(refresh_rate, search_idx);
+       myrateindex = sisfb_search_refresh_rate(ivideo, refresh_rate, search_idx);
 
        /* Eventually recalculate timing and clock */
        if(recalc_clock) {
           if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
-          var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&SiS_Pr, &sishw_ext,
-                                               sisbios_mode[search_idx].mode_no, myrateindex));
-          sisfb_mode_rate_to_ddata(&SiS_Pr, &sishw_ext,
-                                       sisbios_mode[search_idx].mode_no, myrateindex,
-                                       &var->left_margin, &var->right_margin,
-                                       &var->upper_margin, &var->lower_margin,
-                                       &var->hsync_len, &var->vsync_len,
-                                       &var->sync, &var->vmode);
+          var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr,
+                                               &ivideo->sishw_ext,
+                                               sisbios_mode[search_idx].mode_no[ivideo->mni],
+                                               myrateindex));
+          sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, &ivideo->sishw_ext,
+                                   sisbios_mode[search_idx].mode_no[ivideo->mni], myrateindex, var);
           if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-               var->pixclock <<= 1;
+             var->pixclock <<= 1;
           }
        }
 
-       if(sisfb_thismonitor.datavalid) {
-          if(!sisfb_verify_rate(&sisfb_thismonitor, search_idx,
+       if(ivideo->sisfb_thismonitor.datavalid) {
+          if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, search_idx,
                                 myrateindex, refresh_rate)) {
              printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
           }
        }
 
        /* Adapt RGB settings */
-       sisfb_bpp_to_var(var);  
+       sisfb_bpp_to_var(ivideo, var);
        
        /* Sanity check for offsets */
-       if (var->xoffset < 0)
-               var->xoffset = 0;
-       if (var->yoffset < 0)
-               var->yoffset = 0;
+       if(var->xoffset < 0) var->xoffset = 0;
+       if(var->yoffset < 0) var->yoffset = 0;
 
-       /* Horiz-panning not supported */
-       if(var->xres != var->xres_virtual)
-               var->xres_virtual = var->xres;
+       if(var->xres > var->xres_virtual) {
+          var->xres_virtual = var->xres;
+       }
 
-       if(sisfb_ypan) {
-          maxyres = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
-          if(maxyres > 32767) maxyres = 32767;
-          if(sisfb_max) {
+       if(ivideo->sisfb_ypan) {
+          maxyres = sisfb_calc_maxyres(ivideo, var);
+          if(ivideo->sisfb_max) {
              var->yres_virtual = maxyres;
           } else {
              if(var->yres_virtual > maxyres) {
@@ -2040,310 +1984,241 @@ static int sisfb_check_var(struct fb_var_screeninfo *var,
        }
        
        /* Truncate offsets to maximum if too high */
-       if(var->xoffset > var->xres_virtual - var->xres)
-               var->xoffset = var->xres_virtual - var->xres - 1;
+       if(var->xoffset > var->xres_virtual - var->xres) {
+          var->xoffset = var->xres_virtual - var->xres - 1;
+       }
 
-       if(var->yoffset > var->yres_virtual - var->yres)
-               var->yoffset = var->yres_virtual - var->yres - 1;
+       if(var->yoffset > var->yres_virtual - var->yres) {
+          var->yoffset = var->yres_virtual - var->yres - 1;
+       }
        
        /* Set everything else to 0 */
        var->red.msb_right = 
-           var->green.msb_right =
-           var->blue.msb_right =
-           var->transp.offset = var->transp.length = var->transp.msb_right = 0;                
+       var->green.msb_right =
+       var->blue.msb_right =
+       var->transp.offset =
+       var->transp.length =
+       var->transp.msb_right = 0;
 
        return 0;
 }
 
-static int sisfb_pan_display(struct fb_var_screeninfo *var,
-                            struct fb_info* info)
+static int
+sisfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info)
 {
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
        int err;
 
-       if (var->xoffset > (var->xres_virtual - var->xres))
+       if(var->xoffset > (var->xres_virtual - var->xres)) {
                return -EINVAL;
-       if (var->yoffset > (var->yres_virtual - var->yres))
+       }
+       if(var->yoffset > (var->yres_virtual - var->yres)) {
                return -EINVAL;
-
-       if (var->vmode & FB_VMODE_YWRAP) {
-               if (var->yoffset < 0 ||
-                   var->yoffset >= info->var.yres_virtual ||
-                   var->xoffset)
-                       return -EINVAL;
-       } else {
-               if (var->xoffset + info->var.xres > info->var.xres_virtual ||
-                   var->yoffset + info->var.yres > info->var.yres_virtual)
-                       return -EINVAL;
        }
-    
-       if((err = sisfb_pan_var(var)) < 0) return err;
-
-       info->var.xoffset = var->xoffset;
-       info->var.yoffset = var->yoffset;
-       if (var->vmode & FB_VMODE_YWRAP)
-               info->var.vmode |= FB_VMODE_YWRAP;
-       else
-               info->var.vmode &= ~FB_VMODE_YWRAP;
-
-       return 0;
-}
-
-static int sisfb_mmap(struct fb_info *info, struct file *file,
-                     struct vm_area_struct *vma)
-{
-       unsigned long start;
-       unsigned long off;
-       u32 len, mmio_off;
-
-       if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT))  return -EINVAL;
 
-       off = vma->vm_pgoff << PAGE_SHIFT;
+       if(var->vmode & FB_VMODE_YWRAP) return -EINVAL;
 
-       start = (unsigned long) ivideo.video_base;
-       len = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.video_size);
-#if 0
-       if (off >= len) {
-               off -= len;
-#endif
-       /* By Jake Page: Treat mmap request with offset beyond heapstart
-        *               as request for mapping the mmio area 
-        */
-       mmio_off = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.heapstart);
-       if(off >= mmio_off) {
-               off -= mmio_off;                
-               if(info->var.accel_flags) return -EINVAL;
-
-               start = (unsigned long) ivideo.mmio_base;
-               len = PAGE_ALIGN((start & ~PAGE_MASK) + sisfb_mmio_size);
+       if(var->xoffset + info->var.xres > info->var.xres_virtual ||
+          var->yoffset + info->var.yres > info->var.yres_virtual) {
+               return -EINVAL;
        }
 
-       start &= PAGE_MASK;
-       if((vma->vm_end - vma->vm_start + off) > len)   return -EINVAL;
-
-       off += start;
-       vma->vm_pgoff = off >> PAGE_SHIFT;
-       vma->vm_flags |= VM_IO;   /* by Jake Page; is that really needed? */
+       if((err = sisfb_pan_var(ivideo, var)) < 0) return err;
 
-#if defined(__i386__) || defined(__x86_64__)
-       if (boot_cpu_data.x86 > 3)
-               pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
-#endif
-       if (io_remap_page_range(vma, vma->vm_start, off, vma->vm_end - vma->vm_start,
-                               vma->vm_page_prot))
-               return -EAGAIN;
+       info->var.xoffset = var->xoffset;
+       info->var.yoffset = var->yoffset;
 
        return 0;
 }
 
-static int sisfb_blank(int blank, struct fb_info *info)
+static int
+sisfb_blank(int blank, struct fb_info *info)
 {
-       return(sisfb_myblank(blank));
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+
+       return(sisfb_myblank(ivideo, blank));
 }
 
 #endif
 
 /* ----------- FBDev related routines for all series ---------- */
 
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-static int sisfb_ioctl(struct inode *inode, struct file *file,
-                      unsigned int cmd, unsigned long arg,
-                      struct fb_info *info)
-#else
-static int sisfb_ioctl(struct inode *inode, struct file *file,
-                      unsigned int cmd, unsigned long arg, int con,
-                      struct fb_info *info)
-#endif
-{
-       struct sis_memreq sismemreq;
-       struct ap_data sisapdata;
-       unsigned long sismembase = 0;
+static int
+sisfb_ioctl(struct inode *inode, struct file *file,
+            unsigned int cmd, unsigned long arg,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       SIS_GLYINFO sisglyinfo;
+           int con,
 #endif
+           struct fb_info *info)
+{
+       struct sis_video_info   *ivideo = (struct sis_video_info *)info->par;
+       struct sis_memreq       sismemreq;
+       struct fb_vblank        sisvbblank;
+       sisfb_info              x;
+       u32                     gpu32 = 0;
+       static int              count = 0;
+       u32 __user              *argp = (u32 __user *) arg;
 
        switch (cmd) {
           case FBIO_ALLOC:
-               if(!capable(CAP_SYS_RAWIO))
+               if(!capable(CAP_SYS_RAWIO)) {
                        return -EPERM;
-               if(copy_from_user(&sismemreq, (void *)arg, sizeof(sismemreq)))
+               }
+               if(copy_from_user(&sismemreq, argp, sizeof(sismemreq))) {
                        return -EFAULT;
+               }
                sis_malloc(&sismemreq);
-               if(copy_to_user((void *)arg, &sismemreq, sizeof(sismemreq))) {
-                       sis_free(sismemreq.offset);
+               if(copy_to_user(argp, &sismemreq, sizeof(sismemreq))) {
+                       sis_free((u32)sismemreq.offset);
                        return -EFAULT;
                }
                break;
+
           case FBIO_FREE:
-               if(!capable(CAP_SYS_RAWIO))
+               if(!capable(CAP_SYS_RAWIO)) {
                        return -EPERM;
-               if(get_user(sismembase, (unsigned long *) arg))
+               }
+               if(get_user(gpu32, argp)) {
                        return -EFAULT;
-               sis_free(sismembase);
+               }
+               sis_free(gpu32);
                break;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-          case FBIOGET_GLYPH:
-               if(copy_from_user(&sisglyinfo, (void *)arg, sizeof(sisglyinfo)))
+
+          case FBIOGET_VBLANK:
+               sisvbblank.count = 0;
+               sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount);
+               if(copy_to_user(argp, &sisvbblank, sizeof(sisvbblank))) {
                        return -EFAULT;
-                sis_get_glyph(info, &sisglyinfo);
-               break;
-          case FBIOPUT_MODEINFO:
-               {
-                       struct mode_info x;
-
-                       if(copy_from_user(&x, (void *)arg, sizeof(x)))
-                               return -EFAULT;
-
-                       ivideo.video_bpp        = x.bpp;
-                       ivideo.video_width      = x.xres;
-                       ivideo.video_height     = x.yres;
-                       ivideo.video_vwidth     = x.v_xres;
-                       ivideo.video_vheight    = x.v_yres;
-                       ivideo.org_x            = x.org_x;
-                       ivideo.org_y            = x.org_y;
-                       ivideo.refresh_rate     = x.vrate;
-                       ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
-                       sisfb_set_vparms();
-                       break;
                }
-#endif
-          case FBIOGET_HWCINFO:
-               {
-                       unsigned long myhwcoffset = 0;
-
-                       if(sisfb_caps & HW_CURSOR_CAP)
-                               myhwcoffset = sisfb_hwcursor_vbase -
-                                   (unsigned long) ivideo.video_vbase;
+               break;
 
-                       return put_user(myhwcoffset, (unsigned long *)arg);
+          case SISFB_GET_INFO_SIZE:
+               return put_user(sizeof(sisfb_info), argp);
 
-                       break;
+          case SISFB_GET_INFO_OLD:
+               if(++count < 50) {
+                  printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
                }
-          case FBIOGET_DISPINFO:
-               sis_dispinfo(&sisapdata);
-               if(copy_to_user((void *)arg, &sisapdata, sizeof(sisapdata)))
-                       return -EFAULT;
-               break;
           case SISFB_GET_INFO:  /* For communication with X driver */
-               {
-                       sisfb_info x;
-
-                       x.sisfb_id = SISFB_ID;
-                       x.sisfb_version = VER_MAJOR;
-                       x.sisfb_revision = VER_MINOR;
-                       x.sisfb_patchlevel = VER_LEVEL;
-                       x.chip_id = ivideo.chip_id;
-                       x.memory = ivideo.video_size / 1024;
-                       x.heapstart = ivideo.heapstart / 1024;
-                       x.fbvidmode = sisfb_mode_no;
-                       x.sisfb_caps = sisfb_caps;
-                       x.sisfb_tqlen = 512; /* yet fixed */
-                       x.sisfb_pcibus = ivideo.pcibus;
-                       x.sisfb_pcislot = ivideo.pcislot;
-                       x.sisfb_pcifunc = ivideo.pcifunc;
-                       x.sisfb_lcdpdc = sisfb_detectedpdc;
-                       x.sisfb_lcda = sisfb_detectedlcda;
-                       x.sisfb_vbflags = ivideo.vbflags;
-                       x.sisfb_currentvbflags = ivideo.currentvbflags;
-                       x.sisfb_scalelcd = SiS_Pr.UsePanelScaler;
-                       x.sisfb_specialtiming = SiS_Pr.SiS_CustomT;
-                       x.sisfb_haveemi = SiS_Pr.HaveEMI ? 1 : 0;
-                       x.sisfb_haveemilcd = SiS_Pr.HaveEMILCD ? 1 : 0;
-                       x.sisfb_emi30 = SiS_Pr.EMI_30;
-                       x.sisfb_emi31 = SiS_Pr.EMI_31;
-                       x.sisfb_emi32 = SiS_Pr.EMI_32;
-                       x.sisfb_emi33 = SiS_Pr.EMI_33;
-                       if(copy_to_user((void *)arg, &x, sizeof(x)))
-                               return -EFAULT;
-                       break;
+               x.sisfb_id         = SISFB_ID;
+               x.sisfb_version    = VER_MAJOR;
+               x.sisfb_revision   = VER_MINOR;
+               x.sisfb_patchlevel = VER_LEVEL;
+               x.chip_id = ivideo->chip_id;
+               x.memory = ivideo->video_size / 1024;
+               x.heapstart = ivideo->heapstart / 1024;
+               if(ivideo->modechanged) {
+                  x.fbvidmode = ivideo->mode_no;
+               } else {
+                  x.fbvidmode = ivideo->modeprechange;
+               }
+               x.sisfb_caps = ivideo->caps;
+               x.sisfb_tqlen = 512; /* yet fixed */
+               x.sisfb_pcibus = ivideo->pcibus;
+               x.sisfb_pcislot = ivideo->pcislot;
+               x.sisfb_pcifunc = ivideo->pcifunc;
+               x.sisfb_lcdpdc = ivideo->detectedpdc;
+               x.sisfb_lcdpdca = ivideo->detectedpdca;
+               x.sisfb_lcda = ivideo->detectedlcda;
+               x.sisfb_vbflags = ivideo->vbflags;
+               x.sisfb_currentvbflags = ivideo->currentvbflags;
+               x.sisfb_scalelcd = ivideo->SiS_Pr.UsePanelScaler;
+               x.sisfb_specialtiming = ivideo->SiS_Pr.SiS_CustomT;
+               x.sisfb_haveemi = ivideo->SiS_Pr.HaveEMI ? 1 : 0;
+               x.sisfb_haveemilcd = ivideo->SiS_Pr.HaveEMILCD ? 1 : 0;
+               x.sisfb_emi30 = ivideo->SiS_Pr.EMI_30;
+               x.sisfb_emi31 = ivideo->SiS_Pr.EMI_31;
+               x.sisfb_emi32 = ivideo->SiS_Pr.EMI_32;
+               x.sisfb_emi33 = ivideo->SiS_Pr.EMI_33;
+               x.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32);
+               x.sisfb_tvypos = (u16)(ivideo->tvypos + 32);
+
+               if(copy_to_user(argp, &x, sizeof(x))) {
+                       return -EFAULT;
+               }
+               break;
+
+          case SISFB_GET_VBRSTATUS_OLD:
+               if(++count < 50) {
+                  printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
                }
           case SISFB_GET_VBRSTATUS:
-               {
-                       if(sisfb_CheckVBRetrace())
-                               return put_user(1UL, (unsigned long *) arg);
-                       else
-                               return put_user(0UL, (unsigned long *) arg);
-                       break;
+               if(sisfb_CheckVBRetrace(ivideo)) {
+                       return put_user((u32)1, argp);
+               } else {
+                       return put_user((u32)0, argp);
+               }
+
+          case SISFB_GET_AUTOMAXIMIZE_OLD:
+               if(++count < 50) {
+                  printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
                }
           case SISFB_GET_AUTOMAXIMIZE:
-               {
-                       if(sisfb_max)
-                               return put_user(1UL, (unsigned long *) arg);
-                       else
-                               return put_user(0UL, (unsigned long *) arg);
-                       break;
+               if(ivideo->sisfb_max) return put_user((u32)1, argp);
+               else                  return put_user((u32)0, argp);
+
+          case SISFB_SET_AUTOMAXIMIZE_OLD:
+               if(++count < 50) {
+                  printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
                }
           case SISFB_SET_AUTOMAXIMIZE:
-               {
-                       unsigned long newmax;
+               if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
+                       return -EFAULT;
+               }
+               ivideo->sisfb_max = (gpu32) ? 1 : 0;
+               break;
+
+          case SISFB_SET_TVPOSOFFSET:
+               if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
+                       return -EFAULT;
+               }
+               sisfb_set_TVxposoffset(ivideo, ((int)(gpu32 >> 16)) - 32);
+               sisfb_set_TVyposoffset(ivideo, ((int)(gpu32 & 0xffff)) - 32);
+               break;
 
-                       if(copy_from_user(&newmax, (unsigned long *)arg, sizeof(newmax)))
-                               return -EFAULT;
+          case SISFB_GET_TVPOSOFFSET:
+               return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)), argp);
 
-                       if(newmax) sisfb_max = 1;
-                       else       sisfb_max = 0;
-                       break;
+          case SISFB_SET_LOCK:
+               if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
+                       return -EFAULT;
                }
+               ivideo->sisfblocked = (gpu32) ? 1 : 0;
+               break;
+
           default:
                return -EINVAL;
        }
        return 0;
 }
 
-
-static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-                        struct fb_info *info)
+static int
+sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
 {
-       memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 
-       strcpy(fix->id, sis_fb_info->modename);
-#else
-       strcpy(fix->id, myid);
-#endif 
+       memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 
-       fix->smem_start = ivideo.video_base;
-
-        if((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
-           if(sisvga_engine == SIS_300_VGA) {
-              if(ivideo.video_size > 0x1000000) {
-                       fix->smem_len = 0xc00000;
-              } else if(ivideo.video_size > 0x800000)
-                       fix->smem_len = 0x800000;
-              else
-                       fix->smem_len = 0x400000;
-            } else {
-               fix->smem_len = ivideo.video_size - 0x100000;
-           }
-        } else
-               fix->smem_len = sisfb_mem * 1024;
+       strcpy(fix->id, ivideo->myid);
 
+       fix->smem_start  = ivideo->video_base;
+       fix->smem_len    = ivideo->sisfb_mem;
        fix->type        = FB_TYPE_PACKED_PIXELS;
        fix->type_aux    = 0;
-       if(ivideo.video_bpp == 8)
-          fix->visual = FB_VISUAL_PSEUDOCOLOR;
-       else
-          fix->visual = FB_VISUAL_TRUECOLOR;
-       fix->xpanstep    = 0;
-
-        if(sisfb_ypan)          fix->ypanstep = 1;
-
+       fix->visual      = (ivideo->video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+       fix->xpanstep    = 1;
+       fix->ypanstep    = (ivideo->sisfb_ypan) ? 1 : 0;
        fix->ywrapstep   = 0;
-       fix->line_length = ivideo.video_linelength;
-       fix->mmio_start  = ivideo.mmio_base;
-       fix->mmio_len    = sisfb_mmio_size;
-       if(sisvga_engine == SIS_300_VGA) 
+       fix->line_length = ivideo->video_linelength;
+       fix->mmio_start  = ivideo->mmio_base;
+       fix->mmio_len    = ivideo->mmio_size;
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
           fix->accel    = FB_ACCEL_SIS_GLAMOUR;
-       else if((ivideo.chip == SIS_330) || (ivideo.chip == SIS_760))
+       } else if((ivideo->chip == SIS_330) || (ivideo->chip == SIS_760)) {
           fix->accel    = FB_ACCEL_SIS_XABRE;
-       else
+       } else {
           fix->accel    = FB_ACCEL_SIS_GLAMOUR_2;
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       fix->reserved[0] = ivideo.video_size & 0xFFFF;
-       fix->reserved[1] = (ivideo.video_size >> 16) & 0xFFFF;
-       fix->reserved[2] = sisfb_caps;
-#endif
+       }
 
        return 0;
 }
@@ -2359,458 +2234,416 @@ static struct fb_ops sisfb_ops = {
        .fb_get_cmap    = sisfb_get_cmap,
        .fb_set_cmap    = sisfb_set_cmap,
         .fb_pan_display = sisfb_pan_display,
-       .fb_ioctl       = sisfb_ioctl,
-       .fb_mmap        = sisfb_mmap,
+       .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,
-       .fb_release   = sisfb_release,
-       .fb_check_var = sisfb_check_var,
-       .fb_set_par   = sisfb_set_par,
-       .fb_setcolreg = sisfb_setcolreg,
+       .owner          = THIS_MODULE,
+       .fb_open        = sisfb_open,
+       .fb_release     = sisfb_release,
+       .fb_check_var   = sisfb_check_var,
+       .fb_set_par     = sisfb_set_par,
+       .fb_setcolreg   = sisfb_setcolreg,
         .fb_pan_display = sisfb_pan_display,
-        .fb_blank     = sisfb_blank,
-       .fb_fillrect  = fbcon_sis_fillrect,
-       .fb_copyarea  = fbcon_sis_copyarea,
-       .fb_imageblit = cfb_imageblit,
-       .fb_cursor    = soft_cursor,    
-       .fb_sync      = fbcon_sis_sync,
-       .fb_ioctl     = sisfb_ioctl,
-       .fb_mmap      = sisfb_mmap,
+        .fb_blank       = sisfb_blank,
+       .fb_fillrect    = fbcon_sis_fillrect,
+       .fb_copyarea    = fbcon_sis_copyarea,
+       .fb_imageblit   = cfb_imageblit,
+       .fb_cursor      = soft_cursor,
+       .fb_sync        = fbcon_sis_sync,
+       .fb_ioctl       = sisfb_ioctl
 };
 #endif
 
-
 /* ---------------- Chip generation dependent routines ---------------- */
 
-#ifdef CONFIG_FB_SIS_300 /* for SiS 300/630/540/730 */
-
-static int sisfb_get_dram_size_300(void)
+static struct pci_dev * sisfb_get_northbridge(int basechipid)
 {
        struct pci_dev *pdev = NULL;
-       int pdev_valid = 0;
-       u8  pci_data, reg;
-       u16 nbridge_id;
-
-       switch (ivideo.chip) {
-          case SIS_540:
-               nbridge_id = PCI_DEVICE_ID_SI_540;
-               break;
-          case SIS_630:
-               nbridge_id = PCI_DEVICE_ID_SI_630;
-               break;
-          case SIS_730:
-               nbridge_id = PCI_DEVICE_ID_SI_730;
-               break;
-          default:
-               nbridge_id = 0;
-               break;
+       int nbridgenum, nbridgeidx, i;
+       const unsigned short nbridgeids[] = {
+               PCI_DEVICE_ID_SI_540,   /* for SiS 540 VGA */
+               PCI_DEVICE_ID_SI_630,   /* for SiS 630/730 VGA */
+               PCI_DEVICE_ID_SI_730,
+               PCI_DEVICE_ID_SI_550,   /* for SiS 550 VGA */
+               PCI_DEVICE_ID_SI_650,   /* for SiS 650/651/740 VGA */
+               PCI_DEVICE_ID_SI_651,
+               PCI_DEVICE_ID_SI_740,
+               PCI_DEVICE_ID_SI_661,   /* for SiS 661/741/660/760 VGA */
+               PCI_DEVICE_ID_SI_741,
+               PCI_DEVICE_ID_SI_660,
+               PCI_DEVICE_ID_SI_760
+       };
+
+       switch(basechipid) {
+#ifdef CONFIG_FB_SIS_300
+       case SIS_540:   nbridgeidx = 0; nbridgenum = 1; break;
+       case SIS_630:   nbridgeidx = 1; nbridgenum = 2; break;
+#endif
+#ifdef CONFIG_FB_SIS_315
+       case SIS_550:   nbridgeidx = 3; nbridgenum = 1; break;
+       case SIS_650:   nbridgeidx = 4; nbridgenum = 3; break;
+       case SIS_660:   nbridgeidx = 7; nbridgenum = 4; break;
+#endif
+       default:        return NULL;
        }
-
-       if (nbridge_id == 0) {  /* 300 */
-
-               inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE,reg);
-               ivideo.video_size =
-                       ((unsigned int) ((reg & SIS_DRAM_SIZE_MASK) + 1) << 20);
-
-       } else {                /* 540, 630, 730 */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
-               pci_for_each_dev(pdev) {
-#else
-               while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
-#endif
-                       if ((pdev->vendor == PCI_VENDOR_ID_SI)
-                                      && (pdev->device == nbridge_id)) {
-                               pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);
-                               pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
-                               ivideo.video_size = (unsigned int)(1 << (pci_data+21));
-                               pdev_valid = 1;
-
-                               reg = SIS_DATA_BUS_64 << 6;
-                               switch (pci_data) {
-                                  case BRI_DRAM_SIZE_2MB:
-                                       reg |= SIS_DRAM_SIZE_2MB;
-                                       break;
-                                  case BRI_DRAM_SIZE_4MB:
-                                       reg |= SIS_DRAM_SIZE_4MB;
-                                       break;
-                                  case BRI_DRAM_SIZE_8MB:
-                                       reg |= SIS_DRAM_SIZE_8MB;
-                                       break;
-                                  case BRI_DRAM_SIZE_16MB:
-                                       reg |= SIS_DRAM_SIZE_16MB;
-                                       break;
-                                  case BRI_DRAM_SIZE_32MB:
-                                       reg |= SIS_DRAM_SIZE_32MB;
-                                       break;
-                                  case BRI_DRAM_SIZE_64MB:
-                                       reg |= SIS_DRAM_SIZE_64MB;
-                                       break;
-                               }
-                               outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
-                               break;
-                       }  
-               }
-       
-               if (!pdev_valid)  return -1;
+       for(i = 0; i < nbridgenum; i++) {
+               if((pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridgeids[nbridgeidx+i], NULL))) break;
        }
-       return 0;
+       return pdev;
 }
 
-#endif  /* CONFIG_FB_SIS_300 */
-
-
-#ifdef CONFIG_FB_SIS_315    /* for SiS 315/550/650/740/330/661/741/760 */
-
-static int sisfb_get_dram_size_315(void)
+static int __devinit sisfb_get_dram_size(struct sis_video_info *ivideo)
 {
-       u8  reg = 0;
-
-       if(ivideo.chip == SIS_550 ||
-          ivideo.chip == SIS_650 ||
-          ivideo.chip == SIS_740) {
-
-                inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
-               reg &= 0x3f;
-               reg++;
-               reg <<= 2;
-               ivideo.video_size = reg << 20;
-               return 0;
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
+       u8 reg;
+#endif
 
-       } else if(ivideo.chip == SIS_661 ||
-                 ivideo.chip == SIS_741 ||
-                 ivideo.chip == SIS_660 ||
-                 ivideo.chip == SIS_760) {
+       ivideo->video_size = 0;
 
+       switch(ivideo->chip) {
+#ifdef CONFIG_FB_SIS_300
+       case SIS_300:
+               inSISIDXREG(SISSR, 0x14, reg);
+               ivideo->video_size = ((reg & 0x3F) + 1) << 20;
+               break;
+       case SIS_540:
+       case SIS_630:
+       case SIS_730:
+               if(!ivideo->nbridge) return -1;
+               pci_read_config_byte(ivideo->nbridge, 0x63, &reg);
+               ivideo->video_size = 1 << (((reg & 0x70) >> 4) + 21);
+               break;
+#endif
+#ifdef CONFIG_FB_SIS_315
+       case SIS_315H:
+       case SIS_315PRO:
+       case SIS_315:
+               inSISIDXREG(SISSR, 0x14, reg);
+               ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
+               switch((reg >> 2) & 0x03) {
+               case 0x01:
+               case 0x03:
+                  ivideo->video_size <<= 1;
+                  break;
+               case 0x02:
+                  ivideo->video_size += (ivideo->video_size/2);
+               }
+               break;
+       case SIS_330:
+               inSISIDXREG(SISSR, 0x14, reg);
+               ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
+               if(reg & 0x0c) ivideo->video_size <<= 1;
+               break;
+       case SIS_550:
+       case SIS_650:
+       case SIS_740:
+               inSISIDXREG(SISSR, 0x14, reg);
+               ivideo->video_size = (((reg & 0x3f) + 1) << 2) << 20;
+               break;
+       case SIS_661:
+       case SIS_741:
+               inSISIDXREG(SISCR, 0x79, reg);
+               ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
+               break;
+       case SIS_660:
+       case SIS_760:
                inSISIDXREG(SISCR, 0x79, reg);
-               reg &= 0xf0;
-               reg >>= 4;
-               ivideo.video_size = (1 << reg) << 20;
-               return 0;
-
-       } else {        /* 315, 330 */
-
-               inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
-               ivideo.video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
-
-               reg &= SIS315_DUAL_CHANNEL_MASK;
-               reg >>= 2;
-
-               if(ivideo.chip == SIS_330) {
-
-                  if(reg) ivideo.video_size <<= 1;
-               
-               } else {
-                  
-                  switch (reg) {
-                     case SIS315_SINGLE_CHANNEL_2_RANK:
-                          ivideo.video_size <<= 1;
-                          break;
-                     case SIS315_DUAL_CHANNEL_1_RANK:
-                          ivideo.video_size <<= 1;
-                          break;
-                     case SIS315_ASYM_DDR:             /* TW: DDR asymetric */
-                          ivideo.video_size += (ivideo.video_size/2);
-                          break;
-                  }
+               reg = (reg & 0xf0) >> 4;
+               if(reg) ivideo->video_size = (1 << reg) << 20;
+               inSISIDXREG(SISCR, 0x78, reg);
+               reg &= 0x30;
+               if(reg) {
+                  if(reg == 0x10) ivideo->video_size += (32 << 20);
+                  else            ivideo->video_size += (64 << 20);
                }
-
-               return 0;
+               break;
+#endif
+       default:
+               return -1;
        }
-       
-       return -1;
-       
+       return 0;
 }
 
-#endif   /* CONFIG_FB_SIS_315 */
+/* -------------- video bridge device detection --------------- */
 
-
-/* -------------- video bridge detection --------------- */
-
-static void sisfb_detect_VB_connect()
+static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
 {
-       u8 sr16, sr17, cr32, temp;
-
-       if(sisvga_engine == SIS_300_VGA) {
-
-               inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17);
-
-               if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
-
-                       /* Old BIOSes store the detected CRT2 type in SR17
-                        * instead of CR32. However, since our detection
-                        * routines store their results to CR32, we now copy
-                        * the remaining bits (for LCD and VGA) to CR32 for
-                        * unified usage.
-                        * SR17[0] CRT1    [1] LCD     [2] TV    [3] VGA2
-                        *     [4] AVIDEO  [5] SVIDEO
-                        */
-
-#if 0
-                       if (sr17 & 0x01) orSISIDXREG(SISCR, 0x32, SIS_CRT1);
-                       else             andSISIDXREG(SISCR, 0x32, ~SIS_CRT1);
-
-                       if (sr17 & 0x02) orSISIDXREG(SISCR, 0x32, SIS_VB_LCD);
-                       else             andSISIDXREG(SISCR, 0x32, ~SIS_VB_LCD);
-
-                       /* no HiVision and no DVI connector here */
-                       andSISIDXREG(SISCR, 0x32, ~0xc0);
-#endif
+       u8 cr32, temp;
 
+#ifdef CONFIG_FB_SIS_300
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
+               inSISIDXREG(SISSR, 0x17, temp);
+               if((temp & 0x0F) && (ivideo->chip != SIS_300)) {
                        /* PAL/NTSC is stored on SR16 on such machines */
-                       if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {
-                               inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_16, sr16);
-                               if (sr16 & 0x20)
-                                       ivideo.vbflags |= TV_PAL;
+                       if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN))) {
+                               inSISIDXREG(SISSR, 0x16, temp);
+                               if(temp & 0x20)
+                                       ivideo->vbflags |= TV_PAL;
                                else
-                                       ivideo.vbflags |= TV_NTSC;
+                                       ivideo->vbflags |= TV_NTSC;
                        }
-
                }
-
        }
+#endif
 
-       inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);
+       inSISIDXREG(SISCR, 0x32, cr32);
 
-       if (cr32 & SIS_CRT1)
-               sisfb_crt1off = 0;
-       else {
-               if (cr32 & 0x5F)
-                       sisfb_crt1off = 1;
-               else
-                       sisfb_crt1off = 0;
+       if(cr32 & SIS_CRT1) {
+               ivideo->sisfb_crt1off = 0;
+       } else {
+               ivideo->sisfb_crt1off = (cr32 & 0xDF) ? 1 : 0;
        }
 
-       ivideo.vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);
+       ivideo->vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);
 
-       if (cr32 & SIS_VB_TV)
-               ivideo.vbflags |= CRT2_TV;
-       if (cr32 & SIS_VB_LCD)
-               ivideo.vbflags |= CRT2_LCD;
-       if (cr32 & SIS_VB_CRT2)
-               ivideo.vbflags |= CRT2_VGA;
+       if(cr32 & SIS_VB_TV)   ivideo->vbflags |= CRT2_TV;
+       if(cr32 & SIS_VB_LCD)  ivideo->vbflags |= CRT2_LCD;
+       if(cr32 & SIS_VB_CRT2) ivideo->vbflags |= CRT2_VGA;
 
-       /* TW: Detect/set TV plug & type */
-       if(sisfb_tvplug != -1)
-               ivideo.vbflags |= sisfb_tvplug;
+       /* Check given parms for hardware compatibility.
+        * (Cannot do this in the search_xx routines since we don't
+        * know what hardware we are running on then)
+        */
 
-       if (cr32 & SIS_VB_SVIDEO)
-               ivideo.vbflags |= TV_SVIDEO;
-       else if (cr32 & SIS_VB_COMPOSITE)
-               ivideo.vbflags |= TV_AVIDEO;
-       else if (cr32 & SIS_VB_SCART)
-               ivideo.vbflags |= TV_SCART;
+       if(ivideo->chip != SIS_550) {
+          ivideo->sisfb_dstn = ivideo->sisfb_fstn = 0;
+       }
 
-       if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {
-               if(sisvga_engine == SIS_300_VGA) {
-                       inSISIDXREG(SISSR, IND_SIS_POWER_ON_TRAP, temp);
-                       if (temp & 0x01)
-                               ivideo.vbflags |= TV_PAL;
-                       else
-                               ivideo.vbflags |= TV_NTSC;
-               } else if((ivideo.chip <= SIS_315PRO) || (ivideo.chip >= SIS_330)) {
+       if(ivideo->sisfb_tvplug != -1) {
+          if( (ivideo->sisvga_engine != SIS_315_VGA) ||
+              (!(ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV))) ) {
+             if(ivideo->sisfb_tvplug & TV_YPBPR) {
+                ivideo->sisfb_tvplug = -1;
+                printk(KERN_ERR "sisfb: YPbPr not supported\n");
+             }
+          }
+       }
+       if(ivideo->sisfb_tvplug != -1) {
+          if( (ivideo->sisvga_engine != SIS_315_VGA) ||
+              (!(ivideo->vbflags & (VB_301|VB_301B|VB_302B))) ) {
+             if(ivideo->sisfb_tvplug & TV_HIVISION) {
+                ivideo->sisfb_tvplug = -1;
+                printk(KERN_ERR "sisfb: HiVision not supported\n");
+             }
+          }
+       }
+       if(ivideo->sisfb_tvstd != -1) {
+          if( (!(ivideo->vbflags & VB_SISBRIDGE)) &&
+              (!((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags & VB_CHRONTEL))) ) {
+             if(ivideo->sisfb_tvstd & (TV_PALN | TV_PALN | TV_NTSCJ)) {
+                ivideo->sisfb_tvstd = -1;
+                printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n");
+             }
+          }
+       }
 
-                       inSISIDXREG(SISSR, 0x38, temp);
-                       if(temp & 0x01)
-                               ivideo.vbflags |= TV_PAL;
-                       else
-                               ivideo.vbflags |= TV_NTSC;
+       /* Detect/set TV plug & type */
+       if(ivideo->sisfb_tvplug != -1) {
+               ivideo->vbflags |= ivideo->sisfb_tvplug;
+       } else {
+               if(cr32 & SIS_VB_YPBPR)          ivideo->vbflags |= (TV_YPBPR|TV_YPBPR525I); /* default: 480i */
+               else if(cr32 & SIS_VB_HIVISION)  ivideo->vbflags |= TV_HIVISION;
+               else if(cr32 & SIS_VB_SCART)     ivideo->vbflags |= TV_SCART;
+               else {
+                       if(cr32 & SIS_VB_SVIDEO)    ivideo->vbflags |= TV_SVIDEO;
+                       if(cr32 & SIS_VB_COMPOSITE) ivideo->vbflags |= TV_AVIDEO;
+               }
+       }
 
+       if(!(ivideo->vbflags & (TV_YPBPR | TV_HIVISION))) {
+           if(ivideo->sisfb_tvstd != -1) {
+              ivideo->vbflags &= ~(TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ);
+              ivideo->vbflags |= ivideo->sisfb_tvstd;
+           }
+           if(ivideo->vbflags & TV_SCART) {
+              ivideo->vbflags &= ~(TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ);
+              ivideo->vbflags |= TV_PAL;
+           }
+           if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ))) {
+               if(ivideo->sisvga_engine == SIS_300_VGA) {
+                       inSISIDXREG(SISSR, 0x38, temp);
+                       if(temp & 0x01) ivideo->vbflags |= TV_PAL;
+                       else            ivideo->vbflags |= TV_NTSC;
+               } else if((ivideo->chip <= SIS_315PRO) || (ivideo->chip >= SIS_330)) {
+                       inSISIDXREG(SISSR, 0x38, temp);
+                       if(temp & 0x01) ivideo->vbflags |= TV_PAL;
+                       else            ivideo->vbflags |= TV_NTSC;
                } else {
-
                        inSISIDXREG(SISCR, 0x79, temp);
-                       if(temp & 0x20)
-                               ivideo.vbflags |= TV_PAL;
-                       else
-                               ivideo.vbflags |= TV_NTSC;
+                       if(temp & 0x20) ivideo->vbflags |= TV_PAL;
+                       else            ivideo->vbflags |= TV_NTSC;
                }
+           }
        }
 
-       /* TW: Copy forceCRT1 option to CRT1off if option is given */
-       if (sisfb_forcecrt1 != -1) {
-               if(sisfb_forcecrt1) sisfb_crt1off = 0;
-               else                sisfb_crt1off = 1;
+       /* Copy forceCRT1 option to CRT1off if option is given */
+       if(ivideo->sisfb_forcecrt1 != -1) {
+          ivideo->sisfb_crt1off = (ivideo->sisfb_forcecrt1) ? 0 : 1;
        }
-
 }
 
-static void sisfb_get_VB_type(void)
+static void __devinit sisfb_get_VB_type(struct sis_video_info *ivideo)
 {
-       u8 vb_chipid;
-       u8 reg;
        char stdstr[]    = "sisfb: Detected";
        char bridgestr[] = "video bridge";
-       char lvdsstr[]   = "LVDS transmitter";
-       char chrstr[]    = "Chrontel TV encoder";
-
-       ivideo.hasVB = HASVB_NONE;
-       sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
-       sishw_ext.Is301BDH = FALSE;
-       sishw_ext.usExternalChip = 0;
+       u8 vb_chipid;
+       u8 reg;
 
        inSISIDXREG(SISPART4, 0x00, vb_chipid);
-       switch (vb_chipid) {
-          case 0x01:
-               ivideo.hasVB = HASVB_301;
+       switch(vb_chipid) {
+       case 0x01:
                inSISIDXREG(SISPART4, 0x01, reg);
                if(reg < 0xb0) {
-                       ivideo.vbflags |= VB_301;
-                       sishw_ext.ujVBChipID = VB_CHIP_301;
+                       ivideo->vbflags |= VB_301;
                        printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
                } else if(reg < 0xc0) {
-                       ivideo.vbflags |= VB_301B;
-                       sishw_ext.ujVBChipID = VB_CHIP_301B;
+                       ivideo->vbflags |= VB_301B;
                        inSISIDXREG(SISPART4,0x23,reg);
                        if(!(reg & 0x02)) {
-                          sishw_ext.Is301BDH = TRUE;
-                          ivideo.vbflags |= VB_30xBDH;
+                          ivideo->vbflags |= VB_30xBDH;
                           printk(KERN_INFO "%s SiS301B-DH %s\n", stdstr, bridgestr);
                        } else {
                           printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
                        }
                } else if(reg < 0xd0) {
-                       ivideo.vbflags |= VB_301C;
-                       sishw_ext.ujVBChipID = VB_CHIP_301C;
+                       ivideo->vbflags |= VB_301C;
                        printk(KERN_INFO "%s SiS301C %s\n", stdstr, bridgestr);
                } else if(reg < 0xe0) {
-                       ivideo.vbflags |= VB_301LV;
-                       sishw_ext.ujVBChipID = VB_CHIP_301LV;
+                       ivideo->vbflags |= VB_301LV;
                        printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
                } else if(reg <= 0xe1) {
                        inSISIDXREG(SISPART4,0x39,reg);
                        if(reg == 0xff) {
-                          ivideo.vbflags |= VB_302LV;
-                          sishw_ext.ujVBChipID = VB_CHIP_302LV;
+                          ivideo->vbflags |= VB_302LV;
                           printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
                        } else {
-                          ivideo.vbflags |= VB_302ELV;
-                          sishw_ext.ujVBChipID = VB_CHIP_302ELV;
+                          ivideo->vbflags |= VB_301C;
+                          printk(KERN_INFO "%s SiS301C(P4) %s\n", stdstr, bridgestr);
+#if 0
+                          ivideo->vbflags |= VB_302ELV;
                           printk(KERN_INFO "%s SiS302ELV %s\n", stdstr, bridgestr);
+#endif
                        }
                }
                break;
-          case 0x02:
-               ivideo.hasVB = HASVB_302;
-               inSISIDXREG(SISPART4, 0x01, reg);
-               if(reg < 0xd0) {
-                       ivideo.vbflags |= VB_302B;
-                       sishw_ext.ujVBChipID = VB_CHIP_302B;
-                       inSISIDXREG(SISPART4,0x23,reg);
-                       if(!(reg & 0x02)) {
-                          sishw_ext.Is301BDH = TRUE;
-                          ivideo.vbflags |= VB_30xBDH;
-                          printk(KERN_INFO "%s SiS302B-DH %s\n", stdstr, bridgestr);
-                       } else {
-                          printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
-                       }
-               } else if(reg < 0xe0) {
-                       ivideo.vbflags |= VB_301LV;
-                       sishw_ext.ujVBChipID = VB_CHIP_301LV;
-                       printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
-               } else if(reg <= 0xe1) {
-                       ivideo.vbflags |= VB_302LV;
-                       sishw_ext.ujVBChipID = VB_CHIP_302LV;
-                       printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
-               }
+       case 0x02:
+               ivideo->vbflags |= VB_302B;
+               printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
                break;
        }
 
-       if((!(ivideo.vbflags & VB_VIDEOBRIDGE)) && (ivideo.chip != SIS_300)) {
-               inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
+       if((!(ivideo->vbflags & VB_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) {
+               inSISIDXREG(SISCR, 0x37, reg);
                reg &= SIS_EXTERNAL_CHIP_MASK;
                reg >>= 1;
-               if(sisvga_engine == SIS_300_VGA) {
-                       switch (reg) {
+               if(ivideo->sisvga_engine == SIS_300_VGA) {
+#ifdef CONFIG_FB_SIS_300
+                       switch(reg) {
                           case SIS_EXTERNAL_CHIP_LVDS:
-                               ivideo.hasVB = HASVB_LVDS;
-                               ivideo.vbflags |= VB_LVDS;
-                               sishw_ext.usExternalChip = 0x01;
-                               printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
+                               ivideo->vbflags |= VB_LVDS;
                                break;
                           case SIS_EXTERNAL_CHIP_TRUMPION:
-                               ivideo.hasVB = HASVB_TRUMPION;
-                               sishw_ext.usExternalChip = 0x02;
-                               printk(KERN_INFO "%s Trumpion LCD scaler\n", stdstr);
+                               ivideo->vbflags |= VB_TRUMPION;
                                break;
                           case SIS_EXTERNAL_CHIP_CHRONTEL:
-                               ivideo.hasVB = HASVB_CHRONTEL;
-                               ivideo.vbflags |= VB_CHRONTEL;
-                               sishw_ext.usExternalChip = 0x04;
-                               printk(KERN_INFO "%s %s\n", stdstr, chrstr);
+                               ivideo->vbflags |= VB_CHRONTEL;
                                break;
                           case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
-                               ivideo.hasVB = HASVB_LVDS_CHRONTEL;
-                               ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
-                               sishw_ext.usExternalChip = 0x05;
-                               printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
+                               ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
                                break;
                        }
-               } else if(ivideo.chip < SIS_661) {
+                       if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 1;
+#endif
+               } else if(ivideo->chip < SIS_661) {
+#ifdef CONFIG_FB_SIS_315
                        switch (reg) {
                           case SIS310_EXTERNAL_CHIP_LVDS:
-                               ivideo.hasVB = HASVB_LVDS;
-                               ivideo.vbflags |= VB_LVDS;
-                               sishw_ext.usExternalChip = 0x01;
-                               printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
+                               ivideo->vbflags |= VB_LVDS;
                                break;
                           case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
-                               ivideo.hasVB = HASVB_LVDS_CHRONTEL;
-                               ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
-                               sishw_ext.usExternalChip = 0x05;
-                               printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
+                               ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
+                               break;
+                       }
+                       if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 2;
+#endif
+               } else if(ivideo->chip >= SIS_661) {
+#ifdef CONFIG_FB_SIS_315
+                       inSISIDXREG(SISCR, 0x38, reg);
+                       reg >>= 5;
+                       switch(reg) {
+                          case 0x02:
+                               ivideo->vbflags |= VB_LVDS;
+                               break;
+                          case 0x03:
+                               ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
+                               break;
+                          case 0x04:
+                               ivideo->vbflags |= (VB_LVDS | VB_CONEXANT);
                                break;
                        }
+                       if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 2;
+#endif
+               }
+               if(ivideo->vbflags & VB_LVDS) {
+                  printk(KERN_INFO "%s LVDS transmitter\n", stdstr);
+               }
+               if(ivideo->vbflags & VB_TRUMPION) {
+                  printk(KERN_INFO "%s Trumpion Zurac LCD scaler\n", stdstr);
+               }
+               if(ivideo->vbflags & VB_CHRONTEL) {
+                  printk(KERN_INFO "%s Chrontel TV encoder\n", stdstr);
+               }
+               if(ivideo->vbflags & VB_CONEXANT) {
+                  printk(KERN_INFO "%s Conexant external device\n", stdstr);
                }
-
        }
 
-       if(ivideo.vbflags & VB_SISBRIDGE) {
-               SiS_Sense30x();
-       } else if(ivideo.vbflags & VB_CHRONTEL) {
-               SiS_SenseCh();
+       if(ivideo->vbflags & VB_SISBRIDGE) {
+               SiS_Sense30x(ivideo);
+       } else if(ivideo->vbflags & VB_CHRONTEL) {
+               SiS_SenseCh(ivideo);
        }
-
 }
 
 /* ------------------ Sensing routines ------------------ */
 
-static BOOLEAN
-sisfb_test_DDC1(void)
+static BOOLEAN __devinit sisfb_test_DDC1(struct sis_video_info *ivideo)
 {
     unsigned short old;
     int count = 48;
 
-    old = SiS_ReadDDC1Bit(&SiS_Pr);
+    old = SiS_ReadDDC1Bit(&ivideo->SiS_Pr);
     do {
-       if(old != SiS_ReadDDC1Bit(&SiS_Pr)) break;
+               if(old != SiS_ReadDDC1Bit(&ivideo->SiS_Pr)) break;
     } while(count--);
     return (count == -1) ? FALSE : TRUE;
 }
 
-static void
-sisfb_sense_crt1(void)
+static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo)
 {
-    unsigned char SR1F, CR63=0, CR17;
-    unsigned short temp = 0xffff;
-    int i;
     BOOLEAN mustwait = FALSE;
+    u8  SR1F, CR17;
+#ifdef CONFIG_FB_SIS_315
+    u8  CR63=0;
+#endif
+    u16 temp = 0xffff;
+    int i;
 
     inSISIDXREG(SISSR,0x1F,SR1F);
     orSISIDXREG(SISSR,0x1F,0x04);
     andSISIDXREG(SISSR,0x1F,0x3F);
     if(SR1F & 0xc0) mustwait = TRUE;
 
-    if(sisvga_engine == SIS_315_VGA) {
-       inSISIDXREG(SISCR,SiS_Pr.SiS_MyCR63,CR63);
+#ifdef CONFIG_FB_SIS_315
+    if(ivideo->sisvga_engine == SIS_315_VGA) {
+       inSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,CR63);
        CR63 &= 0x40;
-       andSISIDXREG(SISCR,SiS_Pr.SiS_MyCR63,0xBF);
+       andSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF);
     }
+#endif
 
     inSISIDXREG(SISCR,0x17,CR17);
     CR17 &= 0x80;
@@ -2822,25 +2655,46 @@ sisfb_sense_crt1(void)
     }
 
     if(mustwait) {
-       for(i=0; i < 10; i++) sisfbwaitretracecrt1();
+       for(i=0; i < 10; i++) sisfbwaitretracecrt1(ivideo);
     }
 
-    i = 3;
-    do {
-       temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine, 0, 0, NULL);
-    } while(((temp == 0) || (temp == 0xffff)) && i--);
+#ifdef CONFIG_FB_SIS_315
+    if(ivideo->chip >= SIS_330) {
+       andSISIDXREG(SISCR,0x32,~0x20);
+       if(ivideo->chip >= SIS_340) {
+          outSISIDXREG(SISCR, 0x57, 0x4a);
+       } else {
+          outSISIDXREG(SISCR, 0x57, 0x5f);
+       }
+       orSISIDXREG(SISCR, 0x53, 0x02);
+       while((inSISREG(SISINPSTAT)) & 0x01)    break;
+       while(!((inSISREG(SISINPSTAT)) & 0x01)) break;
+       if((inSISREG(SISMISCW)) & 0x10) temp = 1;
+       andSISIDXREG(SISCR, 0x53, 0xfd);
+       andSISIDXREG(SISCR, 0x57, 0x00);
+    }
+#endif
+
+    if(temp == 0xffff) {
+       i = 3;
+       do {
+          temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine, 0, 0, NULL);
+       } while(((temp == 0) || (temp == 0xffff)) && i--);
 
-    if((temp == 0) || (temp == 0xffff)) {
-       if(sisfb_test_DDC1()) temp = 1;
+       if((temp == 0) || (temp == 0xffff)) {
+          if(sisfb_test_DDC1(ivideo)) temp = 1;
+       }
     }
 
     if((temp) && (temp != 0xffff)) {
        orSISIDXREG(SISCR,0x32,0x20);
     }
 
-    if(sisvga_engine == SIS_315_VGA) {
-       setSISIDXREG(SISCR,SiS_Pr.SiS_MyCR63,0xBF,CR63);
+#ifdef CONFIG_FB_SIS_315
+    if(ivideo->sisvga_engine == SIS_315_VGA) {
+       setSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF,CR63);
     }
+#endif
 
     setSISIDXREG(SISCR,0x17,0x7F,CR17);
 
@@ -2848,225 +2702,207 @@ sisfb_sense_crt1(void)
 }
 
 /* Determine and detect attached devices on SiS30x */
-static int
-SISDoSense(int tempbl, int tempbh, int tempcl, int tempch)
+static int __devinit SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test)
 {
-    int temp;
-
-    outSISIDXREG(SISPART4,0x11,tempbl);
-    temp = tempbh | tempcl;
-    setSISIDXREG(SISPART4,0x10,0xe0,temp);
-    SiS_DDC2Delay(&SiS_Pr, 0x1000);
-    tempch &= 0x7f;
-    inSISIDXREG(SISPART4,0x03,temp);
-    temp ^= 0x0e;
-    temp &= tempch;
-    return((temp == tempch));
+    int temp, mytest, result, i, j;
+
+    for(j = 0; j < 10; j++) {
+       result = 0;
+       for(i = 0; i < 3; i++) {
+          mytest = test;
+          outSISIDXREG(SISPART4,0x11,(type & 0x00ff));
+          temp = (type >> 8) | (mytest & 0x00ff);
+          setSISIDXREG(SISPART4,0x10,0xe0,temp);
+          SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1500);
+          mytest >>= 8;
+          mytest &= 0x7f;
+          inSISIDXREG(SISPART4,0x03,temp);
+          temp ^= 0x0e;
+          temp &= mytest;
+          if(temp == mytest) result++;
+#if 1
+         outSISIDXREG(SISPART4,0x11,0x00);
+         andSISIDXREG(SISPART4,0x10,0xe0);
+         SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1000);
+#endif
+       }
+       if((result == 0) || (result >= 2)) break;
+    }
+    return(result);
 }
 
-static void
-SiS_Sense30x(void)
+static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
 {
-  u8 backupP4_0d,backupP2_00;
-  u8 svhs_bl, svhs_bh;
-  u8 svhs_cl, svhs_ch;
-  u8 cvbs_bl, cvbs_bh;
-  u8 cvbs_cl, cvbs_ch;
-  u8 vga2_bl, vga2_bh;
-  u8 vga2_cl, vga2_ch;
-  int myflag, result, haveresult, i, j;
-  char stdstr[] = "sisfb: Detected";
-  char tvstr[]  = "TV connected to";
-
-  inSISIDXREG(SISPART4,0x0d,backupP4_0d);
-  if(!(ivideo.vbflags & (VB_301C|VB_302ELV))) {
-     outSISIDXREG(SISPART4,0x0d,(backupP4_0d | 0x04));
-  }
-
-  inSISIDXREG(SISPART2,0x00,backupP2_00);
-  outSISIDXREG(SISPART2,0x00,(backupP2_00 | 0x1c));
-
-  if(sisvga_engine == SIS_300_VGA) {
-
-       if(ivideo.vbflags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV)) {
-               vga2_bh = 0x01; vga2_bl = 0x90;
-               svhs_bh = 0x01; svhs_bl = 0x6b;
-               cvbs_bh = 0x01; cvbs_bl = 0x74;
-       } else {
-               vga2_bh = 0x00; vga2_bl = 0xd1;
-               svhs_bh = 0x00; svhs_bl = 0xb9;
-               cvbs_bh = 0x00; cvbs_bl = 0xb3;
-       }
-       inSISIDXREG(SISPART4,0x01,myflag);
-       if(myflag & 0x04) {
-          vga2_bh = 0x00; vga2_bl = 0xfd;
-          svhs_bh = 0x00; svhs_bl = 0xdd;
-          cvbs_bh = 0x00; cvbs_bl = 0xee;
-       }
-       vga2_ch = 0x0e; vga2_cl = 0x08;
-       svhs_ch = 0x04; svhs_cl = 0x04;
-       cvbs_ch = 0x08; cvbs_cl = 0x04;
-       if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
-               vga2_bh = 0x00; vga2_bl = 0x00;
-               vga2_ch = 0x00; vga2_cl = 0x00;
-        }
-       if(ivideo.chip == SIS_300) {
-          inSISIDXREG(SISSR,0x3b,myflag);
-          if(!(myflag & 0x01)) {
-               vga2_bh = 0x00; vga2_bl = 0x00;
-               vga2_ch = 0x00; vga2_cl = 0x00;
-          }
-       }
+    u8  backupP4_0d,backupP2_00,backupP2_4d,backupSR_1e,biosflag=0;
+    u16 svhs=0, svhs_c=0;
+    u16 cvbs=0, cvbs_c=0;
+    u16 vga2=0, vga2_c=0;
+    int myflag, result;
+    char stdstr[] = "sisfb: Detected";
+    char tvstr[]  = "TV connected to";
+
+    if(ivideo->vbflags & VB_301) {
+       svhs = 0x00b9; cvbs = 0x00b3; vga2 = 0x00d1;
+       inSISIDXREG(SISPART4,0x01,myflag);
+       if(myflag & 0x04) {
+         svhs = 0x00dd; cvbs = 0x00ee; vga2 = 0x00fd;
+       }
+    } else if(ivideo->vbflags & (VB_301B | VB_302B)) {
+       svhs = 0x016b; cvbs = 0x0174; vga2 = 0x0190;
+    } else if(ivideo->vbflags & (VB_301LV | VB_302LV)) {
+       svhs = 0x0200; cvbs = 0x0100;
+    } else if(ivideo->vbflags & (VB_301C | VB_302ELV)) {
+       svhs = 0x016b; cvbs = 0x0110; vga2 = 0x0190;
+    } else return;
+
+    vga2_c = 0x0e08; svhs_c = 0x0404; cvbs_c = 0x0804;
+    if(ivideo->vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
+       svhs_c = 0x0408; cvbs_c = 0x0808;
+    }
+    biosflag = 2;
 
-  } else {
-
-       if(ivideo.vbflags & (VB_301B|VB_302B)) {
-               vga2_bh = 0x01; vga2_bl = 0x90;
-               svhs_bh = 0x01; svhs_bl = 0x6b;
-               cvbs_bh = 0x01; cvbs_bl = 0x74;
-       } else if(ivideo.vbflags & (VB_301C|VB_302ELV)) {
-               vga2_bh = 0x01; vga2_bl = 0x90;
-               svhs_bh = 0x01; svhs_bl = 0x6b;
-               cvbs_bh = 0x01; cvbs_bl = 0x10;
-       } else if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
-               vga2_bh = 0x00; vga2_bl = 0x00;
-               svhs_bh = 0x02; svhs_bl = 0x00;
-               cvbs_bh = 0x01; cvbs_bl = 0x00;
-       } else {
-               vga2_bh = 0x00; vga2_bl = 0xd1;
-               svhs_bh = 0x00; svhs_bl = 0xb9;
-               cvbs_bh = 0x00; cvbs_bl = 0xb3;
-               inSISIDXREG(SISPART4,0x01,myflag);
-               if(myflag & 0x04) {
-                  vga2_bh = 0x00; vga2_bl = 0xfd;
-                  svhs_bh = 0x00; svhs_bl = 0xdd;
-                  cvbs_bh = 0x00; cvbs_bl = 0xee;
-               }
-       }
+    if(ivideo->chip == SIS_300) {
+       inSISIDXREG(SISSR,0x3b,myflag);
+       if(!(myflag & 0x01)) vga2 = vga2_c = 0;
+    }
 
-       if(ivideo.vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
-          vga2_bh = 0x00; vga2_bl = 0x00;
-          vga2_ch = 0x00; vga2_cl = 0x00;
-          svhs_ch = 0x04; svhs_cl = 0x08;
-          cvbs_ch = 0x08; cvbs_cl = 0x08;
-       } else {
-          vga2_ch = 0x0e; vga2_cl = 0x08;
-          svhs_ch = 0x04; svhs_cl = 0x04;
-          cvbs_ch = 0x08; cvbs_cl = 0x04;
-       }
-    } 
-
-    if(vga2_ch || vga2_cl || vga2_bh || vga2_bl) {
-       haveresult = 0;
-       for(j = 0; j < 10; j++) {
-          result = 0;
-          for(i = 0; i < 3; i++) {
-             if(SISDoSense(vga2_bl, vga2_bh, vga2_cl, vga2_ch))
-               result++;
-          }
-         if((result == 0) || (result >= 2)) break;
-       }
-       if(result) {
-          printk(KERN_INFO "%s secondary VGA connection\n", stdstr);
-         orSISIDXREG(SISCR, 0x32, 0x10);
-       } else {
-         andSISIDXREG(SISCR, 0x32, ~0x10);
+    inSISIDXREG(SISSR,0x1e,backupSR_1e);
+    orSISIDXREG(SISSR,0x1e,0x20);
+
+    inSISIDXREG(SISPART4,0x0d,backupP4_0d);
+    if(ivideo->vbflags & VB_301C) {
+       setSISIDXREG(SISPART4,0x0d,~0x07,0x01);
+    } else {
+       orSISIDXREG(SISPART4,0x0d,0x04);
+    }
+    SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000);
+
+    inSISIDXREG(SISPART2,0x00,backupP2_00);
+    outSISIDXREG(SISPART2,0x00,((backupP2_00 | 0x1c) & 0xfc));
+
+    inSISIDXREG(SISPART2,0x4d,backupP2_4d);
+    if(ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV)) {
+       outSISIDXREG(SISPART2,0x4d,(backupP2_4d & ~0x10));
+    }
+
+    if(!(ivideo->vbflags & VB_301C)) {
+       SISDoSense(ivideo, 0, 0);
+    }
+
+    andSISIDXREG(SISCR, 0x32, ~0x14);
+
+    if(vga2_c || vga2) {
+       if(SISDoSense(ivideo, vga2, vga2_c)) {
+          if(biosflag & 0x01) {
+            printk(KERN_INFO "%s %s SCART output\n", stdstr, tvstr);
+            orSISIDXREG(SISCR, 0x32, 0x04);
+         } else {
+            printk(KERN_INFO "%s secondary VGA connection\n", stdstr);
+            orSISIDXREG(SISCR, 0x32, 0x10);
+         }
        }
     }
 
-    if(ivideo.vbflags & (VB_301C|VB_302ELV)) {
+    andSISIDXREG(SISCR, 0x32, 0x3f);
+
+    if(ivideo->vbflags & VB_301C) {
        orSISIDXREG(SISPART4,0x0d,0x04);
     }
 
-    haveresult = 0;
-    for(j = 0; j < 10; j++) {
-       result = 0;
-       for(i = 0; i < 3; i++) {
-          if(SISDoSense(svhs_bl, svhs_bh, svhs_cl, svhs_ch))
-               result++;
+    if((ivideo->sisvga_engine == SIS_315_VGA) &&
+       (ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV))) {
+       outSISIDXREG(SISPART2,0x4d,(backupP2_4d | 0x10));
+       SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000);
+       if((result = SISDoSense(ivideo, svhs, 0x0604))) {
+          if((result = SISDoSense(ivideo, cvbs, 0x0804))) {
+            printk(KERN_INFO "%s %s YPbPr component output\n", stdstr, tvstr);
+            orSISIDXREG(SISCR,0x32,0x80);
+         }
        }
-       if((result == 0) || (result >= 2)) break;
-    }
-    if(result) {
-        printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr);
-       ivideo.vbflags |= TV_SVIDEO;
-       orSISIDXREG(SISCR, 0x32, 0x02);
-       andSISIDXREG(SISCR, 0x32, ~0x05);
+       outSISIDXREG(SISPART2,0x4d,backupP2_4d);
     }
 
-    if(!result) {
+    andSISIDXREG(SISCR, 0x32, ~0x03);
 
-       haveresult = 0;
-               for(j = 0; j < 10; j++) {
-           result = 0;
-           for(i = 0; i < 3; i++) {
-              if(SISDoSense(cvbs_bl, cvbs_bh, cvbs_cl, cvbs_ch))
-               result++;
-           }
-           if((result == 0) || (result >= 2)) break;
-        }
-       if(result) {
-           printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr);
-           ivideo.vbflags |= TV_AVIDEO;
-           orSISIDXREG(SISCR, 0x32, 0x01);
-           andSISIDXREG(SISCR, 0x32, ~0x06);
-       } else {
-           andSISIDXREG(SISCR, 0x32, ~0x07);
-       }
+    if(!(ivideo->vbflags & TV_YPBPR)) {
+       if((result = SISDoSense(ivideo, svhs, svhs_c))) {
+          printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr);
+          orSISIDXREG(SISCR, 0x32, 0x02);
+       }
+       if((biosflag & 0x02) || (!result)) {
+          if(SISDoSense(ivideo, cvbs, cvbs_c)) {
+            printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr);
+            orSISIDXREG(SISCR, 0x32, 0x01);
+          }
+       }
     }
-    SISDoSense(0, 0, 0, 0);
+
+    SISDoSense(ivideo, 0, 0);
 
     outSISIDXREG(SISPART2,0x00,backupP2_00);
     outSISIDXREG(SISPART4,0x0d,backupP4_0d);
+    outSISIDXREG(SISSR,0x1e,backupSR_1e);
+
+    if(ivideo->vbflags & VB_301C) {
+       inSISIDXREG(SISPART2,0x00,biosflag);
+       if(biosflag & 0x20) {
+          for(myflag = 2; myflag > 0; myflag--) {
+            biosflag ^= 0x20;
+            outSISIDXREG(SISPART2,0x00,biosflag);
+         }
+       }
+    }
+
+    outSISIDXREG(SISPART2,0x00,backupP2_00);
 }
 
 /* Determine and detect attached TV's on Chrontel */
-static void
-SiS_SenseCh(void)
+static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
 {
-
-   u8 temp1, temp2;
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
+    u8 temp1, temp2;
+    char stdstr[] = "sisfb: Chrontel: Detected TV connected to";
+#endif
 #ifdef CONFIG_FB_SIS_300
-   unsigned char test[3];
-   int i;
+    unsigned char test[3];
+    int i;
 #endif
-   char stdstr[] = "sisfb: Chrontel: Detected TV connected to";
 
-   if(ivideo.chip < SIS_315H) {
+    if(ivideo->chip < SIS_315H) {
 
 #ifdef CONFIG_FB_SIS_300
-       SiS_Pr.SiS_IF_DEF_CH70xx = 1;           /* Chrontel 700x */
-       SiS_SetChrontelGPIO(&SiS_Pr, 0x9c);     /* Set general purpose IO for Chrontel communication */
-       SiS_DDC2Delay(&SiS_Pr, 1000);
-       temp1 = SiS_GetCH700x(&SiS_Pr, 0x25);
+       ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 1;           /* Chrontel 700x */
+       SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x9c);     /* Set general purpose IO for Chrontel communication */
+       SiS_DDC2Delay(&ivideo->SiS_Pr, 1000);
+       temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25);
        /* See Chrontel TB31 for explanation */
-       temp2 = SiS_GetCH700x(&SiS_Pr, 0x0e);
+       temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
        if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
-         SiS_SetCH700x(&SiS_Pr, 0x0b0e);
-         SiS_DDC2Delay(&SiS_Pr, 300);
+         SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b0e);
+         SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
        }
-       temp2 = SiS_GetCH700x(&SiS_Pr, 0x25);
+       temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25);
        if(temp2 != temp1) temp1 = temp2;
 
        if((temp1 >= 0x22) && (temp1 <= 0x50)) {
           /* Read power status */
-          temp1 = SiS_GetCH700x(&SiS_Pr, 0x0e);
+          temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
           if((temp1 & 0x03) != 0x03) {
                /* Power all outputs */
-               SiS_SetCH700x(&SiS_Pr, 0x0B0E);
-               SiS_DDC2Delay(&SiS_Pr, 300);
+               SiS_SetCH700x(&ivideo->SiS_Pr, 0x0B0E);
+               SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
           }
           /* Sense connected TV devices */
           for(i = 0; i < 3; i++) {
-              SiS_SetCH700x(&SiS_Pr, 0x0110);
-              SiS_DDC2Delay(&SiS_Pr, 0x96);
-              SiS_SetCH700x(&SiS_Pr, 0x0010);
-              SiS_DDC2Delay(&SiS_Pr, 0x96);
-              temp1 = SiS_GetCH700x(&SiS_Pr, 0x10);
+              SiS_SetCH700x(&ivideo->SiS_Pr, 0x0110);
+              SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
+              SiS_SetCH700x(&ivideo->SiS_Pr, 0x0010);
+              SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
+              temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x10);
               if(!(temp1 & 0x08))       test[i] = 0x02;
               else if(!(temp1 & 0x02))  test[i] = 0x01;
               else                      test[i] = 0;
-              SiS_DDC2Delay(&SiS_Pr, 0x96);
+              SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
           }
 
           if(test[0] == test[1])      temp1 = test[0];
@@ -3079,42 +2915,42 @@ SiS_SenseCh(void)
           }
           if(temp1 == 0x02) {
                printk(KERN_INFO "%s SVIDEO output\n", stdstr);
-               ivideo.vbflags |= TV_SVIDEO;
+               ivideo->vbflags |= TV_SVIDEO;
                orSISIDXREG(SISCR, 0x32, 0x02);
                andSISIDXREG(SISCR, 0x32, ~0x05);
           } else if (temp1 == 0x01) {
                printk(KERN_INFO "%s CVBS output\n", stdstr);
-               ivideo.vbflags |= TV_AVIDEO;
+               ivideo->vbflags |= TV_AVIDEO;
                orSISIDXREG(SISCR, 0x32, 0x01);
                andSISIDXREG(SISCR, 0x32, ~0x06);
           } else {
-               SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
+               SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x010E,0xF8);
                andSISIDXREG(SISCR, 0x32, ~0x07);
           }
        } else if(temp1 == 0) {
-         SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
+         SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x010E,0xF8);
          andSISIDXREG(SISCR, 0x32, ~0x07);
        }
        /* Set general purpose IO for Chrontel communication */
-       SiS_SetChrontelGPIO(&SiS_Pr, 0x00);
+       SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x00);
 #endif
 
-   } else {
+    } else {
 
 #ifdef CONFIG_FB_SIS_315
-       SiS_Pr.SiS_IF_DEF_CH70xx = 2;           /* Chrontel 7019 */
-        temp1 = SiS_GetCH701x(&SiS_Pr, 0x49);
-       SiS_SetCH701x(&SiS_Pr, 0x2049);
-       SiS_DDC2Delay(&SiS_Pr, 0x96);
-       temp2 = SiS_GetCH701x(&SiS_Pr, 0x20);
+       ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 2;           /* Chrontel 7019 */
+        temp1 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x49);
+       SiS_SetCH701x(&ivideo->SiS_Pr, 0x2049);
+       SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
+       temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
        temp2 |= 0x01;
-       SiS_SetCH701x(&SiS_Pr, (temp2 << 8) | 0x20);
-       SiS_DDC2Delay(&SiS_Pr, 0x96);
+       SiS_SetCH701x(&ivideo->SiS_Pr, (temp2 << 8) | 0x20);
+       SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
        temp2 ^= 0x01;
-       SiS_SetCH701x(&SiS_Pr, (temp2 << 8) | 0x20);
-       SiS_DDC2Delay(&SiS_Pr, 0x96);
-       temp2 = SiS_GetCH701x(&SiS_Pr, 0x20);
-       SiS_SetCH701x(&SiS_Pr, (temp1 << 8) | 0x49);
+       SiS_SetCH701x(&ivideo->SiS_Pr, (temp2 << 8) | 0x20);
+       SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
+       temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
+       SiS_SetCH701x(&ivideo->SiS_Pr, (temp1 << 8) | 0x49);
         temp1 = 0;
        if(temp2 & 0x02) temp1 |= 0x01;
        if(temp2 & 0x10) temp1 |= 0x01;
@@ -3123,13 +2959,13 @@ SiS_SenseCh(void)
        switch(temp1) {
        case 0x01:
             printk(KERN_INFO "%s CVBS output\n", stdstr);
-            ivideo.vbflags |= TV_AVIDEO;
+            ivideo->vbflags |= TV_AVIDEO;
             orSISIDXREG(SISCR, 0x32, 0x01);
             andSISIDXREG(SISCR, 0x32, ~0x06);
              break;
        case 0x02:
             printk(KERN_INFO "%s SVIDEO output\n", stdstr);
-            ivideo.vbflags |= TV_SVIDEO;
+            ivideo->vbflags |= TV_SVIDEO;
             orSISIDXREG(SISCR, 0x32, 0x02);
             andSISIDXREG(SISCR, 0x32, ~0x05);
              break;
@@ -3142,336 +2978,171 @@ SiS_SenseCh(void)
             andSISIDXREG(SISCR, 0x32, ~0x07);
        }
 #endif
-
-   }
+    }
 }
 
-
 /* ------------------------ Heap routines -------------------------- */
 
-static int sisfb_heap_init(void)
+static u32 __devinit
+sisfb_getheapstart(struct sis_video_info *ivideo)
 {
-       SIS_OH *poh;
-       u8 temp=0;
-#ifdef CONFIG_FB_SIS_315
-       int            agp_enabled = 1;
-       u32            agp_size;
-       unsigned long *cmdq_baseport = 0;
-       unsigned long *read_port = 0;
-       unsigned long *write_port = 0;
-       SIS_CMDTYPE    cmd_type;
-#ifndef AGPOFF
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-       struct agp_kern_info  *agp_info;
-       struct agp_memory     *agp;
-#else
-       agp_kern_info  *agp_info;
-       agp_memory     *agp;
-#endif
-       u32            agp_phys;
-#endif
-#endif
-/*     The heap start is either set manually using the "mem" parameter, or
- *     defaults as follows:
- *     -) If more than 16MB videoRAM available, let our heap start at 12MB.
- *     -) If more than  8MB videoRAM available, let our heap start at  8MB.
- *     -) If 4MB or less is available, let it start at 4MB.
- *     This is for avoiding a clash with X driver which uses the beginning
- *     of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem
- *     in XF86Config-4.
- *     The heap start can also be specified by parameter "mem" when starting the sisfb
- *     driver. sisfb mem=1024 lets heap starts at 1MB, etc.
- *
- *     On the 315 and Xabre series, the default is a 1MB heap since DRI is not
- *     supported there.
- */
-     if ((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
-        if(sisvga_engine == SIS_300_VGA) {
-           if (ivideo.video_size > 0x1000000) {
-               ivideo.heapstart = 0xc00000;
-          } else if (ivideo.video_size > 0x800000) {
-               ivideo.heapstart = 0x800000;
+       u32 ret = ivideo->sisfb_parm_mem * 1024;
+       u32 max = ivideo->video_size - ivideo->hwcursor_size;
+       u32 def;
+
+       /* Calculate heap start = end of memory for console
+        *
+        * CCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDHHHHQQQQQQQQQQ
+        * C = console, D = heap, H = HWCursor, Q = cmd-queue
+        *
+        * Basically given by "mem" parameter
+        *
+        * maximum = videosize - cmd_queue - hwcursor
+        *           (results in a heap of size 0)
+        * default = SiS 300: depends on videosize
+        *           SiS 315/330: 32k below max
+        */
+
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
+          max -= TURBO_QUEUE_AREA_SIZE;
+          if(ivideo->video_size > 0x1000000) {
+             def = 0xc00000;
+          } else if(ivideo->video_size > 0x800000) {
+             def = 0x800000;
           } else {
-               ivideo.heapstart = 0x400000;
+             def = 0x400000;
           }
        } else {
-          ivideo.heapstart = ivideo.video_size - 0x100000;
+          max -= COMMAND_QUEUE_AREA_SIZE;
+          def = max - 0x8000;
        }
-     } else {
-           ivideo.heapstart = sisfb_mem * 1024;
-     }
-     sisfb_heap_start = (unsigned long) (ivideo.video_vbase + ivideo.heapstart);
-     printk(KERN_INFO "sisfb: Memory heap starting at %dK\n",
-                                       (int)(ivideo.heapstart / 1024));
 
-     sisfb_heap_end = (unsigned long) ivideo.video_vbase + ivideo.video_size;
-     sisfb_heap_size = sisfb_heap_end - sisfb_heap_start;
+        if((!ret) || (ret > max) || (ivideo->cardnumber != 0)) {
+          ret = def;
+        }
 
-#ifdef CONFIG_FB_SIS_315
-     if (sisvga_engine == SIS_315_VGA) {
-        /* Now initialize the 315/330 series' command queue mode.
-        * On 315, there are three queue modes available which
-        * are chosen by setting bits 7:5 in SR26:
-        * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
-        *    track of the queue, the FIFO, command parsing and so
-        *    on. This is the one comparable to the 300 series.
-        * 2. VRAM queue mode (bit 6, 0x40). In this case, one will
-        *    have to do queue management himself. Register 0x85c4 will
-        *    hold the location of the next free queue slot, 0x85c8
-        *    is the "queue read pointer" whose way of working is
-        *    unknown to me. Anyway, this mode would require a
-        *    translation of the MMIO commands to some kind of
-        *    accelerator assembly and writing these commands
-        *    to the memory location pointed to by 0x85c4.
-        *    We will not use this, as nobody knows how this
-        *    "assembly" works, and as it would require a complete
-        *    re-write of the accelerator code.
-        * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
-        *    queue in AGP memory space.
-        *
-        * SR26 bit 4 is called "Bypass H/W queue".
-        * SR26 bit 1 is called "Enable Command Queue Auto Correction"
-        * SR26 bit 0 resets the queue
-        * Size of queue memory is encoded in bits 3:2 like this:
-        *    00  (0x00)  512K
-        *    01  (0x04)  1M
-        *    10  (0x08)  2M
-        *    11  (0x0C)  4M
-        * The queue location is to be written to 0x85C0.
-        *
-         */
-       cmdq_baseport = (unsigned long *)(ivideo.mmio_vbase + MMIO_QUEUE_PHYBASE);
-       write_port    = (unsigned long *)(ivideo.mmio_vbase + MMIO_QUEUE_WRITEPORT);
-       read_port     = (unsigned long *)(ivideo.mmio_vbase + MMIO_QUEUE_READPORT);
+       return ret;
+}
 
-       DPRINTK("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport, read_port, write_port);
+static int __devinit
+sisfb_heap_init(struct sis_video_info *ivideo)
+{
+     SIS_OH *poh;
 
-       agp_size  = COMMAND_QUEUE_AREA_SIZE;
+     ivideo->heapstart = ivideo->sisfb_mem = sisfb_getheapstart(ivideo);
 
-#ifndef AGPOFF
-       if (sisfb_queuemode == AGP_CMD_QUEUE) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-               agp_info = vmalloc(sizeof(*agp_info));
-               memset((void*)agp_info, 0x00, sizeof(*agp_info));
-#else
-               agp_info = vmalloc(sizeof(agp_kern_info));
-               memset((void*)agp_info, 0x00, sizeof(agp_kern_info));
-#endif
-               agp_copy_info(agp_info);
+     ivideo->sisfb_heap_start = ivideo->video_vbase + ivideo->heapstart;
+     ivideo->sisfb_heap_end   = ivideo->video_vbase + ivideo->video_size;
 
-               agp_backend_acquire();
+     /* Initialize command queue (We use MMIO only) */
 
-               agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE/PAGE_SIZE,
-                                         AGP_NORMAL_MEMORY);
-               if (agp == NULL) {
-                       DPRINTK("sisfb: Allocating AGP buffer failed.\n");
-                       agp_enabled = 0;
-               } else {
-                       if (agp_bind_memory(agp, agp->pg_start) != 0) {
-                               DPRINTK("sisfb: AGP: Failed to bind memory\n");
-                               /* TODO: Free AGP memory here */
-                               agp_enabled = 0;
-                       } else {
-                               agp_enable(0);
-                       }
-               }
-       }
-#else
-       agp_enabled = 0;
-#endif
+#ifdef CONFIG_FB_SIS_315
+     if(ivideo->sisvga_engine == SIS_315_VGA) {
+        u32 tempq = 0;
+       u8  temp = 0;
 
-       /* Now select the queue mode */
+        ivideo->sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
 
-       if ((agp_enabled) && (sisfb_queuemode == AGP_CMD_QUEUE)) {
-               cmd_type = AGP_CMD_QUEUE;
-               printk(KERN_INFO "sisfb: Using AGP queue mode\n");
-/*     } else if (sisfb_heap_size >= COMMAND_QUEUE_AREA_SIZE)  */
-        } else if (sisfb_queuemode == VM_CMD_QUEUE) {
-               cmd_type = VM_CMD_QUEUE;
-               printk(KERN_INFO "sisfb: Using VRAM queue mode\n");
-       } else {
-               printk(KERN_INFO "sisfb: Using MMIO queue mode\n");
-               cmd_type = MMIO_CMD;
-       }
+       outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
+       outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
 
-       switch (agp_size) {
-          case 0x80000:
-               temp = SIS_CMD_QUEUE_SIZE_512k;
-               break;
-          case 0x100000:
-               temp = SIS_CMD_QUEUE_SIZE_1M;
-               break;
-          case 0x200000:
-               temp = SIS_CMD_QUEUE_SIZE_2M;
-               break;
-          case 0x400000:
-               temp = SIS_CMD_QUEUE_SIZE_4M;
-               break;
-       }
+       tempq = MMIO_IN32(ivideo->mmio_vbase, MMIO_QUEUE_READPORT);
+       MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq);
 
-       switch (cmd_type) {
-          case AGP_CMD_QUEUE:
-#ifndef AGPOFF
-               DPRINTK("sisfb: AGP buffer base = 0x%lx, offset = 0x%x, size = %dK\n",
-                       agp_info->aper_base, agp->physical, agp_size/1024);
+       temp = SIS_CMD_QUEUE_SIZE_512k;
+       temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
+       outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
 
-               agp_phys = agp_info->aper_base + agp->physical;
+       tempq = (u32)(ivideo->video_size - COMMAND_QUEUE_AREA_SIZE);
+       MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq);
 
-               outSISIDXREG(SISCR,  IND_SIS_AGP_IO_PAD, 0);
-               outSISIDXREG(SISCR,  IND_SIS_AGP_IO_PAD, SIS_AGP_2X);
+       ivideo->caps |= MMIO_CMD_QUEUE_CAP;
+     }
+#endif
 
-                outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
+#ifdef CONFIG_FB_SIS_300
+     if(ivideo->sisvga_engine == SIS_300_VGA) {
+       unsigned long tqueue_pos;
+       u8 tq_state;
 
-               outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
+       ivideo->sisfb_heap_end -= TURBO_QUEUE_AREA_SIZE;
 
-               *write_port = *read_port;
+       tqueue_pos = (ivideo->video_size - TURBO_QUEUE_AREA_SIZE) / (64 * 1024);
 
-               temp |= SIS_AGP_CMDQUEUE_ENABLE;
-               outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
+       inSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
+       tq_state |= 0xf0;
+       tq_state &= 0xfc;
+       tq_state |= (u8)(tqueue_pos >> 8);
+       outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
 
-               *cmdq_baseport = agp_phys;
+       outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff));
 
-               sisfb_caps |= AGP_CMD_QUEUE_CAP;
+       ivideo->caps |= TURBO_QUEUE_CAP;
+     }
 #endif
-               break;
 
-          case VM_CMD_QUEUE:
-               sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
-               sisfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
+     /* Reserve memory for the HWCursor */
+     ivideo->sisfb_heap_end -= ivideo->hwcursor_size;
+     ivideo->hwcursor_vbase = ivideo->sisfb_heap_end;
+     ivideo->caps |= HW_CURSOR_CAP;
 
-               outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
+     ivideo->sisfb_heap_size = ivideo->sisfb_heap_end - ivideo->sisfb_heap_start;
 
-               outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
+     if(ivideo->cardnumber == 0) {
 
-               *write_port = *read_port;
+       printk(KERN_INFO "sisfb: Memory heap starting at %dK, size %dK\n",
+               (int)(ivideo->heapstart / 1024), (int)(ivideo->sisfb_heap_size / 1024));
 
-               temp |= SIS_VRAM_CMDQUEUE_ENABLE;
-               outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
+       sisfb_heap.vinfo = ivideo;
 
-               *cmdq_baseport = ivideo.video_size - COMMAND_QUEUE_AREA_SIZE;
+       sisfb_heap.poha_chain = NULL;
+       sisfb_heap.poh_freelist = NULL;
 
-               sisfb_caps |= VM_CMD_QUEUE_CAP;
+       poh = sisfb_poh_new_node();
+       if(poh == NULL) return 1;
 
-               DPRINTK("sisfb: VM Cmd Queue offset = 0x%lx, size is %dK\n",
-                       *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
-               break;
+       poh->poh_next = &sisfb_heap.oh_free;
+       poh->poh_prev = &sisfb_heap.oh_free;
+       poh->size = ivideo->sisfb_heap_size;
+       poh->offset = ivideo->heapstart;
 
-          default:  /* MMIO */
-               sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
-               sisfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
+       sisfb_heap.oh_free.poh_next = poh;
+       sisfb_heap.oh_free.poh_prev = poh;
+       sisfb_heap.oh_free.size = 0;
+       sisfb_heap.max_freesize = poh->size;
 
-               outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
-               outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
+       sisfb_heap.oh_used.poh_next = &sisfb_heap.oh_used;
+       sisfb_heap.oh_used.poh_prev = &sisfb_heap.oh_used;
+       sisfb_heap.oh_used.size = SENTINEL;
 
-               *write_port = *read_port;
+     } else {
 
-               /* Set Auto_Correction bit */
-               temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
-               outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
+        printk(KERN_INFO "Skipped heap initialization for secondary cards\n");
 
-               *cmdq_baseport = ivideo.video_size - COMMAND_QUEUE_AREA_SIZE;
+     }
 
-               sisfb_caps |= MMIO_CMD_QUEUE_CAP;
+     return 0;
+}
 
-               DPRINTK("sisfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n",
-                       *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
-               break;
-       }
-     } /* sisvga_engine = 315 */
-#endif
-
-#ifdef CONFIG_FB_SIS_300
-     if (sisvga_engine == SIS_300_VGA) {
-           /* Now initialize TurboQueue. TB is always located at the very
-            * top of the video RAM. */
-           if (sisfb_heap_size >= TURBO_QUEUE_AREA_SIZE) {
-               unsigned int  tqueue_pos;
-               u8 tq_state;
-
-               tqueue_pos = (ivideo.video_size -
-                      TURBO_QUEUE_AREA_SIZE) / (64 * 1024);
-
-               temp = (u8) (tqueue_pos & 0xff);
-
-               inSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
-               tq_state |= 0xf0;
-               tq_state &= 0xfc;
-               tq_state |= (u8) (tqueue_pos >> 8);
-               outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
-
-               outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_ADR, temp);
-
-               sisfb_caps |= TURBO_QUEUE_CAP;
-
-               sisfb_heap_end -= TURBO_QUEUE_AREA_SIZE;
-               sisfb_heap_size -= TURBO_QUEUE_AREA_SIZE;
-               DPRINTK("sisfb: TurboQueue start at 0x%lx, size is %dK\n",
-                       sisfb_heap_end, TURBO_QUEUE_AREA_SIZE/1024);
-           }
-     }
-#endif
-     /* Now reserve memory for the HWCursor. It is always located at the very
-        top of the videoRAM, right below the TB memory area (if used). */
-     if (sisfb_heap_size >= sisfb_hwcursor_size) {
-               sisfb_heap_end -= sisfb_hwcursor_size;
-               sisfb_heap_size -= sisfb_hwcursor_size;
-               sisfb_hwcursor_vbase = sisfb_heap_end;
-
-               sisfb_caps |= HW_CURSOR_CAP;
-
-               DPRINTK("sisfb: Hardware Cursor start at 0x%lx, size is %dK\n",
-                       sisfb_heap_end, sisfb_hwcursor_size/1024);
-     }
-
-     sisfb_heap.poha_chain = NULL;
-     sisfb_heap.poh_freelist = NULL;
-
-     poh = sisfb_poh_new_node();
-
-     if(poh == NULL)  return 1;
-       
-     poh->poh_next = &sisfb_heap.oh_free;
-     poh->poh_prev = &sisfb_heap.oh_free;
-     poh->size = sisfb_heap_end - sisfb_heap_start + 1;
-     poh->offset = sisfb_heap_start - (unsigned long) ivideo.video_vbase;
-
-     DPRINTK("sisfb: Heap start:0x%p, end:0x%p, len=%dk\n",
-               (char *) sisfb_heap_start, (char *) sisfb_heap_end,
-               (unsigned int) poh->size / 1024);
-
-     DPRINTK("sisfb: First Node offset:0x%x, size:%dk\n",
-               (unsigned int) poh->offset, (unsigned int) poh->size / 1024);
-
-     sisfb_heap.oh_free.poh_next = poh;
-     sisfb_heap.oh_free.poh_prev = poh;
-     sisfb_heap.oh_free.size = 0;
-     sisfb_heap.max_freesize = poh->size;
-
-     sisfb_heap.oh_used.poh_next = &sisfb_heap.oh_used;
-     sisfb_heap.oh_used.poh_prev = &sisfb_heap.oh_used;
-     sisfb_heap.oh_used.size = SENTINEL;
-
-     return 0;
-}
-
-static SIS_OH *sisfb_poh_new_node(void)
+static SIS_OH *
+sisfb_poh_new_node(void)
 {
        int           i;
        unsigned long cOhs;
        SIS_OHALLOC   *poha;
        SIS_OH        *poh;
 
-       if (sisfb_heap.poh_freelist == NULL) {
-               poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);
+       if(sisfb_heap.poh_freelist == NULL) {
+               poha = kmalloc(SIS_OH_ALLOC_SIZE, GFP_KERNEL);
                if(!poha) return NULL;
 
                poha->poha_next = sisfb_heap.poha_chain;
                sisfb_heap.poha_chain = poha;
 
-               cOhs = (OH_ALLOC_SIZE - sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1;
+               cOhs = (SIS_OH_ALLOC_SIZE - sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1;
 
                poh = &poha->aoh[0];
-               for (i = cOhs - 1; i != 0; i--) {
+               for(i = cOhs - 1; i != 0; i--) {
                        poh->poh_next = poh + 1;
                        poh = poh + 1;
                }
@@ -3486,21 +3157,22 @@ static SIS_OH *sisfb_poh_new_node(void)
        return (poh);
 }
 
-static SIS_OH *sisfb_poh_allocate(unsigned long size)
+static SIS_OH *
+sisfb_poh_allocate(u32 size)
 {
        SIS_OH *pohThis;
        SIS_OH *pohRoot;
        int     bAllocated = 0;
 
-       if (size > sisfb_heap.max_freesize) {
-               DPRINTK("sisfb: Can't allocate %dk size on offscreen\n",
+       if(size > sisfb_heap.max_freesize) {
+               DPRINTK("sisfb: Can't allocate %dk video memory\n",
                        (unsigned int) size / 1024);
                return (NULL);
        }
 
        pohThis = sisfb_heap.oh_free.poh_next;
 
-       while (pohThis != &sisfb_heap.oh_free) {
+       while(pohThis != &sisfb_heap.oh_free) {
                if (size <= pohThis->size) {
                        bAllocated = 1;
                        break;
@@ -3508,19 +3180,19 @@ static SIS_OH *sisfb_poh_allocate(unsigned long size)
                pohThis = pohThis->poh_next;
        }
 
-       if (!bAllocated) {
-               DPRINTK("sisfb: Can't allocate %dk size on offscreen\n",
+       if(!bAllocated) {
+               DPRINTK("sisfb: Can't allocate %dk video memory\n",
                        (unsigned int) size / 1024);
                return (NULL);
        }
 
-       if (size == pohThis->size) {
+       if(size == pohThis->size) {
                pohRoot = pohThis;
                sisfb_delete_node(pohThis);
        } else {
                pohRoot = sisfb_poh_new_node();
 
-               if (pohRoot == NULL) {
+               if(pohRoot == NULL) {
                        return (NULL);
                }
 
@@ -3539,7 +3211,8 @@ static SIS_OH *sisfb_poh_allocate(unsigned long size)
        return (pohRoot);
 }
 
-static void sisfb_delete_node(SIS_OH *poh)
+static void
+sisfb_delete_node(SIS_OH *poh)
 {
        SIS_OH *poh_prev;
        SIS_OH *poh_next;
@@ -3549,10 +3222,10 @@ static void sisfb_delete_node(SIS_OH *poh)
 
        poh_prev->poh_next = poh_next;
        poh_next->poh_prev = poh_prev;
-
 }
 
-static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
+static void
+sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
 {
        SIS_OH *pohTemp;
 
@@ -3565,15 +3238,16 @@ static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
        poh->poh_next = pohTemp;
 }
 
-static SIS_OH *sisfb_poh_free(unsigned long base)
+static SIS_OH *
+sisfb_poh_free(u32 base)
 {
        SIS_OH *pohThis;
        SIS_OH *poh_freed;
        SIS_OH *poh_prev;
        SIS_OH *poh_next;
-       unsigned long ulUpper;
-       unsigned long ulLower;
-       int foundNode = 0;
+       u32     ulUpper;
+       u32     ulLower;
+       int     foundNode = 0;
 
        poh_freed = sisfb_heap.oh_used.poh_next;
 
@@ -3586,7 +3260,7 @@ static SIS_OH *sisfb_poh_free(unsigned long base)
                poh_freed = poh_freed->poh_next;
        }
 
-       if (!foundNode)  return (NULL);
+       if(!foundNode) return(NULL);
 
        sisfb_heap.max_freesize += poh_freed->size;
 
@@ -3596,12 +3270,10 @@ static SIS_OH *sisfb_poh_free(unsigned long base)
 
        pohThis = sisfb_heap.oh_free.poh_next;
 
-       while (pohThis != &sisfb_heap.oh_free) {
-               if (pohThis->offset == ulUpper) {
+       while(pohThis != &sisfb_heap.oh_free) {
+               if(pohThis->offset == ulUpper) {
                        poh_next = pohThis;
-               }
-                       else if ((pohThis->offset + pohThis->size) ==
-                                ulLower) {
+               } else if((pohThis->offset + pohThis->size) == ulLower) {
                        poh_prev = pohThis;
                }
                pohThis = pohThis->poh_next;
@@ -3609,65 +3281,73 @@ static SIS_OH *sisfb_poh_free(unsigned long base)
 
        sisfb_delete_node(poh_freed);
 
-       if (poh_prev && poh_next) {
+       if(poh_prev && poh_next) {
                poh_prev->size += (poh_freed->size + poh_next->size);
                sisfb_delete_node(poh_next);
                sisfb_free_node(poh_freed);
                sisfb_free_node(poh_next);
-               return (poh_prev);
+               return(poh_prev);
        }
 
-       if (poh_prev) {
+       if(poh_prev) {
                poh_prev->size += poh_freed->size;
                sisfb_free_node(poh_freed);
-               return (poh_prev);
+               return(poh_prev);
        }
 
-       if (poh_next) {
+       if(poh_next) {
                poh_next->size += poh_freed->size;
                poh_next->offset = poh_freed->offset;
                sisfb_free_node(poh_freed);
-               return (poh_next);
+               return(poh_next);
        }
 
        sisfb_insert_node(&sisfb_heap.oh_free, poh_freed);
 
-       return (poh_freed);
+       return(poh_freed);
 }
 
-static void sisfb_free_node(SIS_OH *poh)
+static void
+sisfb_free_node(SIS_OH *poh)
 {
        if(poh == NULL) return;
 
        poh->poh_next = sisfb_heap.poh_freelist;
        sisfb_heap.poh_freelist = poh;
-
 }
 
-void sis_malloc(struct sis_memreq *req)
+void
+sis_malloc(struct sis_memreq *req)
 {
-       SIS_OH *poh;
+       struct sis_video_info *ivideo = sisfb_heap.vinfo;
+       SIS_OH *poh = NULL;
 
-       poh = sisfb_poh_allocate(req->size);
+       if((ivideo) && (!ivideo->havenoheap)) {
+          poh = sisfb_poh_allocate((u32)req->size);
+       }
 
        if(poh == NULL) {
-               req->offset = 0;
-               req->size = 0;
-               DPRINTK("sisfb: Video RAM allocation failed\n");
+          req->offset = req->size = 0;
+          DPRINTK("sisfb: Video RAM allocation failed\n");
        } else {
-               DPRINTK("sisfb: Video RAM allocation succeeded: 0x%p\n",
-                       (char *) (poh->offset + (unsigned long) ivideo.video_vbase));
-
-               req->offset = poh->offset;
-               req->size = poh->size;
+          req->offset = poh->offset;
+          req->size = poh->size;
+          DPRINTK("sisfb: Video RAM allocation succeeded: 0x%lx\n",
+                   (poh->offset + ivideo->video_vbase));
        }
 }
 
-void sis_free(unsigned long base)
+/* sis_free: u32 because "base" is offset inside video ram, can never be >4GB */
+
+void
+sis_free(u32 base)
 {
+       struct sis_video_info *ivideo = sisfb_heap.vinfo;
        SIS_OH *poh;
 
-       poh = sisfb_poh_free(base);
+       if((!ivideo) || (ivideo->havenoheap)) return;
+
+       poh = sisfb_poh_free((u32)base);
 
        if(poh == NULL) {
                DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n",
@@ -3677,125 +3357,313 @@ void sis_free(unsigned long base)
 
 /* --------------------- SetMode routines ------------------------- */
 
-static void sisfb_pre_setmode(void)
+static void
+sisfb_pre_setmode(struct sis_video_info *ivideo)
 {
-       u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0;
+       u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0, cr38 = 0;
+       int tvregnum = 0;
 
-       ivideo.currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
+       ivideo->currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
 
        inSISIDXREG(SISCR, 0x31, cr31);
        cr31 &= ~0x60;
        cr31 |= 0x04;
 
-       cr33 = sisfb_rate_idx & 0x0F;
+       cr33 = ivideo->rate_idx & 0x0F;
+
+#ifdef CONFIG_FB_SIS_315
+       if(ivideo->sisvga_engine == SIS_315_VGA) {
+          if(ivideo->chip >= SIS_661) {
+             inSISIDXREG(SISCR, 0x38, cr38);
+             cr38 &= ~0x07;  /* Clear LCDA/DualEdge and YPbPr bits */
+          } else {
+             tvregnum = 0x38;
+             inSISIDXREG(SISCR, tvregnum, cr38);
+             cr38 &= ~0x3b;  /* Clear LCDA/DualEdge and YPbPr bits */
+          }
+       }
+#endif
+#ifdef CONFIG_FB_SIS_300
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
+          tvregnum = 0x35;
+          inSISIDXREG(SISCR, tvregnum, cr38);
+       }
+#endif
+
+       SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
+       SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
 
-       SiS_SetEnableDstn(&SiS_Pr, FALSE);
-       SiS_SetEnableFstn(&SiS_Pr, FALSE);
+       switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
 
-       switch (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
           case CRT2_TV:
-               ivideo.disp_state = DISPTYPE_TV;
-               if (ivideo.vbflags & TV_SVIDEO) {
-                       cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);
-                       ivideo.currentvbflags |= TV_SVIDEO;
-                       ivideo.TV_plug = TVPLUG_SVIDEO;
-               } else if (ivideo.vbflags & TV_AVIDEO) {
-                       cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE);
-                       ivideo.currentvbflags |= TV_AVIDEO;
-                       ivideo.TV_plug = TVPLUG_COMPOSITE;
-               } else if (ivideo.vbflags & TV_SCART) {
-                       cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
-                       ivideo.currentvbflags |= TV_SCART;
-                       ivideo.TV_plug = TVPLUG_SCART;
-               }
-               cr31 |= SIS_DRIVER_MODE;
-
-               if(!(ivideo.vbflags & TV_HIVISION)) {
-                       if (ivideo.vbflags & TV_PAL) {
-                               cr31 |= 0x01;
-                               cr35 |= 0x01;
-                               ivideo.currentvbflags |= TV_PAL;
-                               ivideo.TV_type = TVMODE_PAL;
-                       } else {
-                               cr31 &= ~0x01;
-                               cr35 &= ~0x01;
-                               ivideo.currentvbflags |= TV_NTSC;
-                               ivideo.TV_type = TVMODE_NTSC;
-                       }
-               }
-               break;
+             cr38 &= ~0xc0;   /* Clear PAL-M / PAL-N bits */
+             if((ivideo->vbflags & TV_YPBPR) && (ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV))) {
+#ifdef CONFIG_FB_SIS_315
+                if(ivideo->chip >= SIS_661) {
+                   cr38 |= 0x04;
+                   if(ivideo->vbflags & TV_YPBPR525P)       cr35 |= 0x20;
+                   else if(ivideo->vbflags & TV_YPBPR750P)  cr35 |= 0x40;
+                   else if(ivideo->vbflags & TV_YPBPR1080I) cr35 |= 0x60;
+                   cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
+                   cr35 &= ~0x01;
+                   ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
+                } else if(ivideo->sisvga_engine == SIS_315_VGA) {
+                   cr30 |= (0x80 | SIS_SIMULTANEOUS_VIEW_ENABLE);
+                   cr38 |= 0x08;
+                   if(ivideo->vbflags & TV_YPBPR525P)       cr38 |= 0x10;
+                   else if(ivideo->vbflags & TV_YPBPR750P)  cr38 |= 0x20;
+                   else if(ivideo->vbflags & TV_YPBPR1080I) cr38 |= 0x30;
+                   cr31 &= ~0x01;
+                   ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
+                }
+#endif
+             } else if((ivideo->vbflags & TV_HIVISION) && (ivideo->vbflags & (VB_301|VB_301B|VB_302B))) {
+                if(ivideo->chip >= SIS_661) {
+                   cr38 |= 0x04;
+                   cr35 |= 0x60;
+                } else {
+                   cr30 |= 0x80;
+                }
+                cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
+                cr31 |= 0x01;
+                cr35 |= 0x01;
+                ivideo->currentvbflags |= TV_HIVISION;
+             } else if(ivideo->vbflags & TV_SCART) {
+                cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
+                cr31 |= 0x01;
+                cr35 |= 0x01;
+                ivideo->currentvbflags |= TV_SCART;
+             } else {
+                if(ivideo->vbflags & TV_SVIDEO) {
+                   cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);
+                   ivideo->currentvbflags |= TV_SVIDEO;
+                }
+                if(ivideo->vbflags & TV_AVIDEO) {
+                   cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE);
+                   ivideo->currentvbflags |= TV_AVIDEO;
+                }
+             }
+             cr31 |= SIS_DRIVER_MODE;
+
+             if(ivideo->vbflags & (TV_AVIDEO|TV_SVIDEO)) {
+                if(ivideo->vbflags & TV_PAL) {
+                   cr31 |= 0x01; cr35 |= 0x01;
+                   ivideo->currentvbflags |= TV_PAL;
+                   if(ivideo->vbflags & TV_PALM) {
+                      cr38 |= 0x40; cr35 |= 0x04;
+                      ivideo->currentvbflags |= TV_PALM;
+                   } else if(ivideo->vbflags & TV_PALN) {
+                      cr38 |= 0x80; cr35 |= 0x08;
+                      ivideo->currentvbflags |= TV_PALN;
+                   }
+                 } else {
+                   cr31 &= ~0x01; cr35 &= ~0x01;
+                   ivideo->currentvbflags |= TV_NTSC;
+                   if(ivideo->vbflags & TV_NTSCJ) {
+                      cr38 |= 0x40; cr35 |= 0x02;
+                      ivideo->currentvbflags |= TV_NTSCJ;
+                   }
+                }
+             }
+             break;
+
           case CRT2_LCD:
-               ivideo.disp_state = DISPTYPE_LCD;
-               cr30  = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
-               cr31 |= SIS_DRIVER_MODE;
-               SiS_SetEnableDstn(&SiS_Pr, sisfb_dstn);
-               SiS_SetEnableFstn(&SiS_Pr, sisfb_fstn);
-               break;
+             cr30  = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
+             cr31 |= SIS_DRIVER_MODE;
+             SiS_SetEnableDstn(&ivideo->SiS_Pr, ivideo->sisfb_dstn);
+             SiS_SetEnableFstn(&ivideo->SiS_Pr, ivideo->sisfb_fstn);
+             break;
+
           case CRT2_VGA:
-               ivideo.disp_state = DISPTYPE_CRT2;
-               cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
-               cr31 |= SIS_DRIVER_MODE;
-               if(sisfb_nocrt2rate) {
-                       cr33 |= (sisbios_mode[sisfb_mode_idx].rate_idx << 4);
-               } else {
-                       cr33 |= ((sisfb_rate_idx & 0x0F) << 4);
-               }
-               break;
+             cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
+             cr31 |= SIS_DRIVER_MODE;
+             if(ivideo->sisfb_nocrt2rate) {
+                cr33 |= (sisbios_mode[ivideo->sisfb_mode_idx].rate_idx << 4);
+             } else {
+                cr33 |= ((ivideo->rate_idx & 0x0F) << 4);
+             }
+             break;
+
           default:     /* disable CRT2 */
-               cr30 = 0x00;
-               cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
+             cr30 = 0x00;
+             cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
        }
 
-       if(ivideo.chip >= SIS_661) {
-          cr31 &= ~0x01;
-          /* Leave overscan bit alone */
-          setSISIDXREG(SISCR, 0x35, ~0x10, cr35);
-       }
-       outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR30, cr30);
-       outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR31, cr31);
-       outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR33, cr33);
+       outSISIDXREG(SISCR, 0x30, cr30);
+       outSISIDXREG(SISCR, 0x33, cr33);
 
+       if(ivideo->chip >= SIS_661) {
 #ifdef CONFIG_FB_SIS_315
-        if(sisvga_engine == SIS_315_VGA) {
-          /* Clear LCDA and PAL-N/M bits */
-          andSISIDXREG(SISCR,0x38,~0x03);
-          if(ivideo.chip < SIS_661) {
-             andSISIDXREG(SISCR,0x38,~0xc0);
-          }
+          cr31 &= ~0x01;                          /* Clear PAL flag (now in CR35) */
+          setSISIDXREG(SISCR, 0x35, ~0x10, cr35); /* Leave overscan bit alone */
+          cr38 &= 0x07;                           /* Use only LCDA and HiVision/YPbPr bits */
+          setSISIDXREG(SISCR, 0x38, 0xf8, cr38);
+#endif
+       } else if(ivideo->chip != SIS_300) {
+          outSISIDXREG(SISCR, tvregnum, cr38);
        }
+       outSISIDXREG(SISCR, 0x31, cr31);
+
+       if(ivideo->accel) sisfb_syncaccel(ivideo);
+
+       ivideo->SiS_Pr.SiS_UseOEM = ivideo->sisfb_useoem;
+}
+
+/* Fix SR11 for 661 and later */
+#ifdef CONFIG_FB_SIS_315
+static void
+sisfb_fixup_SR11(struct sis_video_info *ivideo)
+{
+    u8  tmpreg;
+
+    if(ivideo->chip >= SIS_661) {
+       inSISIDXREG(SISSR,0x11,tmpreg);
+       if(tmpreg & 0x20) {
+          inSISIDXREG(SISSR,0x3e,tmpreg);
+         tmpreg = (tmpreg + 1) & 0xff;
+         outSISIDXREG(SISSR,0x3e,tmpreg);
+         inSISIDXREG(SISSR,0x11,tmpreg);
+       }
+       if(tmpreg & 0xf0) {
+          andSISIDXREG(SISSR,0x11,0x0f);
+       }
+    }
+}
 #endif
 
-       if(ivideo.accel) sisfb_syncaccel();
+static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val)
+{
+   if(val > 32) val = 32;
+   if(val < -32) val = -32;
+   ivideo->tvxpos = val;
+
+   if(ivideo->sisfblocked) return;
+   if(!ivideo->modechanged) return;
+
+   if(ivideo->currentvbflags & CRT2_TV) {
+
+      if(ivideo->vbflags & VB_CHRONTEL) {
+
+        int x = ivideo->tvx;
+
+        switch(ivideo->chronteltype) {
+        case 1:
+            x += val;
+            if(x < 0) x = 0;
+            outSISIDXREG(SISSR,0x05,0x86);
+            SiS_SetCH700x(&ivideo->SiS_Pr, (((x & 0xff) << 8) | 0x0a));
+            SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, (((x & 0x0100) << 1) | 0x08),0xFD);
+            break;
+        case 2:
+            /* Not supported by hardware */
+            break;
+        }
 
-       SiS_Pr.SiS_UseOEM = sisfb_useoem;
+      } else if(ivideo->vbflags & VB_SISBRIDGE) {
+
+        u8 p2_1f,p2_20,p2_2b,p2_42,p2_43;
+        unsigned short temp;
+
+        p2_1f = ivideo->p2_1f;
+        p2_20 = ivideo->p2_20;
+        p2_2b = ivideo->p2_2b;
+        p2_42 = ivideo->p2_42;
+        p2_43 = ivideo->p2_43;
+
+        temp = p2_1f | ((p2_20 & 0xf0) << 4);
+        temp += (val * 2);
+        p2_1f = temp & 0xff;
+        p2_20 = (temp & 0xf00) >> 4;
+        p2_2b = ((p2_2b & 0x0f) + (val * 2)) & 0x0f;
+        temp = p2_43 | ((p2_42 & 0xf0) << 4);
+        temp += (val * 2);
+        p2_43 = temp & 0xff;
+        p2_42 = (temp & 0xf00) >> 4;
+        outSISIDXREG(SISPART2,0x1f,p2_1f);
+        setSISIDXREG(SISPART2,0x20,0x0F,p2_20);
+        setSISIDXREG(SISPART2,0x2b,0xF0,p2_2b);
+        setSISIDXREG(SISPART2,0x42,0x0F,p2_42);
+        outSISIDXREG(SISPART2,0x43,p2_43);
+      }
+   }
 }
 
-static void sisfb_post_setmode(void)
+static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val)
+{
+   if(val > 32) val = 32;
+   if(val < -32) val = -32;
+   ivideo->tvypos = val;
+
+   if(ivideo->sisfblocked) return;
+   if(!ivideo->modechanged) return;
+
+   if(ivideo->currentvbflags & CRT2_TV) {
+
+      if(ivideo->vbflags & VB_CHRONTEL) {
+
+        int y = ivideo->tvy;
+
+        switch(ivideo->chronteltype) {
+        case 1:
+           y -= val;
+           if(y < 0) y = 0;
+           outSISIDXREG(SISSR,0x05,0x86);
+           SiS_SetCH700x(&ivideo->SiS_Pr, (((y & 0xff) << 8) | 0x0b));
+           SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, ((y & 0x0100) | 0x08),0xFE);
+           break;
+        case 2:
+           /* Not supported by hardware */
+           break;
+        }
+
+      } else if(ivideo->vbflags & VB_SISBRIDGE) {
+
+        char p2_01, p2_02;
+        val /= 2;
+        p2_01 = ivideo->p2_01;
+        p2_02 = ivideo->p2_02;
+
+        p2_01 += val;
+        p2_02 += val;
+        while((p2_01 <= 0) || (p2_02 <= 0)) {
+           p2_01 += 2;
+           p2_02 += 2;
+        }
+        outSISIDXREG(SISPART2,0x01,p2_01);
+        outSISIDXREG(SISPART2,0x02,p2_02);
+      }
+   }
+}
+
+static void
+sisfb_post_setmode(struct sis_video_info *ivideo)
 {
-       u8 reg;
        BOOLEAN crt1isoff = FALSE;
+       BOOLEAN doit = TRUE;
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
+       u8 reg;
+#endif
 #ifdef CONFIG_FB_SIS_315
        u8 reg1;
 #endif
-#ifdef CONFIG_FB_SIS_300
-       BOOLEAN doit = TRUE;
-#endif
-       /* We can't switch off CRT1 if bridge is in slave mode */
-       if(ivideo.vbflags & VB_VIDEOBRIDGE) {
-#ifdef CONFIG_FB_SIS_300
-               if(sisvga_engine == SIS_300_VGA) {
-                       inSISIDXREG(SISPART1, 0x00, reg);
-                       if((reg & 0xa0) == 0x20) {
-                               doit = FALSE;
-                       }
-               }
+
+       outSISIDXREG(SISSR,0x05,0x86);
+
+#ifdef CONFIG_FB_SIS_315
+       sisfb_fixup_SR11(ivideo);
 #endif
-       } else sisfb_crt1off = 0;
 
-       if(sisvga_engine == SIS_300_VGA) {
+       /* Now we actually HAVE changed the display mode */
+        ivideo->modechanged = 1;
+
+       /* We can't switch off CRT1 if bridge is in slave mode */
+       if(ivideo->vbflags & VB_VIDEOBRIDGE) {
+               if(sisfb_bridgeisslave(ivideo)) doit = FALSE;
+       } else ivideo->sisfb_crt1off = 0;
 
 #ifdef CONFIG_FB_SIS_300
-          if((sisfb_crt1off) && (doit)) {
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
+          if((ivideo->sisfb_crt1off) && (doit)) {
                crt1isoff = TRUE;
                reg = 0x00;
           } else {
@@ -3803,12 +3671,11 @@ static void sisfb_post_setmode(void)
                reg = 0x80;
           }
           setSISIDXREG(SISCR, 0x17, 0x7f, reg);
+       }
 #endif
-
-       } else {
-
 #ifdef CONFIG_FB_SIS_315
-          if(sisfb_crt1off) {
+       if(ivideo->sisvga_engine == SIS_315_VGA) {
+          if((ivideo->sisfb_crt1off) && (doit)) {
                crt1isoff = TRUE;
                reg  = 0x40;
                reg1 = 0xc0;
@@ -3818,66 +3685,89 @@ static void sisfb_post_setmode(void)
                reg1 = 0x00;
 
           }
-          setSISIDXREG(SISCR, SiS_Pr.SiS_MyCR63, ~0x40, reg);
+          setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg);
           setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
-#endif
-
        }
+#endif
 
        if(crt1isoff) {
-          ivideo.currentvbflags &= ~VB_DISPTYPE_CRT1;
-          ivideo.currentvbflags |= VB_SINGLE_MODE;
-          ivideo.disp_state |= DISPMODE_SINGLE;
+          ivideo->currentvbflags &= ~VB_DISPTYPE_CRT1;
+          ivideo->currentvbflags |= VB_SINGLE_MODE;
        } else {
-          ivideo.currentvbflags |= VB_DISPTYPE_CRT1;
-          ivideo.disp_state |= DISPTYPE_CRT1;
-          if(ivideo.currentvbflags & VB_DISPTYPE_CRT2) {
-               ivideo.currentvbflags |= VB_MIRROR_MODE;
-               ivideo.disp_state |= DISPMODE_MIRROR;
+          ivideo->currentvbflags |= VB_DISPTYPE_CRT1;
+          if(ivideo->currentvbflags & VB_DISPTYPE_CRT2) {
+               ivideo->currentvbflags |= VB_MIRROR_MODE;
           } else {
-               ivideo.currentvbflags |= VB_SINGLE_MODE;
-               ivideo.disp_state |= DISPMODE_SINGLE;
+               ivideo->currentvbflags |= VB_SINGLE_MODE;
           }
        }
 
         andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
 
-       if((ivideo.currentvbflags & CRT2_TV) && (ivideo.vbflags & VB_301)) {  /* Set filter for SiS301 */
+       if(ivideo->currentvbflags & CRT2_TV) {
+          if(ivideo->vbflags & VB_SISBRIDGE) {
+             inSISIDXREG(SISPART2,0x1f,ivideo->p2_1f);
+             inSISIDXREG(SISPART2,0x20,ivideo->p2_20);
+             inSISIDXREG(SISPART2,0x2b,ivideo->p2_2b);
+             inSISIDXREG(SISPART2,0x42,ivideo->p2_42);
+             inSISIDXREG(SISPART2,0x43,ivideo->p2_43);
+             inSISIDXREG(SISPART2,0x01,ivideo->p2_01);
+             inSISIDXREG(SISPART2,0x02,ivideo->p2_02);
+          } else if(ivideo->vbflags & VB_CHRONTEL) {
+             if(ivideo->chronteltype == 1) {
+                ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a);
+                ivideo->tvx |= (((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x02) >> 1) << 8);
+                ivideo->tvy = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0b);
+                ivideo->tvy |= ((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x01) << 8);
+             }
+          }
+       }
+
+       if(ivideo->tvxpos) {
+          sisfb_set_TVxposoffset(ivideo, ivideo->tvxpos);
+       }
+       if(ivideo->tvypos) {
+          sisfb_set_TVyposoffset(ivideo, ivideo->tvypos);
+       }
+
+       if((ivideo->currentvbflags & CRT2_TV) && (ivideo->vbflags & VB_301)) {  /* Set filter for SiS301 */
+
+               unsigned char filter_tb = 0;
 
-               switch (ivideo.video_width) {
+               switch (ivideo->video_width) {
                   case 320:
-                       filter_tb = (ivideo.vbflags & TV_NTSC) ? 4 : 12;
+                       filter_tb = (ivideo->vbflags & TV_NTSC) ? 4 : 12;
                        break;
                   case 640:
-                       filter_tb = (ivideo.vbflags & TV_NTSC) ? 5 : 13;
+                       filter_tb = (ivideo->vbflags & TV_NTSC) ? 5 : 13;
                        break;
                   case 720:
-                       filter_tb = (ivideo.vbflags & TV_NTSC) ? 6 : 14;
+                       filter_tb = (ivideo->vbflags & TV_NTSC) ? 6 : 14;
                        break;
                   case 400:
                   case 800:
-                       filter_tb = (ivideo.vbflags & TV_NTSC) ? 7 : 15;
+                       filter_tb = (ivideo->vbflags & TV_NTSC) ? 7 : 15;
                        break;
                   default:
-                       filter = -1;
+                       ivideo->sisfb_filter = -1;
                        break;
                }
 
-               orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
+               orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);
 
-               if(ivideo.vbflags & TV_NTSC) {
+               if(ivideo->vbflags & TV_NTSC) {
 
                        andSISIDXREG(SISPART2, 0x3a, 0x1f);
 
-                       if (ivideo.vbflags & TV_SVIDEO) {
+                       if (ivideo->vbflags & TV_SVIDEO) {
 
                                andSISIDXREG(SISPART2, 0x30, 0xdf);
 
-                       } else if (ivideo.vbflags & TV_AVIDEO) {
+                       } else if (ivideo->vbflags & TV_AVIDEO) {
 
                                orSISIDXREG(SISPART2, 0x30, 0x20);
 
-                               switch (ivideo.video_width) {
+                               switch (ivideo->video_width) {
                                case 640:
                                        outSISIDXREG(SISPART2, 0x35, 0xEB);
                                        outSISIDXREG(SISPART2, 0x36, 0x04);
@@ -3900,19 +3790,19 @@ static void sisfb_post_setmode(void)
                                }
                        }
 
-               } else if(ivideo.vbflags & TV_PAL) {
+               } else if(ivideo->vbflags & TV_PAL) {
 
                        andSISIDXREG(SISPART2, 0x3A, 0x1F);
 
-                       if (ivideo.vbflags & TV_SVIDEO) {
+                       if (ivideo->vbflags & TV_SVIDEO) {
 
                                andSISIDXREG(SISPART2, 0x30, 0xDF);
 
-                       } else if (ivideo.vbflags & TV_AVIDEO) {
+                       } else if (ivideo->vbflags & TV_AVIDEO) {
 
                                orSISIDXREG(SISPART2, 0x30, 0x20);
 
-                               switch (ivideo.video_width) {
+                               switch (ivideo->video_width) {
                                case 640:
                                        outSISIDXREG(SISPART2, 0x35, 0xF1);
                                        outSISIDXREG(SISPART2, 0x36, 0xF7);
@@ -3936,129 +3826,137 @@ static void sisfb_post_setmode(void)
                        }
                }
 
-               if ((filter >= 0) && (filter <= 7)) {
-                       DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
-                               sis_TV_filter[filter_tb].filter[filter][0],
-                               sis_TV_filter[filter_tb].filter[filter][1],
-                               sis_TV_filter[filter_tb].filter[filter][2],
-                               sis_TV_filter[filter_tb].filter[filter][3]
-                       );
-                       outSISIDXREG(SISPART2, 0x35, (sis_TV_filter[filter_tb].filter[filter][0]));
-                       outSISIDXREG(SISPART2, 0x36, (sis_TV_filter[filter_tb].filter[filter][1]));
-                       outSISIDXREG(SISPART2, 0x37, (sis_TV_filter[filter_tb].filter[filter][2]));
-                       outSISIDXREG(SISPART2, 0x38, (sis_TV_filter[filter_tb].filter[filter][3]));
+               if((ivideo->sisfb_filter >= 0) && (ivideo->sisfb_filter <= 7)) {
+                  outSISIDXREG(SISPART2,0x35,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][0]));
+                  outSISIDXREG(SISPART2,0x36,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][1]));
+                  outSISIDXREG(SISPART2,0x37,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][2]));
+                  outSISIDXREG(SISPART2,0x38,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][3]));
                }
          
        }
-
 }
 
 #ifndef MODULE
-int sisfb_setup(char *options)
+int __init sisfb_setup(char *options)
 {
        char *this_opt;
        
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       sisfb_fontname[0] = '\0';
-#endif
-
-       ivideo.refresh_rate = 0;
-       SiS_Pr.SiS_CustomT = CUT_NONE;
-       SiS_Pr.UsePanelScaler = -1;
-       SiS_Pr.LVDSHL = -1;
+       sisfb_setdefaultparms();
 
         printk(KERN_DEBUG "sisfb: Options %s\n", options);
 
-       if (!options || !*options)
+       if(!options || !(*options)) {
                return 0;
+       }
 
        while((this_opt = strsep(&options, ",")) != NULL) {
 
-               if (!*this_opt) continue;
+               if(!(*this_opt)) continue;
 
-               if (!strnicmp(this_opt, "mode:", 5)) {
+               if(!strnicmp(this_opt, "off", 3)) {
+                       sisfb_off = 1;
+               } else if(!strnicmp(this_opt, "forcecrt2type:", 14)) {
+                       /* Need to check crt2 type first for fstn/dstn */
+                       sisfb_search_crt2type(this_opt + 14);
+               } else if(!strnicmp(this_opt, "tvmode:",7)) {
+                       sisfb_search_tvstd(this_opt + 7);
+                } else if(!strnicmp(this_opt, "tvstandard:",11)) {
+                       sisfb_search_tvstd(this_opt + 7);
+               } else if(!strnicmp(this_opt, "mode:", 5)) {
                        sisfb_search_mode(this_opt + 5, FALSE);
-               } else if (!strnicmp(this_opt, "vesa:", 5)) {
+               } 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)) {
+               } else if(!strnicmp(this_opt, "inverse", 7)) {
                        sisfb_inverse = 1;
                        /* fb_invert_cmaps(); */
-               } else if (!strnicmp(this_opt, "font:", 5)) {
-                       strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1);
-                       sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0';
+               } 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, "vrate:", 6)) {
-                       ivideo.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
-                       sisfb_parm_rate = ivideo.refresh_rate;
-               } else if (!strnicmp(this_opt, "rate:", 5)) {
-                       ivideo.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
-                       sisfb_parm_rate = ivideo.refresh_rate;
-               } else if (!strnicmp(this_opt, "off", 3)) {
-                       sisfb_off = 1;
-               } else if (!strnicmp(this_opt, "crt1off", 7)) {
-                       sisfb_crt1off = 1;
-               } else if (!strnicmp(this_opt, "filter:", 7)) {
-                       filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
-               } else if (!strnicmp(this_opt, "forcecrt2type:", 14)) {
-                       sisfb_search_crt2type(this_opt + 14);
-               } else if (!strnicmp(this_opt, "forcecrt1:", 10)) {
+               } else if(!strnicmp(this_opt, "rate:", 5)) {
+                       sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0);
+               } else if(!strnicmp(this_opt, "filter:", 7)) {
+                       sisfb_filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
+               } else if(!strnicmp(this_opt, "forcecrt1:", 10)) {
                        sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
-                } else if (!strnicmp(this_opt, "tvmode:",7)) {
-                       sisfb_search_tvstd(this_opt + 7);
-                } else if (!strnicmp(this_opt, "tvstandard:",11)) {
-                       sisfb_search_tvstd(this_opt + 7);
-                } else if (!strnicmp(this_opt, "mem:",4)) {
-                       sisfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
-               } else if (!strnicmp(this_opt, "queuemode:", 10)) {
-                       sisfb_search_queuemode(this_opt + 10);
-               } else if (!strnicmp(this_opt, "pdc:", 4)) {
+                } else if(!strnicmp(this_opt, "mem:",4)) {
+                       sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0);
+               } else if(!strnicmp(this_opt, "pdc:", 4)) {
                        sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
-               } else if (!strnicmp(this_opt, "noaccel", 7)) {
+               } else if(!strnicmp(this_opt, "pdc1:", 5)) {
+                       sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0);
+               } else if(!strnicmp(this_opt, "noaccel", 7)) {
                        sisfb_accel = 0;
-               } else if (!strnicmp(this_opt, "noypan", 6)) {
+               } else if(!strnicmp(this_opt, "accel", 5)) {
+                       sisfb_accel = -1;
+               } else if(!strnicmp(this_opt, "noypan", 6)) {
                        sisfb_ypan = 0;
-               } else if (!strnicmp(this_opt, "nomax", 5)) {
+               } else if(!strnicmp(this_opt, "ypan", 4)) {
+                       sisfb_ypan = -1;
+               } else if(!strnicmp(this_opt, "nomax", 5)) {
                        sisfb_max = 0;
-               } else if (!strnicmp(this_opt, "userom:", 7)) {
+               } else if(!strnicmp(this_opt, "max", 3)) {
+                       sisfb_max = -1;
+               } else if(!strnicmp(this_opt, "userom:", 7)) {
                        sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
-               } else if (!strnicmp(this_opt, "useoem:", 7)) {
+               } else if(!strnicmp(this_opt, "useoem:", 7)) {
                        sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
-               } else if (!strnicmp(this_opt, "nocrt2rate", 10)) {
+               } else if(!strnicmp(this_opt, "nocrt2rate", 10)) {
                        sisfb_nocrt2rate = 1;
-               } else if (!strnicmp(this_opt, "scalelcd:", 9)) {
+               } else if(!strnicmp(this_opt, "scalelcd:", 9)) {
                        unsigned long temp = 2;
                        temp = simple_strtoul(this_opt + 9, NULL, 0);
                        if((temp == 0) || (temp == 1)) {
-                          SiS_Pr.UsePanelScaler = temp ^ 1;
+                          sisfb_scalelcd = temp ^ 1;
                        }
-               } else if (!strnicmp(this_opt, "specialtiming:", 14)) {
+               } else if(!strnicmp(this_opt, "tvxposoffset:", 13)) {
+                       int temp = 0;
+                       temp = (int)simple_strtol(this_opt + 13, NULL, 0);
+                       if((temp >= -32) && (temp <= 32)) {
+                          sisfb_tvxposoffset = temp;
+                       }
+               } else if(!strnicmp(this_opt, "tvyposoffset:", 13)) {
+                       int temp = 0;
+                       temp = (int)simple_strtol(this_opt + 13, NULL, 0);
+                       if((temp >= -32) && (temp <= 32)) {
+                          sisfb_tvyposoffset = temp;
+                       }
+               } else if(!strnicmp(this_opt, "specialtiming:", 14)) {
                        sisfb_search_specialtiming(this_opt + 14);
-               } else if (!strnicmp(this_opt, "lvdshl:", 7)) {
-                       unsigned long temp = 4;
+               } else if(!strnicmp(this_opt, "lvdshl:", 7)) {
+                       int temp = 4;
                        temp = simple_strtoul(this_opt + 7, NULL, 0);
                        if((temp >= 0) && (temp <= 3)) {
-                          SiS_Pr.LVDSHL = temp;
+                          sisfb_lvdshl = temp;
                        }
                } else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
                        sisfb_search_mode(this_opt, TRUE);
+#if !defined(__i386__) && !defined(__x86_64__)
+               } else if(!strnicmp(this_opt, "resetcard", 9)) {
+                       sisfb_resetcard = 1;
+               } else if(!strnicmp(this_opt, "videoram:", 9)) {
+                       sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0);
+#endif
                } else {
                        printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt);
                }
 
-               /* TW: Acceleration only with MMIO mode */
-               if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
-                       sisfb_accel = 0;
-               }
-
        }
+
+
+
        return 0;
 }
 #endif
 
-static char *sis_find_rom(void)
+static char * __devinit sis_find_rom(struct pci_dev *pdev)
 {
-#if defined(__i386__)
+       struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+
+#if defined(__i386__) || defined(__x86_64__)
         u32  segstart;
         unsigned char *rom_base, *rom;
         int  romptr;
@@ -4066,292 +3964,972 @@ static char *sis_find_rom(void)
 
         for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
 
-                rom_base = (char *)ioremap(segstart, 0x10000);
-               if(!rom_base) continue;
+            rom_base = (unsigned char *)ioremap(segstart, 0x10000);
+           if(!rom_base) continue;
 
-                if((*rom_base != 0x55) || (*(rom_base + 1) != 0xaa)) {
-                   iounmap(rom_base);
-                   continue;
-                }
+           if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa)) {
+              iounmap(rom_base);
+               continue;
+           }
 
-               romptr = (unsigned short)(*(rom_base + 0x18) | (*(rom_base + 0x19) << 8));
-               if(romptr > (0x10000 - 8)) {
-                  iounmap(rom_base);
-                  continue;
-               }
+           romptr = (unsigned short)(readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
+           if(romptr > (0x10000 - 8)) {
+              iounmap(rom_base);
+              continue;
+           }
 
-               rom = rom_base + romptr;
+           rom = rom_base + romptr;
 
-               if((*rom != 'P') || (*(rom + 1) != 'C') || (*(rom + 2) != 'I') || (*(rom + 3) != 'R')) {
-                  iounmap(rom_base);
-                  continue;
-               }
+           if((readb(rom)     != 'P') || (readb(rom + 1) != 'C') ||
+              (readb(rom + 2) != 'I') || (readb(rom + 3) != 'R')) {
+              iounmap(rom_base);
+              continue;
+           }
 
-               pciid = (*(rom + 4)) | ((*(rom + 5)) << 8);
-               if(pciid != 0x1039) {
-                  iounmap(rom_base);
-                  continue;
-               }
+           pciid = readb(rom + 4) | (readb(rom + 5) << 8);
+           if(pciid != 0x1039) {
+              iounmap(rom_base);
+              continue;
+           }
 
-               pciid = (*(rom + 6)) | ((*(rom + 7)) << 8);
-               if(pciid == ivideo.chip_id) return rom_base;
+           pciid = readb(rom + 6) | (readb(rom + 7) << 8);
+           if(pciid == ivideo->chip_id) return rom_base;
 
-               iounmap(rom_base);
+           iounmap(rom_base);
         }
+#else
+       unsigned char *rom_base, *rom, *myrombase = NULL;
+        int  romptr;
+       unsigned short pciid;
+       u32 backup;
+
+       pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &backup);
+       pci_write_config_dword(pdev, PCI_ROM_ADDRESS,
+                       (ivideo->video_base & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE);
+
+       rom_base = ioremap(ivideo->video_base, 65536);
+       if(rom_base) {
+          if((readb(rom_base) == 0x55) && (readb(rom_base + 1) == 0xaa)) {
+             romptr = (u16)(readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
+             if(romptr <= (0x10000 - 8)) {
+                rom = rom_base + romptr;
+                if((readb(rom)     == 'P') && (readb(rom + 1) == 'C') &&
+                   (readb(rom + 2) == 'I') && (readb(rom + 3) == 'R')) {
+                   pciid = readb(rom + 4) | (readb(rom + 5) << 8);
+                   if(pciid == 0x1039) {
+                      pciid = readb(rom + 6) | (readb(rom + 7) << 8);
+                      if(pciid == ivideo->chip_id) {
+                         if((myrombase = vmalloc(65536))) {
+                            memcpy_fromio(myrombase, rom_base, 65536);
+                         }
+                      }
+                   }
+                }
+             }
+          }
+          iounmap(rom_base);
+       }
+        pci_write_config_dword(pdev, PCI_ROM_ADDRESS, backup);
+       if(myrombase) return myrombase;
 #endif
         return NULL;
 }
 
-
-
-int __init sisfb_init(void)
+#ifdef CONFIG_FB_SIS_300
+static int __devinit
+sisfb_chkbuswidth300(struct pci_dev *pdev, ULONG FBAddress)
 {
-       struct pci_dev *pdev = NULL;
-       struct board *b;
-       int pdev_valid = 0;
-       u32 reg32;
-       u16 reg16;
-       u8  reg;
+       struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+       int i, j;
+       USHORT temp;
+       UCHAR reg;
+
+       andSISIDXREG(SISSR,0x15,0xFB);
+       orSISIDXREG(SISSR,0x15,0x04);
+       outSISIDXREG(SISSR,0x13,0x00);
+       outSISIDXREG(SISSR,0x14,0xBF);
+
+       for(i=0; i<2; i++) {
+          temp = 0x1234;
+          for(j=0; j<4; j++) {
+             writew(temp, FBAddress);
+             if(readw(FBAddress) == temp) break;
+             orSISIDXREG(SISSR,0x3c,0x01);
+             inSISIDXREG(SISSR,0x05,reg);
+             inSISIDXREG(SISSR,0x05,reg);
+             andSISIDXREG(SISSR,0x3c,0xfe);
+             inSISIDXREG(SISSR,0x05,reg);
+             inSISIDXREG(SISSR,0x05,reg);
+             temp++;
+          }
+       }
 
-#if 0
-       /* for DOC VB */
-       sisfb_set_reg4(0xcf8,0x800000e0);
-       reg32 = sisfb_get_reg3(0xcfc);
-       reg32 = reg32 | 0x00001000;
-       sisfb_set_reg4(0xcfc,reg32);
+       writel(0x01234567L, FBAddress);
+       writel(0x456789ABL, (FBAddress+4));
+       writel(0x89ABCDEFL, (FBAddress+8));
+       writel(0xCDEF0123L, (FBAddress+12));
+       inSISIDXREG(SISSR,0x3b,reg);
+       if(reg & 0x01) {
+          if(readl((FBAddress+12)) == 0xCDEF0123L) return(4);  /* Channel A 128bit */
        }
-#endif
+       if(readl((FBAddress+4)) == 0x456789ABL)     return(2);  /* Channel B 64bit */
+       return(1);                                              /* 32bit */
+}
 
-       if (sisfb_off)
-               return -ENXIO;
+static void __devinit
+sisfb_setramsize300(struct pci_dev *pdev)
+{
+       struct  sis_video_info *ivideo = pci_get_drvdata(pdev);
+       ULONG   FBAddr = (ULONG)ivideo->sishw_ext.pjVideoMemoryAddress, Addr;
+       USHORT  SR13, SR14=0, buswidth, Done, data, TotalCapacity, PhysicalAdrOtherPage=0;
+       int     PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount;
+       int     RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank;
+       int     PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage, i, j, k;
+       const   USHORT SiS_DRAMType[17][5] = {
+                       {0x0C,0x0A,0x02,0x40,0x39},
+                       {0x0D,0x0A,0x01,0x40,0x48},
+                       {0x0C,0x09,0x02,0x20,0x35},
+                       {0x0D,0x09,0x01,0x20,0x44},
+                       {0x0C,0x08,0x02,0x10,0x31},
+                       {0x0D,0x08,0x01,0x10,0x40},
+                       {0x0C,0x0A,0x01,0x20,0x34},
+                       {0x0C,0x09,0x01,0x08,0x32},
+                       {0x0B,0x08,0x02,0x08,0x21},
+                       {0x0C,0x08,0x01,0x08,0x30},
+                       {0x0A,0x08,0x02,0x04,0x11},
+                       {0x0B,0x0A,0x01,0x10,0x28},
+                       {0x09,0x08,0x02,0x02,0x01},
+                       {0x0B,0x09,0x01,0x08,0x24},
+                       {0x0B,0x08,0x01,0x04,0x20},
+                       {0x0A,0x08,0x01,0x02,0x10},
+                       {0x09,0x08,0x01,0x01,0x00}
+               };
+
+        buswidth = sisfb_chkbuswidth300(pdev, FBAddr);
+
+       MB2Bank = 16;
+       Done = 0;
+       for(i = 6; i >= 0; i--) {
+          if(Done) break;
+          PseudoRankCapacity = 1 << i;
+          for(j = 4; j >= 1; j--) {
+              if(Done) break;
+              PseudoTotalCapacity = PseudoRankCapacity * j;
+              PseudoAdrPinCount = 15 - j;
+              if(PseudoTotalCapacity <= 64) {
+                 for(k = 0; k <= 16; k++) {
+                    if(Done) break;
+                    RankCapacity = buswidth * SiS_DRAMType[k][3];
+                    AdrPinCount = SiS_DRAMType[k][2] + SiS_DRAMType[k][0];
+                    if(RankCapacity == PseudoRankCapacity)
+                       if(AdrPinCount <= PseudoAdrPinCount) {
+                          if(j == 3) {             /* Rank No */
+                             BankNumHigh = RankCapacity * MB2Bank * 3 - 1;
+                             BankNumMid  = RankCapacity * MB2Bank * 1 - 1;
+                          } else {
+                             BankNumHigh = RankCapacity * MB2Bank * j - 1;
+                             BankNumMid  = RankCapacity * MB2Bank * j / 2 - 1;
+                          }
+                          PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
+                          PhysicalAdrHigh = BankNumHigh;
+                          PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
+                          PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
+                          /* Write data */
+                          andSISIDXREG(SISSR,0x15,0xFB); /* Test */
+                          orSISIDXREG(SISSR,0x15,0x04);  /* Test */
+                          TotalCapacity = SiS_DRAMType[k][3] * buswidth;
+                          SR13 = SiS_DRAMType[k][4];
+                          if(buswidth == 4) SR14 = (TotalCapacity - 1) | 0x80;
+                          if(buswidth == 2) SR14 = (TotalCapacity - 1) | 0x40;
+                          if(buswidth == 1) SR14 = (TotalCapacity - 1) | 0x00;
+                          outSISIDXREG(SISSR,0x13,SR13);
+                          outSISIDXREG(SISSR,0x14,SR14);
+                          Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
+                          /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHigh; */
+                         writew(((USHORT)PhysicalAdrHigh), Addr);
+                          Addr = FBAddr + BankNumMid * 64 * 1024 + PhysicalAdrHigh;
+                          /* *((USHORT *)(Addr)) = (USHORT)BankNumMid; */
+                         writew(((USHORT)BankNumMid), Addr);
+                          Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHalfPage;
+                          /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHalfPage; */
+                         writew(((USHORT)PhysicalAdrHalfPage), Addr);
+                          Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrOtherPage;
+                          /* *((USHORT *)(Addr)) = PhysicalAdrOtherPage; */
+                         writew(((USHORT)PhysicalAdrOtherPage), Addr);
+                          /* Read data */
+                          Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
+                          data = readw(Addr); /* *((USHORT *)(Addr)); */
+                          if(data == PhysicalAdrHigh) Done = 1;
+                       }  /* if */
+                 }  /* for k */
+              }  /* if */
+          }  /* for j */
+       }  /* for i */
+}
 
-       sisfb_registered = 0;
-       sisfb_thismonitor.datavalid = FALSE;
+static void __devinit sisfb_post_sis300(struct pci_dev *pdev)
+{
+       struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+       u8  reg, v1, v2, v3, v4, v5, v6, v7, v8;
+       u16 index, rindex, memtype = 0;
 
-       memset(&sishw_ext, 0, sizeof(sishw_ext));
+       outSISIDXREG(SISSR,0x05,0x86);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-        memset(&sisfb_lastrates[0], 0, 128);
-#endif
-       
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 
-       memset(&sis_disp, 0, sizeof(sis_disp));
-#endif
+       if(ivideo->sishw_ext.UseROM) {
+          if(ivideo->sishw_ext.pjVirtualRomBase[0x52] & 0x80) {
+             memtype = ivideo->sishw_ext.pjVirtualRomBase[0x52];
+          } else {
+             inSISIDXREG(SISSR,0x3a,memtype);
+          }
+          memtype &= 0x07;
+       }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
-       pci_for_each_dev(pdev) {
-#else
-       while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
+       if(ivideo->revision_id <= 0x13) {
+          v1 = 0x44; v2 = 0x42; v3 = 0x80;
+          v4 = 0x44; v5 = 0x42; v6 = 0x80;
+       } else {
+          v1 = 0x68; v2 = 0x43; v3 = 0x80;  /* Assume 125Mhz MCLK */
+          v4 = 0x68; v5 = 0x43; v6 = 0x80;  /* Assume 125Mhz ECLK */
+          if(ivideo->sishw_ext.UseROM) {
+             index = memtype * 5;
+             rindex = index + 0x54;
+             v1 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+             v2 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+             v3 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+             rindex = index + 0x7c;
+             v4 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+             v5 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+             v6 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+          }
+       }
+       outSISIDXREG(SISSR,0x28,v1);
+       outSISIDXREG(SISSR,0x29,v2);
+       outSISIDXREG(SISSR,0x2a,v3);
+       outSISIDXREG(SISSR,0x2e,v4);
+       outSISIDXREG(SISSR,0x2f,v5);
+       outSISIDXREG(SISSR,0x30,v6);
+       v1 = 0x10;
+       if(ivideo->sishw_ext.UseROM) v1 = ivideo->sishw_ext.pjVirtualRomBase[0xa4];
+       outSISIDXREG(SISSR,0x07,v1);       /* DAC speed */
+       outSISIDXREG(SISSR,0x11,0x0f);     /* DDC, power save */
+       v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a;
+       v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00;
+       if(ivideo->sishw_ext.UseROM) {
+          memtype += 0xa5;
+          v1 = ivideo->sishw_ext.pjVirtualRomBase[memtype];
+          v2 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 8];
+          v3 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 16];
+          v4 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 24];
+          v5 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 32];
+          v6 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 40];
+          v7 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 48];
+          v8 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 56];
+       }
+       if(ivideo->revision_id >= 0x80) v3 &= 0xfd;
+       outSISIDXREG(SISSR,0x15,v1);       /* Ram type (assuming 0, BIOS 0xa5 step 8) */
+       outSISIDXREG(SISSR,0x16,v2);
+       outSISIDXREG(SISSR,0x17,v3);
+       outSISIDXREG(SISSR,0x18,v4);
+       outSISIDXREG(SISSR,0x19,v5);
+       outSISIDXREG(SISSR,0x1a,v6);
+       outSISIDXREG(SISSR,0x1b,v7);
+       outSISIDXREG(SISSR,0x1c,v8);       /* ---- */
+       andSISIDXREG(SISSR,0x15,0xfb);
+       orSISIDXREG(SISSR,0x15,0x04);
+       if(ivideo->sishw_ext.UseROM) {
+          if(ivideo->sishw_ext.pjVirtualRomBase[0x53] & 0x02) {
+             orSISIDXREG(SISSR,0x19,0x20);
+          }
+       }
+       v1 = 0x04;                         /* DAC pedestal (BIOS 0xe5) */
+       if(ivideo->revision_id >= 0x80) v1 |= 0x01;
+       outSISIDXREG(SISSR,0x1f,v1);
+       outSISIDXREG(SISSR,0x20,0xa0);     /* linear & relocated io */
+       v1 = 0xf6; v2 = 0x0d; v3 = 0x00;
+       if(ivideo->sishw_ext.UseROM) {
+          v1 = ivideo->sishw_ext.pjVirtualRomBase[0xe8];
+          v2 = ivideo->sishw_ext.pjVirtualRomBase[0xe9];
+          v3 = ivideo->sishw_ext.pjVirtualRomBase[0xea];
+       }
+       outSISIDXREG(SISSR,0x23,v1);
+       outSISIDXREG(SISSR,0x24,v2);
+       outSISIDXREG(SISSR,0x25,v3);
+       outSISIDXREG(SISSR,0x21,0x84);
+       outSISIDXREG(SISSR,0x22,0x00);
+       outSISIDXREG(SISCR,0x37,0x00);
+       orSISIDXREG(SISPART1,0x24,0x01);   /* unlock crt2 */
+       outSISIDXREG(SISPART1,0x00,0x00);
+       v1 = 0x40; v2 = 0x11;
+       if(ivideo->sishw_ext.UseROM) {
+          v1 = ivideo->sishw_ext.pjVirtualRomBase[0xec];
+          v2 = ivideo->sishw_ext.pjVirtualRomBase[0xeb];
+       }
+       outSISIDXREG(SISPART1,0x02,v1);
+       if(ivideo->revision_id >= 0x80) v2 &= ~0x01;
+       inSISIDXREG(SISPART4,0x00,reg);
+       if((reg == 1) || (reg == 2)) {
+          outSISIDXREG(SISCR,0x37,0x02);
+          outSISIDXREG(SISPART2,0x00,0x1c);
+          v4 = 0x00; v5 = 0x00; v6 = 0x10;
+          if(ivideo->sishw_ext.UseROM) {
+             v4 = ivideo->sishw_ext.pjVirtualRomBase[0xf5];
+             v5 = ivideo->sishw_ext.pjVirtualRomBase[0xf6];
+             v6 = ivideo->sishw_ext.pjVirtualRomBase[0xf7];
+          }
+          outSISIDXREG(SISPART4,0x0d,v4);
+          outSISIDXREG(SISPART4,0x0e,v5);
+          outSISIDXREG(SISPART4,0x10,v6);
+          outSISIDXREG(SISPART4,0x0f,0x3f);
+          inSISIDXREG(SISPART4,0x01,reg);
+          if(reg >= 0xb0) {
+             inSISIDXREG(SISPART4,0x23,reg);
+             reg &= 0x20;
+             reg <<= 1;
+             outSISIDXREG(SISPART4,0x23,reg);
+          }
+       } else {
+          v2 &= ~0x10;
+       }
+       outSISIDXREG(SISSR,0x32,v2);
+       andSISIDXREG(SISPART1,0x24,0xfe);  /* Lock CRT2 */
+       inSISIDXREG(SISSR,0x16,reg);
+       reg &= 0xc3;
+       outSISIDXREG(SISCR,0x35,reg);
+       outSISIDXREG(SISCR,0x83,0x00);
+#if !defined(__i386__) && !defined(__x86_64__)
+       if(sisfb_videoram) {
+          outSISIDXREG(SISSR,0x13,0x28);  /* ? */
+          reg = ((sisfb_videoram >> 10) - 1) | 0x40;
+          outSISIDXREG(SISSR,0x14,reg);
+       } else {
 #endif
-               for (b = sisdev_list; b->vendor; b++) {
-                       if ((b->vendor == pdev->vendor)
-                           && (b->device == pdev->device)) {
-                               pdev_valid = 1;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && defined(NEWFBDEV)
-                               sis_fb_info = framebuffer_alloc(0, &pdev->dev);
-#else
-                               sis_fb_info = kmalloc(sizeof(*sis_fb_info), GFP_KERNEL);
+          /* Need to map max FB size for finding out about RAM size */
+          ivideo->sishw_ext.pjVideoMemoryAddress = ioremap(ivideo->video_base, 0x4000000);
+          if(ivideo->sishw_ext.pjVideoMemoryAddress) {
+             sisfb_setramsize300(pdev);
+             iounmap(ivideo->sishw_ext.pjVideoMemoryAddress);
+          } else {
+             printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
+             outSISIDXREG(SISSR,0x13,0x28);  /* ? */
+             outSISIDXREG(SISSR,0x14,0x47);  /* 8MB, 64bit default */
+          }
+#if !defined(__i386__) && !defined(__x86_64__)
+       }
 #endif
-                               if(!sis_fb_info) return -ENOMEM;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) || (!(defined(NEWFBDEV)))
-                               memset(sis_fb_info, 0, sizeof(*sis_fb_info));
+       if(ivideo->sishw_ext.UseROM) {
+          v1 = ivideo->sishw_ext.pjVirtualRomBase[0xe6];
+          v2 = ivideo->sishw_ext.pjVirtualRomBase[0xe7];
+       } else {
+          inSISIDXREG(SISSR,0x3a,reg);
+          if((reg & 0x30) == 0x30) {
+             v1 = 0x04; /* PCI */
+             v2 = 0x92;
+          } else {
+             v1 = 0x14; /* AGP */
+             v2 = 0xb2;
+          }
+       }
+       outSISIDXREG(SISSR,0x21,v1);
+       outSISIDXREG(SISSR,0x22,v2);
+}
 #endif
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-                               strcpy(sis_fb_info->modename, b->name);
-#else                          
-                               strcpy(myid, b->name);
-#endif                         
-                               ivideo.chip_id = pdev->device;
-                               pci_read_config_byte(pdev, PCI_REVISION_ID,
-                                                    &ivideo.revision_id);
-                               pci_read_config_word(pdev, PCI_COMMAND, &reg16);
-                               sishw_ext.jChipRevision = ivideo.revision_id;
-                               sisvga_enabled = reg16 & 0x01;
-                               ivideo.pcibus = pdev->bus->number;
-                               ivideo.pcislot = PCI_SLOT(pdev->devfn);
-                               ivideo.pcifunc = PCI_FUNC(pdev->devfn);
-                               ivideo.subsysvendor = pdev->subsystem_vendor;
-                               ivideo.subsysdevice = pdev->subsystem_device;
-                               break;
-                       }
-               }
 
-               if (pdev_valid)
-                       break;
+#ifdef CONFIG_FB_SIS_315
+static void __devinit sisfb_post_sis315330(struct pci_dev *pdev)
+{
+#ifdef YET_TO_BE_DONE
+       struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+       u8  reg, v1, v2, v3, v4, v5, v6, v7, v8;
+       u16 index, rindex, memtype = 0;
+       u32 reg1_32, reg2_32, reg3_32;
+       int i;
+
+       /* Unlock */
+       /* outSISIDXREG(0x3c4,0x05,0x86); */
+       outSISIDXREG(SISSR,0x05,0x86);
+
+       /* Enable relocated i/o ports */
+       /* setSISIDXREG(0x3c4,0x20,~0x10,0x20); */
+       setSISIDXREG(SISSR,0x20,~0x10,0x20);
+
+       /* Clear regs */
+       for(i = 0; i < 0x22; i++) {
+          outSISIDXREG(SISSR,(0x06 + i),0x00);
+       }
+       v1 = 0x0d;
+       if( is 330) v1 = 0x0b;
+       for(i = 0; i < v1; i++) {
+          outSISIDXREG(SISSR,(0x31 + i),0x00);
+       }
+       for(i = 0; i < 0x10; i++) {
+          outSISIDXREG(SISCR,(0x30 + i),0x00);
+       }
+
+       /* Reset clocks */
+       reg = inSISREG(SISMISCR);
+       outSISIDXREG(SISSR,0x28,0x81);
+       outSISIDXREG(SISSR,0x2A,0x00);
+       outSISIDXREG(SISSR,0x29,0xE1);
+       outSISREG(SISMISCW,(reg | 0x0c));
+       outSISIDXREG(SISSR,0x2B,0x81);
+       outSISIDXREG(SISSR,0x2D,0x00);
+       outSISIDXREG(SISSR,0x2C,0xE1);
+       outSISIDXREG(SISSR,0x2E,0x81);
+       outSISIDXREG(SISSR,0x30,0x00);
+       outSISIDXREG(SISSR,0x2F,0xE1);
+       SiS_DDC2Delay(....);
+       outSISREG(SISMISCW,reg);
+
+       /* Get memory type */
+       if(ivideo->sishw_ext.UseROM) {
+          if(ivideo->sishw_ext.pjVirtualRomBase[0x52] & 0x80)) {
+             memtype = ivideo->sishw_ext.pjVirtualRomBase[0x52];
+          } else {
+             inSISIDXREG(SISSR,0x3a,memtype);
+          }
+          memtype &= 0x03;
+          if( is 330 ) {
+             if(memtype <= 1) memtype = 0;
+             else {
+                inSISIDXREG(SISCR,0x5F,reg);
+                reg &= 0x30;
+                switch(reg) {
+                case 0x00: memtype = 1; break;
+                case 0x10: memtype = 3; break;
+                case 0x20: memtype = 3; break;
+                default:   memtype = 2;
+                }
+             }
+          }
        }
 
-       if (!pdev_valid)
-               return -ENODEV;
+       /* Set clocks */
+       v1 = 0x3b; v2 = 0x22; v3 = 0x01;  /* Assume 143Mhz MCLK */
+       v4 = 0x5c; v5 = 0x23; v6 = 0x01;  /* Assume 166Mhz ECLK */
+       if(ivideo->sishw_ext.UseROM) {
+          index = memtype * 5;
+          rindex = index + 0x54;
+          v1 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+          v2 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+          v3 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+          rindex = index + 0x68;
+          v4 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+          v5 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+          v6 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+       }
+       outSISIDXREG(SISSR,0x28,v1);
+       outSISIDXREG(SISSR,0x29,v2);
+       outSISIDXREG(SISSR,0x2a,v3);
+       if( is 330 ) {
+          inSISIDXREG(SISSR,0x3a,reg);
+          reg &= 0x03;
+          if(reg >= 2) {
+             ...
+          }
+       }
+       outSISIDXREG(SISSR,0x2e,v4);
+       outSISIDXREG(SISSR,0x2f,v5);
+       outSISIDXREG(SISSR,0x30,v6);
+
+       /* End of comp with 330 */
+
+       v1 = 0x18;
+       if(ivideo->sishw_ext.UseROM) v1 = ivideo->sishw_ext.pjVirtualRomBase[0x7c];
+       outSISIDXREG(SISSR,0x07,v1);
+       outSISIDXREG(SISSR,0x11,0x0f);
+
+       v1 = 0x00; v2 = 0x0f; v3 = 0xba; v4 = 0xa9;
+       v5 = 0xa0; v6 = 0x00; v7 = 0x30;
+       if(ivideo->sishw_ext.UseROM) {
+          index = memtype + 0x7d;
+          v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
+          v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
+          v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
+          v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
+          v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
+          v6 = ivideo->sishw_ext.pjVirtualRomBase[index + 20];
+          v7 = ivideo->sishw_ext.pjVirtualRomBase[index + 24];
+       }
+       outSISIDXREG(SISSR,0x15,v1);       /* Ram type (assuming 0, BIOS 0x7d step 4) */
+       outSISIDXREG(SISSR,0x16,v2);
+       outSISIDXREG(SISSR,0x17,v3);
+       outSISIDXREG(SISSR,0x18,v4);
+       outSISIDXREG(SISSR,0x19,v5);
+       outSISIDXREG(SISSR,0x1a,v6);
+       outSISIDXREG(SISSR,0x1b,v7);
+       outSISIDXREG(SISSR,0x1c,v8);       /* ---- */
+
+       v1 = 0x77; v2 = 0x77; v3 = 0x00; v4 = 0x5b; v5 = 0x00;
+       if(ivideo->sishw_ext.UseROM) {
+          index = memtype + 0xa2;
+          v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
+          v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
+          v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
+          v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
+          v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
+       }
+       outSISIDXREG(SISCR,0x40,v1);
+       outSISIDXREG(SISCR,0x41,v2);
+       outSISIDXREG(SISCR,0x42,v3);
+       outSISIDXREG(SISCR,0x43,v4);
+       outSISIDXREG(SISCR,0x44,v5);
+
+       if( is 330 ) {
+
+          v1 = 0x;
+          if(ivideo->sishw_ext.UseROM) {
+             v1 = ivideo->sishw_ext.pjVirtualRomBase[0xBA];
+          }
+          outSISIDXREG(SISCR,0x59,v1);
+
+          v1 = 0x; v2 = 0x; v3 = 0x; v4 = 0x;
+          v5 = 0x; v6 = 0x; v7 = 0x; v8 = 0x;
+          if(ivideo->sishw_ext.UseROM) {
+             index = memtype + 0xbe;
+             v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
+             v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
+             v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
+             v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
+             v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
+             v6 = ivideo->sishw_ext.pjVirtualRomBase[index + 20];
+             v7 = ivideo->sishw_ext.pjVirtualRomBase[index + 24];
+             v8 = ivideo->sishw_ext.pjVirtualRomBase[index + 28];
+          }
+          outSISIDXREG(SISCR,0x68,v1);
+          outSISIDXREG(SISCR,0x69,v2);
+          outSISIDXREG(SISCR,0x6a,v3);
+          outSISIDXREG(SISCR,0x6b,v4);
+          outSISIDXREG(SISCR,0x6c,v5);
+          outSISIDXREG(SISCR,0x6d,v6);
+          outSISIDXREG(SISCR,0x6e,v7);
+          outSISIDXREG(SISCR,0x6f,v8);
+
+          v1 = 0x20;
+          inSISIDXREG(SISSR,0x3b,reg);
+
+          if(!(reg & 0x04)) {
+             inSISIDXREG(SISCR,0x5F,reg);
+             reg &= 0x30;
+             if(reg) v1 = 0x23;
+          }
+          outSISIDXREG(SISCR,0x48,v1);
+          outSISIDXREG(SISCR,0x4c,0x20);
+
+          xx= xxx();
+          if(xx >= 1) {
+             v1 = 0x;
+             if(ivideo->sishw_ext.UseROM) {
+                v1 = ivideo->sishw_ext.pjVirtualRomBase[0xBA];
+             }
+             outSISIDXREG(SISCR,0x59,v1);
+          }
+
+
+
+       } else {
+
+          outSISIDXREG(SISCR,0x48,0x23);
+
+          andSISIDXREG(SISSR,0x16,0x0f);
+          if(memtype <= 1) {
+             orSISIDXREG(SISSR,0x16,0x80);
+          } else {
+             v1 = 0x0f;
+             if(ivideo->sishw_ext.UseROM) {
+                v1 = ivideo->sishw_ext.pjVirtualRomBase[0x81 + memtype];
+             }
+             if(!(v1 & 0x10)) v2 = 0xc0;
+             else             v2 = 0xd0;
+             orSISIDXREG(SISSR,0x16,v2);
+             andSISIDXREG(SISSR,0x16,0x0f);
+             if(!(v1 & 0x10)) v2 = 0x80;
+             else             v2 = 0xA0;
+             orSISIDXREG(SISSR,0x16,v2);
+          }
+
+          if(memtype >= 2) {
+             const u8 sr3cseq1[] = { 0xc0,0xe0,0xf0,0xe0,0xf0,0xa0,0xb0,0xa0,0xb0,0x90,0xd0 };
+             const u8 sr3cseq2[] = { 0xc0,0xa0,0xb0,0xa0,0xb0,0xe0,0xf0,0xa0,0xb0,0x90,0xd0 };
+             for(i = 0; i < 11; i++) {
+                outSISIDXREG(SISSR,0x3c,sr3cseq1[i]);
+             }
+             outSISIDXREG(SISSR,0x3d,0x00);
+             outSISIDXREG(SISSR,0x3d,0x04);
+             SiS_DDC2Delay(0x200);
+             v1 = inSISIDXREG(SISCR,0xEC);
+             v2 = inSISIDXREG(SISCR,0xED);
+             reg1_32 = (v2 << 8) | v1;
+             outSISIDXREG(SISSR,0x3D,0x00);
+             for(i = 0; i < 11; i++) {
+                outSISIDXREG(SISSR,0x3c,sr3cseq2[i]);
+             }
+             outSISIDXREG(SISSR,0x3d,0x00);
+             outSISIDXREG(SISSR,0x3d,0x04);
+             SiS_DDC2Delay(0x200);
+             v1 = inSISIDXREG(SISCR,0xEC);
+             v2 = inSISIDXREG(SISCR,0xED);
+             reg2_32 = (v2 << 8) | v1;
+             outSISIDXREG(SISSR,0x3D,0x00);
+             reg3_32 = reg2_32 << 1;
+             reg2_32 >>= 1;
+             reg3_32 += reg2_32;
+             v1 = 0x40;
+             if(reg3_32 > reg1_32) v1 = 0x10;
+                outSISIDXREG(SISCR,0x59,v1);
+          }
+
+       }
+
+       v1 = 0x00;
+       if(ivideo->sishw_ext.UseROM) {
+          v1 = ivideo->sishw_ext.pjVirtualRomBase[0x99];
+       }
+       outSISIDXREG(SISSR,0x1f,v1);
+
+       outSISIDXREG(SISSR,0x20,0x20);
+
+       v1 = 0xf6; v2 = 0x0d; v3 = 0x33;
+       if(ivideo->sishw_ext.UseROM) {
+          v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9c];
+          v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9d];
+          v3 = ivideo->sishw_ext.pjVirtualRomBase[0x9e];
+       }
+       outSISIDXREG(SISSR,0x23,v1);
+       outSISIDXREG(SISSR,0x24,v2);
+       outSISIDXREG(SISSR,0x25,v3);
+
+       outSISIDXREG(SISSR,0x21,0x84);
+       outSISIDXREG(SISSR,0x22,0x00);
+       outSISIDXREG(SISSR,0x27,0x1f);
+
+       v1 = 0x00; v2 = 0x00;
+       if(ivideo->sishw_ext.UseROM) {
+          v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9F];
+          v2 = ivideo->sishw_ext.pjVirtualRomBase[0xA1];
+       }
+       outSISIDXREG(SISSR,0x31,v1);
+       outSISIDXREG(SISSR,0x33,v2);
+
+       v1 = 0x11;
+       if(ivideo->sishw_ext.UseROM) {
+          v1 = ivideo->sishw_ext.pjVirtualRomBase[0xA0];
+       }
+       v2 = inSISIDXREG(SISPART4,0x00);
+       if((v2 != 1) && (v2 != 2)) v1 &= 0xef;
+       outSISIDXREG(SISSR,0x32,v1);
+
+       /* AGP */
+       pci_read_config_long(pdev, 0x50, &reg1_32);
+       reg1_32 >>= 20;
+       reg1_32 &= 0x0f;
+       if(reg1_32 == 1) {
+          v1 = 0xAA; v2 = 0x33;
+          if(ivideo->sishw_ext.UseROM) {
+             v1 = ivideo->sishw_ext.pjVirtualRomBase[0xF7];
+             v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9E];
+          }
+       } else {
+          v1 = 0x88; v2 = 0x03;
+          if(ivideo->sishw_ext.UseROM) {
+             v1 = ivideo->sishw_ext.pjVirtualRomBase[0xF8];
+             v2 = ivideo->sishw_ext.pjVirtualRomBase[0xF6];
+          }
+       }
+       outSISIDXREG(SISCR,0x49,v1);
+       outSISIDXREG(SISSR,0x25,v2);
+
+       v1 = inSISIDXREG(SISPART4,0x00);
+       if((v1 == 1) || (v1 == 2)) {
+          orSISIDXREG(SISPART1,0x2F,0x01);  /* Unlock CRT2 */
+          outSISIDXREG(SISPART1,0x00,0x00);
+          v1 = 0x00;
+          if(ivideo->sishw_ext.UseROM) {
+             v1 = ivideo->sishw_ext.pjVirtualRomBase[0xb6];
+          }
+          outSISIDXREG(SISPART1,0x02,v1);
+          outSISIDXREG(SISPART1,0x2E,0x08);
+          outSISIDXREG(SISPART2,0x00,0x1c);
+          v1 = 0x40; v2 = 0x00; v3 = 0x80;
+          if(ivideo->sishw_ext.UseROM) {
+             v1 = ivideo->sishw_ext.pjVirtualRomBase[0xb7];
+             v2 = ivideo->sishw_ext.pjVirtualRomBase[0xb8];
+             v3 = ivideo->sishw_ext.pjVirtualRomBase[0xbb];
+          }
+          outSISIDXREG(SISPART4,0x0d,v1);
+          outSISIDXREG(SISPART4,0x0e,v2);
+          outSISIDXREG(SISPART4,0x10,v3);
+          outSISIDXREG(SISPART4,0x0F,0x3F);
+
+          inSISIDXREG(SISPART4,0x01,reg);
+          if(reg >= 0xb0) {
+             inSISIDXREG(SISPART4,0x23,reg);
+             reg &= 0x20;
+             reg <<= 1;
+             outSISIDXREG(SISPART4,0x23,reg);
+          }
+       }
+       outSISIDXREG(SISCR,0x37,0x02); /* Why? */
+
+       outSISIDXREG(SISCR,0x83,0x00);
+       outSISIDXREG(SISCR,0x90,0x00);
+       andSISIDXREG(SISSR,0x5B,0xDF);
+       outSISIDXREG(SISVID,0x00,0x86);
+       outSISIDXREG(SISVID,0x32,0x00);
+       outSISIDXREG(SISVID,0x30,0x00);
+       outSISIDXREG(SISVID,0x32,0x01);
+       outSISIDXREG(SISVID,0x30,0x00);
+       orSISIDXREG(SISCR,0x63,0x80);
+       /* End of Init1 */
+
+       /* Set Mode 0x2e */
+
+       /* Ramsize */
+       orSISIDXREG(SISSR,0x16,0x0f);
+       orSISIDXREG(SISSR,0x18,0xA9);
+       orSISIDXREG(SISSR,0x19,0xA0);
+       orSISIDXREG(SISSR,0x1B,0x30);
+       andSISIDXREG(SISSR,0x17,0xF8);
+       orSISIDXREG(SISSR,0x19,0x03);
+       andSIDIDXREG(SISSR,0x13,0x00);
+
+       /* Need to map max FB size for finding out about RAM size */
+       ivideo->sishw_ext.pjVideoMemoryAddress = ioremap(ivideo->video_base, 0x4000000);
+       if(ivideo->sishw_ext.pjVideoMemoryAddress) {
+          /* Find out about bus width */
+          if(memtype <= 1) {
+             outSISIDXREG(SISSR,0x14,0x02);
+             andSISIDXREG(SISSR,0x16,0x0F);
+             orSISIDXREG(SISSR,0x16,0x80);
+
+             ...
+
+          } else {
+
+             ...
+
+          }
+
+          /* Find out about size */
+
+
+          iounmap(ivideo->sishw_ext.pjVideoMemoryAddress);
+       } else {
+          printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
+          outSISIDXREG(SISSR,0x14,0x??);  /* 8MB, 64bit default */
+       }
+
+       /* AGP (Missing: Checks for VIA and AMD hosts) */
+       v1 = 0xA5; v2 = 0xFB;
+       if(ivideo->sishw_ext.UseROM) {
+          v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9A];
+          v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9B];
+       }
+       outSISIDXREG(SISSR,0x21,v1);
+       outSISIDXREG(SISSR,0x22,v2);
 
-       switch (ivideo.chip_id) {
-#ifdef CONFIG_FB_SIS_300
-          case PCI_DEVICE_ID_SI_300:
-               ivideo.chip = SIS_300;
-               sisvga_engine = SIS_300_VGA;
-               sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300 * 2;  /* New X driver uses 2 buffers */
-               sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
-               break;
-          case PCI_DEVICE_ID_SI_630_VGA:
-               {
-                       ivideo.chip = SIS_630;
-                       sisfb_set_reg4(0xCF8, 0x80000000);
-                       reg32 = sisfb_get_reg3(0xCFC);
-                       if(reg32 == 0x07301039) {
-                               ivideo.chip = SIS_730;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-                               strcpy(sis_fb_info->modename, "SIS 730");
-#else
-                               strcpy(myid, "SIS 730");
-#endif
-                       }
-                       sisvga_engine = SIS_300_VGA;
-                       sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300 * 2;
-                       sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
-                       break;
-               }
-          case PCI_DEVICE_ID_SI_540_VGA:
-               ivideo.chip = SIS_540;
-               sisvga_engine = SIS_300_VGA;
-               sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300 * 2;
-               sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
-               break;
-#endif
-#ifdef CONFIG_FB_SIS_315
-          case PCI_DEVICE_ID_SI_315H:
-               ivideo.chip = SIS_315H;
-               sisvga_engine = SIS_315_VGA;
-               sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
-               sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
-               break;
-          case PCI_DEVICE_ID_SI_315:
-               ivideo.chip = SIS_315;
-               sisvga_engine = SIS_315_VGA;
-               sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
-               sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
-               break;
-          case PCI_DEVICE_ID_SI_315PRO:
-               ivideo.chip = SIS_315PRO;
-               sisvga_engine = SIS_315_VGA;
-               sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
-               sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
-               break;
-          case PCI_DEVICE_ID_SI_550_VGA:
-               ivideo.chip = SIS_550;
-               sisvga_engine = SIS_315_VGA;
-               sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
-               sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
-               break;
-          case PCI_DEVICE_ID_SI_650_VGA:
-               {
-                       ivideo.chip = SIS_650;  
-                       sisfb_set_reg4(0xCF8, 0x80000000);
-                       reg32 = sisfb_get_reg3(0xCFC);
-                       if(reg32 == 0x07401039) {
-                               ivideo.chip = SIS_740;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-                               strcpy(sis_fb_info->modename, "SIS 740");
-#else
-                               strcpy(myid, "SIS 740");
-#endif
-                       }
-                       sisvga_engine = SIS_315_VGA;
-                       sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
-                       sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
-                       break;
-               }
-          case PCI_DEVICE_ID_SI_330:
-               ivideo.chip = SIS_330;
-               sisvga_engine = SIS_315_VGA;
-               sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
-               sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
-               break;
-          case PCI_DEVICE_ID_SI_660_VGA:
-               {
-                       sisfb_set_reg4(0xCF8, 0x80000000);
-                       reg32 = sisfb_get_reg3(0xCFC);
-                       if(reg32 == 0x07601039) {
-                               ivideo.chip = SIS_760;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-                               strcpy(sis_fb_info->modename, "SIS 760");
-#else
-                               strcpy(myid, "SIS 760");
 #endif
-                       } else if(reg32 == 0x06601039) {
-                               ivideo.chip = SIS_660;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-                               strcpy(sis_fb_info->modename, "SIS 660");
-#else
-                               strcpy(myid, "SIS 660");
+       return;
+}
 #endif
-                       } else if(reg32 == 0x07411039) {
-                               ivideo.chip = SIS_741;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-                               strcpy(sis_fb_info->modename, "SIS 741");
+
+
+int __devinit sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+       struct sisfb_chip_info  *chipinfo = &sisfb_chip_info[ent->driver_data];
+       struct sis_video_info   *ivideo = NULL;
+       struct fb_info          *sis_fb_info = NULL;
+       u16 reg16;
+       u8  reg;
+       int sisvga_enabled = 0, i;
+
+       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
-                               strcpy(myid, "SIS 741");
+       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
-                       } else {
-                               ivideo.chip = SIS_661;
+
+       ivideo = (struct sis_video_info *)sis_fb_info->par;
+       ivideo->memyselfandi = sis_fb_info;
+
+       if(card_list == NULL) {
+          ivideo->cardnumber = 0;
+       } else {
+          struct sis_video_info *countvideo = card_list;
+          ivideo->cardnumber = 1;
+          while ((countvideo = countvideo->next) != NULL) ivideo->cardnumber++;
+       }
+
+       strncpy(ivideo->myid, chipinfo->chip_name, 30);
+
+       ivideo->chip_id = pdev->device;
+       pci_read_config_byte(pdev, PCI_REVISION_ID, &ivideo->revision_id);
+       ivideo->sishw_ext.jChipRevision = ivideo->revision_id;
+       pci_read_config_word(pdev, PCI_COMMAND, &reg16);
+       sisvga_enabled = reg16 & 0x01;
+       ivideo->pcibus = pdev->bus->number;
+       ivideo->pcislot = PCI_SLOT(pdev->devfn);
+       ivideo->pcifunc = PCI_FUNC(pdev->devfn);
+       ivideo->subsysvendor = pdev->subsystem_vendor;
+       ivideo->subsysdevice = pdev->subsystem_device;
+#ifdef SIS_CONFIG_COMPAT
+       ivideo->ioctl32registered = 0;
+       ivideo->ioctl32vblankregistered = 0;
+#endif
+
+#ifndef MODULE
+       if(sisfb_mode_idx == -1) {
+               sisfb_get_vga_mode_from_kernel();
+       }
+#endif
+
+       ivideo->chip = chipinfo->chip;
+       ivideo->sisvga_engine = chipinfo->vgaengine;
+       ivideo->hwcursor_size = chipinfo->hwcursor_size;
+       ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable;
+       ivideo->mni = chipinfo->mni;
+
+       ivideo->detectedpdc  = 0xff;
+       ivideo->detectedpdca = 0xff;
+       ivideo->detectedlcda = 0xff;
+
+       ivideo->sisfb_thismonitor.datavalid = FALSE;
+
+       ivideo->sisfb_parm_mem = sisfb_parm_mem;
+       ivideo->sisfb_accel = sisfb_accel;
+       ivideo->sisfb_ypan = sisfb_ypan;
+       ivideo->sisfb_max = sisfb_max;
+       ivideo->sisfb_userom = sisfb_userom;
+       ivideo->sisfb_useoem = sisfb_useoem;
+       ivideo->sisfb_mode_idx = sisfb_mode_idx;
+       ivideo->sisfb_parm_rate = sisfb_parm_rate;
+       ivideo->sisfb_crt1off = sisfb_crt1off;
+       ivideo->sisfb_forcecrt1 = sisfb_forcecrt1;
+       ivideo->sisfb_crt2type = sisfb_crt2type;
+       ivideo->sisfb_crt2flags = sisfb_crt2flags;
+       /* pdc(a), scalelcd, special timing, lvdshl handled below */
+       ivideo->sisfb_dstn = sisfb_dstn;
+       ivideo->sisfb_fstn = sisfb_fstn;
+       ivideo->sisfb_tvplug = sisfb_tvplug;
+       ivideo->sisfb_tvstd = sisfb_tvstd;
+       ivideo->tvxpos = sisfb_tvxposoffset;
+       ivideo->tvypos = sisfb_tvyposoffset;
+       ivideo->sisfb_filter = sisfb_filter;
+       ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate;
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-                               strcpy(sis_fb_info->modename, "SIS 661");
-#else
-                               strcpy(myid, "SIS 661");
+       ivideo->sisfb_inverse = sisfb_inverse;
 #endif
-                       }
-                       sisvga_engine = SIS_315_VGA;
-                       sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
-                       sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
+
+       ivideo->refresh_rate = 0;
+       if(ivideo->sisfb_parm_rate != -1) {
+          ivideo->refresh_rate = ivideo->sisfb_parm_rate;
+       }
+
+       ivideo->SiS_Pr.UsePanelScaler = sisfb_scalelcd;
+       ivideo->SiS_Pr.CenterScreen = -1;
+       ivideo->SiS_Pr.SiS_CustomT = sisfb_specialtiming;
+       ivideo->SiS_Pr.LVDSHL = sisfb_lvdshl;
+
+       ivideo->SiS_Pr.SiS_Backup70xx = 0xff;
+        ivideo->SiS_Pr.SiS_CHOverScan = -1;
+        ivideo->SiS_Pr.SiS_ChSW = FALSE;
+       ivideo->SiS_Pr.SiS_UseLCDA = FALSE;
+       ivideo->SiS_Pr.HaveEMI = FALSE;
+       ivideo->SiS_Pr.HaveEMILCD = FALSE;
+       ivideo->SiS_Pr.OverruleEMI = FALSE;
+       ivideo->SiS_Pr.SiS_SensibleSR11 = FALSE;
+       ivideo->SiS_Pr.SiS_MyCR63 = 0x63;
+       ivideo->SiS_Pr.PDC  = -1;
+       ivideo->SiS_Pr.PDCA = -1;
+#ifdef CONFIG_FB_SIS_315
+       if(ivideo->chip >= SIS_330) {
+          ivideo->SiS_Pr.SiS_MyCR63 = 0x53;
+          if(ivideo->chip >= SIS_661) {
+             ivideo->SiS_Pr.SiS_SensibleSR11 = TRUE;
+          }
+       }
+#endif
+
+       memcpy(&ivideo->default_var, &my_default_var, sizeof(my_default_var));
+
+       pci_set_drvdata(pdev, ivideo);
+
+       /* Patch special cases */
+       if((ivideo->nbridge = sisfb_get_northbridge(ivideo->chip))) {
+               switch(ivideo->nbridge->device) {
+#ifdef CONFIG_FB_SIS_300
+               case PCI_DEVICE_ID_SI_730:
+                       ivideo->chip = SIS_730;
+                       strcpy(ivideo->myid, "SiS 730");
+                       break;
+#endif
+#ifdef CONFIG_FB_SIS_315
+               case PCI_DEVICE_ID_SI_651:
+                       /* ivideo->chip is ok */
+                       strcpy(ivideo->myid, "SiS 651");
+                       break;
+               case PCI_DEVICE_ID_SI_740:
+                       ivideo->chip = SIS_740;
+                       strcpy(ivideo->myid, "SiS 740");
+                       break;
+               case PCI_DEVICE_ID_SI_661:
+                       ivideo->chip = SIS_661;
+                       strcpy(ivideo->myid, "SiS 661");
+                       break;
+               case PCI_DEVICE_ID_SI_741:
+                       ivideo->chip = SIS_741;
+                       strcpy(ivideo->myid, "SiS 741");
+                       break;
+               case PCI_DEVICE_ID_SI_760:
+                       ivideo->chip = SIS_760;
+                       strcpy(ivideo->myid, "SiS 760");
                        break;
-               }
 #endif
-           default:
-               kfree(sis_fb_info);
-               return -ENODEV;
+               }
        }
-       sishw_ext.jChipType = ivideo.chip;
 
-       /* for Debug */
-       if( (sishw_ext.jChipType == SIS_315PRO) ||
-           (sishw_ext.jChipType == SIS_315) )
-               sishw_ext.jChipType = SIS_315H;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+       strcpy(sis_fb_info->modename, ivideo->myid);
+#endif
+
+       ivideo->sishw_ext.jChipType = ivideo->chip;
 
-       ivideo.video_base = pci_resource_start(pdev, 0);
-       ivideo.mmio_base = pci_resource_start(pdev, 1);
-       sishw_ext.ulIOAddress = SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
-       ivideo.vga_base = (unsigned short) sishw_ext.ulIOAddress;
+#ifdef CONFIG_FB_SIS_315
+       if((ivideo->sishw_ext.jChipType == SIS_315PRO) ||
+          (ivideo->sishw_ext.jChipType == SIS_315)) {
+               ivideo->sishw_ext.jChipType = SIS_315H;
+       }
+#endif
 
-       sisfb_mmio_size =  pci_resource_len(pdev, 1);
+       ivideo->video_base = pci_resource_start(pdev, 0);
+       ivideo->mmio_base  = pci_resource_start(pdev, 1);
+       ivideo->mmio_size  = pci_resource_len(pdev, 1);
+       ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
+       ivideo->sishw_ext.ulIOAddress = ivideo->vga_base = ivideo->SiS_Pr.RelIO;
 
        if(!sisvga_enabled) {
-          if(pci_enable_device(pdev)) {
-             kfree(sis_fb_info);
-             return -EIO;
-          }
+               if(pci_enable_device(pdev)) {
+                       pci_set_drvdata(pdev, NULL);
+                       kfree(sis_fb_info);
+                       return -EIO;
+               }
        }
 
-       SiS_Pr.SiS_Backup70xx = 0xff;
-        SiS_Pr.SiS_CHOverScan = -1;
-        SiS_Pr.SiS_ChSW = FALSE;
-       SiS_Pr.SiS_UseLCDA = FALSE;
-       SiS_Pr.HaveEMI = FALSE;
-       SiS_Pr.HaveEMILCD = FALSE;
-       SiS_Pr.OverruleEMI = FALSE;
-       SiS_Pr.SiS_SensibleSR11 = FALSE;
-       SiS_Pr.SiS_MyCR63 = 0x63;
-       if(ivideo.chip >= SIS_661) {
-          SiS_Pr.SiS_SensibleSR11 = TRUE;
-          SiS_Pr.SiS_MyCR63 = 0x53;
-       }
-       SiSRegInit(&SiS_Pr, sishw_ext.ulIOAddress);
+       SiSRegInit(&ivideo->SiS_Pr, ivideo->sishw_ext.ulIOAddress);
 
 #ifdef CONFIG_FB_SIS_300
-       /* TW: Find PCI systems for Chrontel/GPIO communication setup */
-       if(ivideo.chip == SIS_630) {
-          int i=0;
+       /* Find PCI systems for Chrontel/GPIO communication setup */
+       if(ivideo->chip == SIS_630) {
+          i=0;
            do {
-             if(mychswtable[i].subsysVendor == ivideo.subsysvendor &&
-                mychswtable[i].subsysCard   == ivideo.subsysdevice) {
-                SiS_Pr.SiS_ChSW = TRUE;
+             if(mychswtable[i].subsysVendor == ivideo->subsysvendor &&
+                mychswtable[i].subsysCard   == ivideo->subsysdevice) {
+                ivideo->SiS_Pr.SiS_ChSW = TRUE;
                 printk(KERN_DEBUG "sisfb: Identified [%s %s] requiring Chrontel/GPIO setup\n",
                        mychswtable[i].vendorName, mychswtable[i].cardName);
                 break;
@@ -4361,14 +4939,41 @@ int __init sisfb_init(void)
        }
 #endif
 
-        outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+        outSISIDXREG(SISSR, 0x05, 0x86);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)         
-#ifdef MODULE
+       if( (!sisvga_enabled)
+#if !defined(__i386__) && !defined(__x86_64__)
+                             || (sisfb_resetcard)
+#endif
+                                                  ) {
+               for(i = 0x30; i <= 0x3f; i++) {
+                       outSISIDXREG(SISCR,i,0x00);
+               }
+       }
+
+       /* Find out about current video mode */
        inSISIDXREG(SISCR,0x34,reg);
+       if(reg & 0x7f) {
+               ivideo->modeprechange = reg & 0x7f;
+       } else {
+               ivideo->modeprechange = 0x03;
+#if defined(__i386__) || defined(__x86_64__)
+               {
+                       unsigned char *tt = ioremap(0, 0x1000);
+                       if(tt) {
+                               ivideo->modeprechange = tt[0x449];
+                               iounmap(tt);
+                       }
+               }
+#endif
+       }
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#ifdef MODULE
        if((reg & 0x80) && (reg != 0xff)) {
-          if((sisbios_mode[sisfb_mode_idx].mode_no) != 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");
+             pci_set_drvdata(pdev, NULL);
              kfree(sis_fb_info);
              return -EBUSY;
           }
@@ -4376,96 +4981,82 @@ int __init sisfb_init(void)
 #endif 
 #endif
 
-       if (sisvga_engine == SIS_315_VGA) {
-               switch (ivideo.chip) {
-                  case SIS_315H:
-                  case SIS_315:
-                  case SIS_330:
-                       sishw_ext.bIntegratedMMEnabled = TRUE;
-                       break;
-                  case SIS_550:
-                  case SIS_650:
-                  case SIS_740:
-                  case SIS_661:
-                  case SIS_741:
-                  case SIS_660:
-                  case SIS_760:
-                       sishw_ext.bIntegratedMMEnabled = TRUE;
-                       break;
-                  default:
-                       break;
-               }
-       } else if (sisvga_engine == SIS_300_VGA) {
-               if (ivideo.chip == SIS_300) {
-                       sishw_ext.bIntegratedMMEnabled = TRUE;
-               } else {
-                       inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_1A, reg);
-                       if (reg & SIS_SCRATCH_REG_1A_MASK)
-                               sishw_ext.bIntegratedMMEnabled = TRUE;
-                       else
-                               sishw_ext.bIntegratedMMEnabled = FALSE;
-               }
+       ivideo->sishw_ext.bIntegratedMMEnabled = TRUE;
+#ifdef CONFIG_FB_SIS_300
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
+          if(ivideo->chip != SIS_300) {
+             inSISIDXREG(SISSR, 0x1a, reg);
+             if(!(reg & 0x10)) {
+                ivideo->sishw_ext.bIntegratedMMEnabled = FALSE;
+             }
+          }
        }
+#endif
 
-       if(sisfb_userom) {
-           sishw_ext.pjVirtualRomBase = sis_find_rom();
-           if(sishw_ext.pjVirtualRomBase) {
-               printk(KERN_INFO "sisfb: Video ROM found and mapped to %p\n",
-                       sishw_ext.pjVirtualRomBase);
-               sishw_ext.UseROM = TRUE;
+       ivideo->bios_vbase = ivideo->bios_abase = NULL;
+       if(ivideo->sisfb_userom) {
+           ivideo->sishw_ext.pjVirtualRomBase = sis_find_rom(pdev);
+#if defined(__i386__) || defined(__x86_64__)
+           ivideo->bios_vbase = ivideo->sishw_ext.pjVirtualRomBase;    /* mapped */
+#else
+           ivideo->bios_abase = ivideo->sishw_ext.pjVirtualRomBase;    /* allocated */
+#endif
+           if(ivideo->sishw_ext.pjVirtualRomBase) {
+               printk(KERN_INFO "sisfb: Video ROM found and %s to 0x%p\n",
+                       ivideo->bios_vbase ? "mapped" : "copied",
+                       ivideo->sishw_ext.pjVirtualRomBase);
+               ivideo->sishw_ext.UseROM = TRUE;
            } else {
-               sishw_ext.UseROM = FALSE;
+               ivideo->sishw_ext.UseROM = FALSE;
                printk(KERN_INFO "sisfb: Video ROM not found\n");
            }
        } else {
-           sishw_ext.pjVirtualRomBase = NULL;
-           sishw_ext.UseROM = FALSE;
+           ivideo->sishw_ext.pjVirtualRomBase = NULL;
+           ivideo->sishw_ext.UseROM = FALSE;
            printk(KERN_INFO "sisfb: Video ROM usage disabled\n");
        }
-       sishw_ext.bSkipDramSizing = 0;
-       sishw_ext.pQueryVGAConfigSpace = &sisfb_query_VGA_config_space;
-       sishw_ext.pQueryNorthBridgeSpace = &sisfb_query_north_bridge_space;
 
         /* Find systems for special custom timing */
-       if(SiS_Pr.SiS_CustomT == CUT_NONE) {
-          int i=0, j;
+       if(ivideo->SiS_Pr.SiS_CustomT == CUT_NONE) {
+          int j;
           unsigned char *biosver = NULL;
            unsigned char *biosdate = NULL;
           BOOLEAN footprint;
-          unsigned long chksum = 0;
+          u32 chksum = 0;
 
-          if(sishw_ext.UseROM) {
-             biosver = sishw_ext.pjVirtualRomBase + 0x06;
-             biosdate = sishw_ext.pjVirtualRomBase + 0x2c;
-              for(i=0; i<32768; i++) chksum += sishw_ext.pjVirtualRomBase[i];
+          if(ivideo->sishw_ext.UseROM) {
+             biosver = ivideo->sishw_ext.pjVirtualRomBase + 0x06;
+             biosdate = ivideo->sishw_ext.pjVirtualRomBase + 0x2c;
+              for(i=0; i<32768; i++) chksum += ivideo->sishw_ext.pjVirtualRomBase[i];
           }
 
           i=0;
            do {
-             if( (mycustomttable[i].chipID == ivideo.chip) &&
+             if( (mycustomttable[i].chipID == ivideo->chip) &&
                  ((!strlen(mycustomttable[i].biosversion)) ||
-                  (sishw_ext.UseROM &&
+                  (ivideo->sishw_ext.UseROM &&
                   (!strncmp(mycustomttable[i].biosversion, biosver, strlen(mycustomttable[i].biosversion))))) &&
                  ((!strlen(mycustomttable[i].biosdate)) ||
-                  (sishw_ext.UseROM &&
+                  (ivideo->sishw_ext.UseROM &&
                   (!strncmp(mycustomttable[i].biosdate, biosdate, strlen(mycustomttable[i].biosdate))))) &&
                  ((!mycustomttable[i].bioschksum) ||
-                  (sishw_ext.UseROM &&
+                  (ivideo->sishw_ext.UseROM &&
                   (mycustomttable[i].bioschksum == chksum)))   &&
-                 (mycustomttable[i].pcisubsysvendor == ivideo.subsysvendor) &&
-                 (mycustomttable[i].pcisubsyscard == ivideo.subsysdevice) ) {
+                 (mycustomttable[i].pcisubsysvendor == ivideo->subsysvendor) &&
+                 (mycustomttable[i].pcisubsyscard == ivideo->subsysdevice) ) {
                 footprint = TRUE;
-                for(j=0; j<5; j++) {
+                for(j = 0; j < 5; j++) {
                    if(mycustomttable[i].biosFootprintAddr[j]) {
-                      if(sishw_ext.UseROM) {
-                         if(sishw_ext.pjVirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
-                               mycustomttable[i].biosFootprintData[j])
-                         footprint = FALSE;
+                      if(ivideo->sishw_ext.UseROM) {
+                         if(ivideo->sishw_ext.pjVirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
+                               mycustomttable[i].biosFootprintData[j]) {
+                            footprint = FALSE;
+                         }
                       } else footprint = FALSE;
                    }
                 }
                 if(footprint) {
-                   SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
+                   ivideo->SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
                    printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
                        mycustomttable[i].vendorName,
                        mycustomttable[i].cardName);
@@ -4479,466 +5070,502 @@ int __init sisfb_init(void)
        }
 
 #ifdef CONFIG_FB_SIS_300
-       /* Mode numbers for 1280x768 are different for 300 and 315 series */
-       if(sisvga_engine == SIS_300_VGA) {
-               sisbios_mode[MODEINDEX_1280x768].mode_no = 0x55;
-               sisbios_mode[MODEINDEX_1280x768+1].mode_no = 0x5a;
-               sisbios_mode[MODEINDEX_1280x768+2].mode_no = 0x5b;
-               sisbios_mode[MODEINDEX_1280x768+3].mode_no = 0x5b;
-       }
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
+               if( (!sisvga_enabled)
+#if !defined(__i386__) && !defined(__x86_64__)
+                                     || (sisfb_resetcard)
 #endif
-
-       sishw_ext.pSR = vmalloc(sizeof(SIS_DSReg) * SR_BUFFER_SIZE);
-       if (sishw_ext.pSR == NULL) {
-               printk(KERN_ERR "sisfb: Fatal error: Allocating SRReg space failed.\n");
-               kfree(sis_fb_info);
-               return -ENODEV;
-       }
-       sishw_ext.pSR[0].jIdx = sishw_ext.pSR[0].jVal = 0xFF;
-
-       sishw_ext.pCR = vmalloc(sizeof(SIS_DSReg) * CR_BUFFER_SIZE);
-       if (sishw_ext.pCR == NULL) {
-               vfree(sishw_ext.pSR);
-               printk(KERN_ERR "sisfb: Fatal error: Allocating CRReg space failed.\n");
-               kfree(sis_fb_info);
-               return -ENODEV;
-       }
-       sishw_ext.pCR[0].jIdx = sishw_ext.pCR[0].jVal = 0xFF;
-
-#ifdef CONFIG_FB_SIS_300
-       if(sisvga_engine == SIS_300_VGA) {
-               if(!sisvga_enabled) {
-                       /* Mapping Max FB Size for 300 Init */
-                       sishw_ext.pjVideoMemoryAddress = ioremap(ivideo.video_base, 0x4000000);
-                       if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
-                               outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+                                                          ) {
+                       if(ivideo->chip == SIS_300) {
+                               sisfb_post_sis300(pdev);
                        }
                }
-               if(sisfb_get_dram_size_300()) {
-                       vfree(sishw_ext.pSR);
-                       vfree(sishw_ext.pCR);
-                       printk(KERN_ERR "sisfb: Fatal error: Unable to determine RAM size\n");
-                       kfree(sis_fb_info);
-                       return -ENODEV;
-               }
        }
 #endif
 
 #ifdef CONFIG_FB_SIS_315
-       if (sisvga_engine == SIS_315_VGA) {
-               if (!sisvga_enabled) {
-                       /* Mapping Max FB Size for 315 Init */
-                       sishw_ext.pjVideoMemoryAddress = ioremap(ivideo.video_base, 0x8000000);
-                       if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
-                               outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
-                               sishw_ext.bSkipDramSizing = TRUE;
-                               sishw_ext.pSR[0].jIdx = 0x13;
-                               sishw_ext.pSR[1].jIdx = 0x14;
-                               sishw_ext.pSR[2].jIdx = 0xFF;
-                               inSISIDXREG(SISSR, 0x13, sishw_ext.pSR[0].jVal);
-                               inSISIDXREG(SISSR, 0x14, sishw_ext.pSR[1].jVal);
-                               sishw_ext.pSR[2].jVal = 0xFF;
+       if(ivideo->sisvga_engine == SIS_315_VGA) {
+               if( (!sisvga_enabled)
+#if !defined(__i386__) && !defined(__x86_64__)
+                                    || (sisfb_resetcard)
+#endif
+                                                         ) {
+                       if((ivideo->chip == SIS_315H)   ||
+                          (ivideo->chip == SIS_315)    ||
+                          (ivideo->chip == SIS_315PRO) ||
+                          (ivideo->chip == SIS_330)) {
+                               sisfb_post_sis315330(pdev);
                        }
                }
-               if(sisfb_get_dram_size_315()) {
-                       vfree(sishw_ext.pSR);
-                       vfree(sishw_ext.pCR);
-                       printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size.\n");
-                       kfree(sis_fb_info);
-                       return -ENODEV;
-               }
        }
 #endif
 
-       if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) { 
+       if(sisfb_get_dram_size(ivideo)) {
+               printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size.\n");
+               if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+               pci_set_drvdata(pdev, NULL);
+               kfree(sis_fb_info);
+               return -ENODEV;
+       }
 
+       if((ivideo->sisfb_mode_idx < 0) ||
+          ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
                /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE  */
                orSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
-
                 /* Enable 2D accelerator engine */
                orSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
-
        }
 
-       sishw_ext.ulVideoMemorySize = ivideo.video_size;
-
-       if(sisvga_engine == SIS_300_VGA) sisfb_pdc &= 0x3c;
-       if(sisfb_pdc) {
-           SiS_Pr.PDC = sisfb_pdc;
-       } else {
-           SiS_Pr.PDC = 0;
+       if(sisfb_pdc != 0xff) {
+          if(ivideo->sisvga_engine == SIS_300_VGA) sisfb_pdc &= 0x3c;
+          else                                     sisfb_pdc &= 0x1f;
+          ivideo->SiS_Pr.PDC = sisfb_pdc;
        }
+#ifdef CONFIG_FB_SIS_315
+       if(ivideo->sisvga_engine == SIS_315_VGA) {
+          if(sisfb_pdca != 0xff) ivideo->SiS_Pr.PDCA = sisfb_pdca & 0x1f;
+       }
+#endif
 
-       if(!request_mem_region(ivideo.video_base, ivideo.video_size, "sisfb FB")) {
+       if(!request_mem_region(ivideo->video_base, ivideo->video_size, "sisfb FB")) {
                printk(KERN_ERR "sisfb: Fatal error: Unable to reserve frame buffer memory\n");
                printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n");
-               vfree(sishw_ext.pSR);
-               vfree(sishw_ext.pCR);
+               if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+               if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+               pci_set_drvdata(pdev, NULL);
                kfree(sis_fb_info);
                return -ENODEV;
        }
 
-       if(!request_mem_region(ivideo.mmio_base, sisfb_mmio_size, "sisfb MMIO")) {
+       if(!request_mem_region(ivideo->mmio_base, ivideo->mmio_size, "sisfb MMIO")) {
                printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n");
-               release_mem_region(ivideo.video_base, ivideo.video_size);
-               vfree(sishw_ext.pSR);
-               vfree(sishw_ext.pCR);
+               release_mem_region(ivideo->video_base, ivideo->video_size);
+               if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+               if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+               pci_set_drvdata(pdev, NULL);
                kfree(sis_fb_info);
                return -ENODEV;
        }
 
-       ivideo.video_vbase = sishw_ext.pjVideoMemoryAddress = ioremap(ivideo.video_base, ivideo.video_size);
-       if(!ivideo.video_vbase) {
+       ivideo->video_vbase = (unsigned long)ioremap(ivideo->video_base, ivideo->video_size);
+       ivideo->sishw_ext.pjVideoMemoryAddress = (unsigned char *)ivideo->video_vbase;
+       if(!ivideo->video_vbase) {
                printk(KERN_ERR "sisfb: Fatal error: Unable to map frame buffer memory\n");
-               release_mem_region(ivideo.video_base, ivideo.video_size);
-               release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
-               vfree(sishw_ext.pSR);
-               vfree(sishw_ext.pCR);
+               release_mem_region(ivideo->video_base, ivideo->video_size);
+               release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
+               if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+               if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+               pci_set_drvdata(pdev, NULL);
                kfree(sis_fb_info);
                return -ENODEV;
        }
 
-       ivideo.mmio_vbase = ioremap(ivideo.mmio_base, sisfb_mmio_size);
-       if(!ivideo.mmio_vbase) {
+       ivideo->mmio_vbase = (unsigned long)ioremap(ivideo->mmio_base, ivideo->mmio_size);
+       if(!ivideo->mmio_vbase) {
                printk(KERN_ERR "sisfb: Fatal error: Unable to map MMIO region\n");
-               iounmap(ivideo.video_vbase);
-               release_mem_region(ivideo.video_base, ivideo.video_size);
-               release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
-               vfree(sishw_ext.pSR);
-               vfree(sishw_ext.pCR);
+               iounmap((void *)ivideo->video_vbase);
+               release_mem_region(ivideo->video_base, ivideo->video_size);
+               release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
+               if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+               if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+               pci_set_drvdata(pdev, NULL);
                kfree(sis_fb_info);
                return -ENODEV;
        }
 
-       printk(KERN_INFO "sisfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
-               ivideo.video_base, ivideo.video_vbase, ivideo.video_size / 1024);
+       printk(KERN_INFO "sisfb: Framebuffer at 0x%lx, mapped to 0x%lx, size %ldk\n",
+               ivideo->video_base, ivideo->video_vbase, ivideo->video_size / 1024);
 
-       printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
-               ivideo.mmio_base, ivideo.mmio_vbase, sisfb_mmio_size / 1024);
+       printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%lx, size %ldk\n",
+               ivideo->mmio_base, ivideo->mmio_vbase, ivideo->mmio_size / 1024);
 
-       if(sisfb_heap_init()) {
+       if((ivideo->havenoheap = sisfb_heap_init(ivideo))) {
                printk(KERN_WARNING "sisfb: Failed to initialize offscreen memory heap\n");
        }
 
-       ivideo.mtrr = (unsigned int) 0;
+       /* Used for clearing the screen only, therefore respect our mem limit */
+       ivideo->sishw_ext.ulVideoMemorySize = ivideo->sisfb_mem;
+
+       ivideo->mtrr = 0;
 
-       ivideo.vbflags = 0;
+       ivideo->vbflags = 0;
+       ivideo->lcddefmodeidx = DEFAULT_LCDMODE;
+       ivideo->tvdefmodeidx  = DEFAULT_TVMODE;
+       ivideo->defmodeidx    = DEFAULT_MODE;
 
-       if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
+       ivideo->newrom = SiSDetermineROMLayout661(&ivideo->SiS_Pr, &ivideo->sishw_ext);
 
-               sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
-               sishw_ext.Is301BDH = FALSE;
-               sishw_ext.usExternalChip = 0;
+       if((ivideo->sisfb_mode_idx < 0) ||
+          ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
 
-               sisfb_sense_crt1();
+               sisfb_sense_crt1(ivideo);
 
-               sisfb_get_VB_type();
+               sisfb_get_VB_type(ivideo);
 
-               if(ivideo.vbflags & VB_VIDEOBRIDGE) {
-                       sisfb_detect_VB_connect();
+               if(ivideo->vbflags & VB_VIDEOBRIDGE) {
+                       sisfb_detect_VB_connect(ivideo);
                }
 
-               ivideo.currentvbflags = ivideo.vbflags & VB_VIDEOBRIDGE;
+               ivideo->currentvbflags = ivideo->vbflags & (VB_VIDEOBRIDGE | TV_STANDARD);
 
-               if(ivideo.vbflags & VB_VIDEOBRIDGE) {
-                  if(sisfb_crt2type != -1) {
-                     if((sisfb_crt2type == CRT2_LCD) && (ivideo.vbflags & CRT2_LCD)) {
-                        ivideo.currentvbflags |= CRT2_LCD;
-                     } else if(sisfb_crt2type != CRT2_LCD) {
-                        ivideo.currentvbflags |= sisfb_crt2type;
+               if(ivideo->vbflags & VB_VIDEOBRIDGE) {
+                  if(ivideo->sisfb_crt2type != -1) {
+                     if((ivideo->sisfb_crt2type == CRT2_LCD) && (ivideo->vbflags & CRT2_LCD)) {
+                        ivideo->currentvbflags |= CRT2_LCD;
+                     } else if(ivideo->sisfb_crt2type != CRT2_LCD) {
+                        ivideo->currentvbflags |= ivideo->sisfb_crt2type;
                      }
                   } else {
                      /* Chrontel 700x TV detection often unreliable, therefore use a
                       * different default order on such machines
                       */
-                     if((sisvga_engine == SIS_300_VGA) && (ivideo.vbflags & VB_CHRONTEL)) {
-                        if(ivideo.vbflags & CRT2_LCD)      ivideo.currentvbflags |= CRT2_LCD;
-                        else if(ivideo.vbflags & CRT2_TV)  ivideo.currentvbflags |= CRT2_TV;
-                        else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
+                     if((ivideo->sisvga_engine == SIS_300_VGA) && (ivideo->vbflags & VB_CHRONTEL)) {
+                        if(ivideo->vbflags & CRT2_LCD)      ivideo->currentvbflags |= CRT2_LCD;
+                        else if(ivideo->vbflags & CRT2_TV)  ivideo->currentvbflags |= CRT2_TV;
+                        else if(ivideo->vbflags & CRT2_VGA) ivideo->currentvbflags |= CRT2_VGA;
                      } else {
-                        if(ivideo.vbflags & CRT2_TV)       ivideo.currentvbflags |= CRT2_TV;
-                        else if(ivideo.vbflags & CRT2_LCD) ivideo.currentvbflags |= CRT2_LCD;
-                        else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
+                        if(ivideo->vbflags & CRT2_TV)       ivideo->currentvbflags |= CRT2_TV;
+                        else if(ivideo->vbflags & CRT2_LCD) ivideo->currentvbflags |= CRT2_LCD;
+                        else if(ivideo->vbflags & CRT2_VGA) ivideo->currentvbflags |= CRT2_VGA;
                      }
                   }
                }
 
-               if(ivideo.vbflags & CRT2_LCD) {
-                  inSISIDXREG(SISCR, IND_SIS_LCD_PANEL, reg);
+               if(ivideo->vbflags & CRT2_LCD) {
+                  inSISIDXREG(SISCR, 0x36, reg);
                   reg &= 0x0f;
-                  if(sisvga_engine == SIS_300_VGA) {
-                     sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
+                  if(ivideo->sisvga_engine == SIS_300_VGA) {
+                     ivideo->sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
+                  } else if(ivideo->chip >= SIS_661) {
+                     ivideo->sishw_ext.ulCRT2LCDType = sis661paneltype[reg];
                   } else {
-                     sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
+                     ivideo->sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
+                     if((ivideo->chip == SIS_550) && (sisfb_fstn)) {
+                        if((ivideo->sishw_ext.ulCRT2LCDType != LCD_640x480_2) &&
+                           (ivideo->sishw_ext.ulCRT2LCDType != LCD_640x480_3)) {
+                           ivideo->sishw_ext.ulCRT2LCDType = LCD_320x480;
+                        }
+                     }
+                  }
+                  if(ivideo->sishw_ext.ulCRT2LCDType == LCD_UNKNOWN) {
+                     ivideo->sishw_ext.ulCRT2LCDType = LCD_1024x768;
+                     printk(KERN_DEBUG "sisfb: Illegal panel ID (%02x), assuming 1024x768\n", reg);
+                  }
+                  for(i = 0; i < SIS_LCD_NUMBER; i++) {
+                     if(ivideo->sishw_ext.ulCRT2LCDType == sis_lcd_data[i].lcdtype) {
+                        ivideo->lcdxres = sis_lcd_data[i].xres;
+                        ivideo->lcdyres = sis_lcd_data[i].yres;
+                        ivideo->lcddefmodeidx = sis_lcd_data[i].default_mode_idx;
+                        break;
+                     }
+                  }
+                  if(ivideo->SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
+                       ivideo->lcdxres = 1360; ivideo->lcdyres = 1024; ivideo->lcddefmodeidx = 99;
+                  } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL848) {
+                       ivideo->lcdxres =  848; ivideo->lcdyres =  480; ivideo->lcddefmodeidx = 47;
                   }
+                  printk(KERN_DEBUG "sisfb: Detected %dx%d flat panel\n",
+                               ivideo->lcdxres, ivideo->lcdyres);
                }
-               
-               sisfb_detectedpdc = 0;
 
 #ifdef CONFIG_FB_SIS_300
                 /* Save the current PanelDelayCompensation if the LCD is currently used */
-               if(sisvga_engine == SIS_300_VGA) {
-                  if(ivideo.vbflags & (VB_LVDS | VB_30xBDH)) {
+               if(ivideo->sisvga_engine == SIS_300_VGA) {
+                  if(ivideo->vbflags & (VB_LVDS | VB_30xBDH)) {
                       int tmp;
                       inSISIDXREG(SISCR,0x30,tmp);
                       if(tmp & 0x20) {
                          /* Currently on LCD? If yes, read current pdc */
-                         inSISIDXREG(SISPART1,0x13,sisfb_detectedpdc);
-                         sisfb_detectedpdc &= 0x3c;
-                         if(SiS_Pr.PDC == 0) {
+                         inSISIDXREG(SISPART1,0x13,ivideo->detectedpdc);
+                         ivideo->detectedpdc &= 0x3c;
+                         if(ivideo->SiS_Pr.PDC == -1) {
                             /* Let option override detection */
-                            SiS_Pr.PDC = sisfb_detectedpdc;
+                            ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
                          }
-                         printk(KERN_INFO
-                                "sisfb: Detected LCD PanelDelayCompensation %d\n",
-                                sisfb_detectedpdc);
+                         printk(KERN_INFO "sisfb: Detected LCD PDC 0x%02x\n",
+                                ivideo->detectedpdc);
                       }
-                      if((SiS_Pr.PDC) && (SiS_Pr.PDC != sisfb_detectedpdc)) {
-                         printk(KERN_INFO
-                                "sisfb: Using LCD PanelDelayCompensation %d\n",
-                                SiS_Pr.PDC);
+                      if((ivideo->SiS_Pr.PDC != -1) && (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
+                         printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x\n",
+                                ivideo->SiS_Pr.PDC);
                       }
                   }
                }
 #endif
 
-               sisfb_detectedlcda = 0xff;
-
 #ifdef CONFIG_FB_SIS_315
+               if(ivideo->sisvga_engine == SIS_315_VGA) {
+
+                  /* Try to find about LCDA */
+                  if(ivideo->vbflags & (VB_301C | VB_302B | VB_301LV | VB_302LV | VB_302ELV)) {
+                     int tmp;
+                     inSISIDXREG(SISPART1,0x13,tmp);
+                     if(tmp & 0x04) {
+                        ivideo->SiS_Pr.SiS_UseLCDA = TRUE;
+                        ivideo->detectedlcda = 0x03;
+                     }
+                  }
 
-               if(sisvga_engine == SIS_315_VGA) {
                   /* Save PDC */
-                  if(ivideo.vbflags & (VB_301LV | VB_302LV | VB_302ELV)) {
+                  if(ivideo->vbflags & (VB_301LV | VB_302LV | VB_302ELV)) {
                      int tmp;
                      inSISIDXREG(SISCR,0x30,tmp);
-                     if(tmp & 0x20) {
+                     if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
                         /* Currently on LCD? If yes, read current pdc */
-                        inSISIDXREG(SISPART1,0x2D,sisfb_detectedpdc);
-                        if(SiS_Pr.PDC == 0) {
-                           /* Let option override detection */
-                           SiS_Pr.PDC = sisfb_detectedpdc;
+                        u8 pdc;
+                        inSISIDXREG(SISPART1,0x2D,pdc);
+                        ivideo->detectedpdc  = (pdc & 0x0f) << 1;
+                        ivideo->detectedpdca = (pdc & 0xf0) >> 3;
+                        inSISIDXREG(SISPART1,0x35,pdc);
+                        ivideo->detectedpdc |= ((pdc >> 7) & 0x01);
+                        inSISIDXREG(SISPART1,0x20,pdc);
+                        ivideo->detectedpdca |= ((pdc >> 6) & 0x01);
+                        if(ivideo->newrom) {
+                           /* New ROM invalidates other PDC resp. */
+                           if(ivideo->detectedlcda != 0xff) {
+                              ivideo->detectedpdc = 0xff;
+                           } else {
+                              ivideo->detectedpdca = 0xff;
+                           }
+                        }
+                        if(ivideo->SiS_Pr.PDC == -1) {
+                           if(ivideo->detectedpdc != 0xff) {
+                              ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
+                           }
+                        }
+                        if(ivideo->SiS_Pr.PDCA == -1) {
+                           if(ivideo->detectedpdca != 0xff) {
+                              ivideo->SiS_Pr.PDCA = ivideo->detectedpdca;
+                           }
+                        }
+                        if(ivideo->detectedpdc != 0xff) {
+                           printk(KERN_INFO
+                                "sisfb: Detected LCD PDC 0x%02x (for LCD=CRT2)\n",
+                                 ivideo->detectedpdc);
+                        }
+                        if(ivideo->detectedpdca != 0xff) {
+                           printk(KERN_INFO
+                                "sisfb: Detected LCD PDC1 0x%02x (for LCD=CRT1)\n",
+                                 ivideo->detectedpdca);
                         }
-                        printk(KERN_INFO
-                               "sisfb: Detected LCD PanelDelayCompensation %d\n",
-                                sisfb_detectedpdc);
-                     }
-                     if((SiS_Pr.PDC) && (SiS_Pr.PDC != sisfb_detectedpdc)) {
-                        printk(KERN_INFO
-                                "sisfb: Using LCD PanelDelayCompensation %d\n",
-                                SiS_Pr.PDC);
                      }
+
                      /* Save EMI */
-                     if(ivideo.vbflags & (VB_302LV | VB_302ELV)) {
-                        inSISIDXREG(SISPART4,0x30,SiS_Pr.EMI_30);
-                        inSISIDXREG(SISPART4,0x31,SiS_Pr.EMI_31);
-                        inSISIDXREG(SISPART4,0x32,SiS_Pr.EMI_32);
-                        inSISIDXREG(SISPART4,0x33,SiS_Pr.EMI_33);
-                        SiS_Pr.HaveEMI = TRUE;
-                        if(tmp & 0x20) SiS_Pr.HaveEMILCD = TRUE;
+                     if(ivideo->vbflags & (VB_302LV | VB_302ELV)) {
+                        inSISIDXREG(SISPART4,0x30,ivideo->SiS_Pr.EMI_30);
+                        inSISIDXREG(SISPART4,0x31,ivideo->SiS_Pr.EMI_31);
+                        inSISIDXREG(SISPART4,0x32,ivideo->SiS_Pr.EMI_32);
+                        inSISIDXREG(SISPART4,0x33,ivideo->SiS_Pr.EMI_33);
+                        ivideo->SiS_Pr.HaveEMI = TRUE;
+                        if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
+                               ivideo->SiS_Pr.HaveEMILCD = TRUE;
+                        }
                      }
                   }
 
-                  /* Try to find about LCDA */
-                  if(ivideo.vbflags & (VB_301C | VB_302B | VB_301LV | VB_302LV | VB_302ELV)) {
-                     int tmp;
-                     inSISIDXREG(SISCR,0x34,tmp);
-                     if((tmp <= 0x13) || (tmp == 0xff)) {
-                        /* Currently on LCDA? (Some BIOSes leave CR38) */
-                        inSISIDXREG(SISCR,0x38,tmp);
-                        if((tmp & 0x03) == 0x03)  SiS_Pr.SiS_UseLCDA = TRUE;
-                        else {
-                           /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
-                           inSISIDXREG(SISCR,0x35,tmp);
-                           if(tmp & 0x01) SiS_Pr.SiS_UseLCDA = TRUE;
-                           else {
-                              /* Currently on LCD? If so, we can find out
-                               * by peeking the mode register
-                               */
-                              inSISIDXREG(SISCR,0x30,tmp);
-                              if(tmp & 0x20) {
-                                 inSISIDXREG(SISPART1,0x13,tmp);
-                                 if(tmp & 0x04) SiS_Pr.SiS_UseLCDA = TRUE;
-                              }
-                           }
-                        }
+                  /* Let user override detected PDCs (all bridges) */
+                  if(ivideo->vbflags & (VB_301B | VB_301C | VB_301LV | VB_302LV | VB_302ELV)) {
+                     if((ivideo->SiS_Pr.PDC != -1) && (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
+                        printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x (for LCD=CRT2)\n",
+                                ivideo->SiS_Pr.PDC);
                      }
-                     if(SiS_Pr.SiS_UseLCDA) {
-                        sisfb_detectedlcda = 0x03;
-                        printk(KERN_DEBUG
-                               "sisfb: Bridge uses LCDA for low resolution and text modes\n");
+                     if((ivideo->SiS_Pr.PDCA != -1) && (ivideo->SiS_Pr.PDCA != ivideo->detectedpdca)) {
+                        printk(KERN_INFO "sisfb: Using LCD PDC1 0x%02x (for LCD=CRT1)\n",
+                                ivideo->SiS_Pr.PDCA);
                      }
-                 }
+                  }
+
                }
 #endif
 
-               if (!sisfb_crt1off) {
-                       sisfb_handle_ddc(&sisfb_thismonitor, 0);
+               if(!ivideo->sisfb_crt1off) {
+                       sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 0);
                } else {
-                       if ((ivideo.vbflags & (VB_301|VB_301B|VB_301C|VB_302B)) &&
-                           (ivideo.vbflags & (CRT2_VGA | CRT2_LCD))) {
-                               sisfb_handle_ddc(&sisfb_thismonitor, 1);
+                       if((ivideo->vbflags & (VB_301|VB_301B|VB_301C|VB_302B)) &&
+                          (ivideo->vbflags & (CRT2_VGA | CRT2_LCD))) {
+                               sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 1);
                        }
                }
 
-               if (sisfb_mode_idx >= 0)
-                       sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx, ivideo.currentvbflags);
+               if(ivideo->sisfb_mode_idx >= 0) {
+                       int bu = ivideo->sisfb_mode_idx;
+                       ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo,
+                                       ivideo->sisfb_mode_idx, ivideo->currentvbflags);
+                       if(bu != ivideo->sisfb_mode_idx) {
+                               printk(KERN_ERR "Mode %dx%dx%d failed validation\n",
+                                       sisbios_mode[bu].xres,
+                                       sisbios_mode[bu].yres,
+                                       sisbios_mode[bu].bpp);
+                       }
+               }
 
-               if (sisfb_mode_idx < 0) {
-                       switch (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+               if(ivideo->sisfb_mode_idx < 0) {
+                       switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
                           case CRT2_LCD:
-                               sisfb_mode_idx = DEFAULT_LCDMODE;
+                               ivideo->sisfb_mode_idx = ivideo->lcddefmodeidx;
                                break;
                           case CRT2_TV:
-                               sisfb_mode_idx = DEFAULT_TVMODE;
+                               ivideo->sisfb_mode_idx = ivideo->tvdefmodeidx;
                                break;
                           default:
-                               sisfb_mode_idx = DEFAULT_MODE;
+                               ivideo->sisfb_mode_idx = ivideo->defmodeidx;
                                break;
                        }
                }
 
-               sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
+               ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
 
-               if (ivideo.refresh_rate != 0)
-                       sisfb_search_refresh_rate(ivideo.refresh_rate, sisfb_mode_idx);
+               if(ivideo->refresh_rate != 0) {
+                       sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx);
+               }
 
-               if (sisfb_rate_idx == 0) {
-                       sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
-                       ivideo.refresh_rate = 60;
+               if(ivideo->rate_idx == 0) {
+                       ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx;
+                       ivideo->refresh_rate = 60;
                }
 
-               if (sisfb_thismonitor.datavalid) {
-                       if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
-                                             sisfb_rate_idx, ivideo.refresh_rate)) {
+               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");
                        }
                }
 
-               ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
-               ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
-               ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
-               ivideo.org_x = ivideo.org_y = 0;
-               ivideo.video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
+               ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
+               ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres;
+               ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
 
-               sisfb_set_vparms();
+               sisfb_set_vparms(ivideo);
                
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 
 
                /* ---------------- For 2.4: Now switch the mode ------------------ */          
                
                printk(KERN_INFO "sisfb: Mode is %dx%dx%d (%dHz)\n",
-                       ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
-                       ivideo.refresh_rate);
+                       ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
+                       ivideo->refresh_rate);
 
-               sisfb_pre_setmode();
+               sisfb_pre_setmode(ivideo);
 
-               if (SiSSetMode(&SiS_Pr, &sishw_ext, sisfb_mode_no) == 0) {
+               if(SiSSetMode(&ivideo->SiS_Pr, &ivideo->sishw_ext, ivideo->mode_no) == 0) {
                        printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n",
-                               sisfb_mode_no);
-                       vfree(sishw_ext.pSR);
-                       vfree(sishw_ext.pCR);
-                       release_mem_region(ivideo.video_base, ivideo.video_size);
-                       release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
+                                                                       ivideo->mode_no);
+                       iounmap((void *)ivideo->video_vbase);
+                       iounmap((void *)ivideo->mmio_vbase);
+                       release_mem_region(ivideo->video_base, ivideo->video_size);
+                       release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
+                       if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+                       if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+                       pci_set_drvdata(pdev, NULL);
                        kfree(sis_fb_info);
                        return -EINVAL;
                }
 
                outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
 
-               sisfb_post_setmode();
-
-               ivideo.accel = 0;
-               if(sisfb_accel) {
-                  ivideo.accel = -1;
-                  default_var.accel_flags |= FB_ACCELF_TEXT;
-                  sisfb_initaccel();
-               }
+               sisfb_post_setmode(ivideo);
 
                /* Maximize regardless of sisfb_max at startup */
-               default_var.yres_virtual = 32767;
-               sisfb_crtc_to_var(&default_var);
+               ivideo->default_var.yres_virtual = 32767;
+
+               /* Force reset of x virtual in crtc_to_var */
+               ivideo->default_var.xres_virtual = 0;
+
+               sisfb_crtc_to_var(ivideo, &ivideo->default_var);
+
+               sisfb_calc_pitch(ivideo, &ivideo->default_var);
+               sisfb_set_pitch(ivideo);
+
+               ivideo->accel = 0;
+               if(ivideo->sisfb_accel) {
+                  ivideo->accel = -1;
+                  ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
+               }
+               sisfb_initaccel(ivideo);
                
-               sis_fb_info->node = -1;
+               sis_fb_info->node  = -1;
                sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
-               sis_fb_info->blank = &sisfb_blank;
                sis_fb_info->fbops = &sisfb_ops;
+               sis_fb_info->disp  = &ivideo->sis_disp;
+               sis_fb_info->blank = &sisfb_blank;
                sis_fb_info->switch_con = &sisfb_switch;
-               sis_fb_info->updatevar = &sisfb_update_var;
-               sis_fb_info->changevar = NULL;
-               sis_fb_info->disp = &sis_disp;
+               sis_fb_info->updatevar  = &sisfb_update_var;
+               sis_fb_info->changevar  = NULL;
                strcpy(sis_fb_info->fontname, sisfb_fontname);
 
-               sisfb_set_disp(-1, &default_var, sis_fb_info);
+               sisfb_set_disp(-1, &ivideo->default_var, sis_fb_info);
 
-#else          /* --------- For 2.5: Setup a somewhat sane default var ------------ */
+#else          /* --------- For 2.6: Setup a somewhat sane default var ------------ */
 
                printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
-                       ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
-                       ivideo.refresh_rate);
+                       ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
+                       ivideo->refresh_rate);
 
-               default_var.xres = default_var.xres_virtual = ivideo.video_width;
-               default_var.yres = default_var.yres_virtual = ivideo.video_height;
-               default_var.bits_per_pixel = ivideo.video_bpp;
+               ivideo->default_var.xres = ivideo->default_var.xres_virtual = ivideo->video_width;
+               ivideo->default_var.yres = ivideo->default_var.yres_virtual = ivideo->video_height;
+               ivideo->default_var.bits_per_pixel = ivideo->video_bpp;
 
-               sisfb_bpp_to_var(&default_var);
+               sisfb_bpp_to_var(ivideo, &ivideo->default_var);
                
-               default_var.pixclock = (u32) (1000000000 /
-                               sisfb_mode_rate_to_dclock(&SiS_Pr, &sishw_ext,
-                                               sisfb_mode_no, sisfb_rate_idx));
+               ivideo->default_var.pixclock = (u32) (1000000000 /
+                               sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, &ivideo->sishw_ext,
+                                               ivideo->mode_no, ivideo->rate_idx));
                                                
-               if(sisfb_mode_rate_to_ddata(&SiS_Pr, &sishw_ext,
-                        sisfb_mode_no, sisfb_rate_idx,
-                        &default_var.left_margin, &default_var.right_margin, 
-                        &default_var.upper_margin, &default_var.lower_margin,
-                        &default_var.hsync_len, &default_var.vsync_len,
-                        &default_var.sync, &default_var.vmode)) {
-                  if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-                     default_var.pixclock <<= 1;
+               if(sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, &ivideo->sishw_ext,
+                               ivideo->mode_no, ivideo->rate_idx, &ivideo->default_var)) {
+                  if((ivideo->default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+                     ivideo->default_var.pixclock <<= 1;
                   }
                }
 
-               ivideo.accel = 0;
-               if(sisfb_accel) {
-                  ivideo.accel = -1;
-                  default_var.accel_flags |= FB_ACCELF_TEXT;
-                  sisfb_initaccel();
-               }
-
-               if(sisfb_ypan) {
+               if(ivideo->sisfb_ypan) {
                   /* Maximize regardless of sisfb_max at startup */
-                  default_var.yres_virtual =
-                               ivideo.heapstart / (default_var.xres * (default_var.bits_per_pixel >> 3));
-                  if(default_var.yres_virtual > 32767) default_var.yres_virtual = 32767;
-                  if(default_var.yres_virtual <= default_var.yres) {
-                     default_var.yres_virtual = default_var.yres;
+                  ivideo->default_var.yres_virtual = sisfb_calc_maxyres(ivideo, &ivideo->default_var);
+                  if(ivideo->default_var.yres_virtual < ivideo->default_var.yres) {
+                     ivideo->default_var.yres_virtual = ivideo->default_var.yres;
                   }
                }
 
+               sisfb_calc_pitch(ivideo, &ivideo->default_var);
+
+               ivideo->accel = 0;
+               if(ivideo->sisfb_accel) {
+                  ivideo->accel = -1;
+#ifdef STUPID_ACCELF_TEXT_SHIT
+                  ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
+#endif
+               }
+               sisfb_initaccel(ivideo);
+
+#if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)
+               sis_fb_info->flags = FBINFO_DEFAULT             |
+                                    FBINFO_HWACCEL_YPAN        |
+                                    FBINFO_HWACCEL_XPAN        |
+                                    FBINFO_HWACCEL_COPYAREA    |
+                                    FBINFO_HWACCEL_FILLRECT    |
+                                    ((ivideo->accel) ? 0 : FBINFO_HWACCEL_DISABLED);
+#else
                sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
-               sis_fb_info->var = default_var;
-               sis_fb_info->fix = sisfb_fix;
-               sis_fb_info->par = &ivideo;
-               sis_fb_info->screen_base = ivideo.video_vbase;
-               sis_fb_info->fbops = &sisfb_ops;
-#ifdef NEWFBDEV
-               sis_fb_info->class_dev.dev = &pdev->dev;
 #endif
+               sis_fb_info->var = ivideo->default_var;
+               sis_fb_info->fix = ivideo->sisfb_fix;
+               sis_fb_info->screen_base = (char *)ivideo->video_vbase;
+               sis_fb_info->fbops = &sisfb_ops;
+
                sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info);
-               sis_fb_info->pseudo_palette = pseudo_palette;
+               sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
                
                fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0);
-#endif
+#endif         /* 2.6 */
 
-               printk(KERN_INFO "sisfb: Initial vbflags 0x%lx\n", ivideo.vbflags);
+               printk(KERN_DEBUG "sisfb: Initial vbflags 0x%lx\n", (unsigned long)ivideo->vbflags);
 
 #ifdef CONFIG_MTRR
-               ivideo.mtrr = mtrr_add((unsigned int) ivideo.video_base,
-                               (unsigned int) ivideo.video_size,
-                               MTRR_TYPE_WRCOMB, 1);
-               if(ivideo.mtrr) {
-                       printk(KERN_INFO "sisfb: Added MTRRs\n");
+               ivideo->mtrr = mtrr_add(ivideo->video_base, ivideo->video_size,
+                                       MTRR_TYPE_WRCOMB, 1);
+               if(!ivideo->mtrr) {
+                       printk(KERN_DEBUG "sisfb: Failed to add MTRRs\n");
                }
-
 #endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
@@ -4946,39 +5573,157 @@ int __init sisfb_init(void)
 #endif
 
                if(register_framebuffer(sis_fb_info) < 0) {
-                       vfree(sishw_ext.pSR);
-                       vfree(sishw_ext.pCR);
-                       release_mem_region(ivideo.video_base, ivideo.video_size);
-                       release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
                        printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
+                       iounmap((void *)ivideo->video_vbase);
+                       iounmap((void *)ivideo->mmio_vbase);
+                       release_mem_region(ivideo->video_base, ivideo->video_size);
+                       release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
+                       if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+                       if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+                       pci_set_drvdata(pdev, NULL);
                        kfree(sis_fb_info);
                        return -EINVAL;
                }
 
-               sisfb_registered = 1;                   
+               ivideo->registered = 1;
 
-               printk(KERN_DEBUG "sisfb: Installed SISFB_GET_INFO ioctl (%x)\n", SISFB_GET_INFO);
-               printk(KERN_DEBUG "sisfb: Installed SISFB_GET_VBRSTATUS ioctl (%x)\n", SISFB_GET_VBRSTATUS);
-               
-               printk(KERN_INFO "sisfb: 2D acceleration is %s, scrolling mode %s\n",
-                    sisfb_accel ? "enabled" : "disabled",
-                    sisfb_ypan  ? (sisfb_max ? "ypan (auto-max)" : "ypan (no auto-max)") : "redraw");
+               /* Enlist us */
+               ivideo->next = card_list;
+               card_list = ivideo;
+
+#ifdef SIS_CONFIG_COMPAT
+               {
+               int ret;
+               /* Our ioctls are all "32/64bit compatible" */
+               if(register_ioctl32_conversion(FBIOGET_VBLANK, NULL)) {
+                  printk(KERN_ERR "sisfb: Error registering FBIOGET_VBLANK ioctl32 translation\n");
+               } else {
+                  ivideo->ioctl32vblankregistered = 1;
+               }
+               ret =  register_ioctl32_conversion(FBIO_ALLOC,             NULL);
+               ret |= register_ioctl32_conversion(FBIO_FREE,              NULL);
+               ret |= register_ioctl32_conversion(SISFB_GET_INFO_SIZE,    NULL);
+               ret |= register_ioctl32_conversion(SISFB_GET_INFO,         NULL);
+               ret |= register_ioctl32_conversion(SISFB_GET_TVPOSOFFSET,  NULL);
+               ret |= register_ioctl32_conversion(SISFB_SET_TVPOSOFFSET,  NULL);
+               ret |= register_ioctl32_conversion(SISFB_SET_LOCK,         NULL);
+               ret |= register_ioctl32_conversion(SISFB_GET_VBRSTATUS,    NULL);
+               ret |= register_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE, NULL);
+               ret |= register_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE, NULL);
+               if(ret) printk(KERN_ERR "sisfb: Error registering ioctl32 translations\n");
+               else    ivideo->ioctl32registered = 1;
+               }
+#endif
 
+               printk(KERN_INFO "sisfb: 2D acceleration is %s, y-panning %s\n",
+                    ivideo->sisfb_accel ? "enabled" : "disabled",
+                    ivideo->sisfb_ypan  ?
+                       (ivideo->sisfb_max ? "enabled (auto-max)" : "enabled (no auto-max)") : "disabled");
+
+
+               printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%d\n",
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-               printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
-                       GET_FB_IDX(sis_fb_info->node), sis_fb_info->modename, VER_MAJOR, VER_MINOR,
-                       VER_LEVEL);                  
+                       GET_FB_IDX(sis_fb_info->node),
 #else
-               printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
-                       sis_fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
+                       sis_fb_info->node,
 #endif
+                       ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
 
                printk(KERN_INFO "sisfb: (C) 2001-2004 Thomas Winischhofer.\n");
 
        }       /* if mode = "none" */
+
        return 0;
 }
 
+/*****************************************************/
+/*                PCI DEVICE HANDLING                */
+/*****************************************************/
+
+static void __devexit sisfb_remove(struct pci_dev *pdev)
+{
+       struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+       struct fb_info        *sis_fb_info = ivideo->memyselfandi;
+       int                   registered = ivideo->registered;
+
+#ifdef SIS_CONFIG_COMPAT
+       if(ivideo->ioctl32vblankregistered) {
+               if(unregister_ioctl32_conversion(FBIOGET_VBLANK)) {
+                       printk(KERN_ERR "sisfb: Error unregistering FBIOGET_VBLANK ioctl32 translation\n");
+               }
+       }
+       if(ivideo->ioctl32registered) {
+               int ret;
+               ret =  unregister_ioctl32_conversion(FBIO_ALLOC);
+               ret |= unregister_ioctl32_conversion(FBIO_FREE);
+               ret |= unregister_ioctl32_conversion(SISFB_GET_INFO_SIZE);
+               ret |= unregister_ioctl32_conversion(SISFB_GET_INFO);
+               ret |= unregister_ioctl32_conversion(SISFB_GET_TVPOSOFFSET);
+               ret |= unregister_ioctl32_conversion(SISFB_SET_TVPOSOFFSET);
+               ret |= unregister_ioctl32_conversion(SISFB_SET_LOCK);
+               ret |= unregister_ioctl32_conversion(SISFB_GET_VBRSTATUS);
+               ret |= unregister_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE);
+               ret |= unregister_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE);
+               if(ret) printk(KERN_ERR "sisfb: Error unregistering ioctl32 translations\n");
+       }
+#endif
+
+       /* Unmap */
+       iounmap((void *)ivideo->video_vbase);
+       iounmap((void *)ivideo->mmio_vbase);
+       if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+       if(ivideo->bios_abase)    vfree(ivideo->bios_abase);
+
+       /* Release mem regions */
+       release_mem_region(ivideo->video_base, ivideo->video_size);
+       release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
+
+#ifdef CONFIG_MTRR
+       /* Release MTRR region */
+       if(ivideo->mtrr) {
+               mtrr_del(ivideo->mtrr, ivideo->video_base, ivideo->video_size);
+       }
+#endif
+
+       /* 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
+       }
+
+       pci_set_drvdata(pdev, NULL);
+
+       /* TODO: Restore the initial mode
+        * This sounds easy but is as good as impossible
+        * on many machines with SiS chip and video bridge
+        * since text modes are always set up differently
+        * from machine to machine. Depends on the type
+        * of integration between chipset and bridge.
+        */
+       if(registered) {
+          printk(KERN_INFO "sisfb: Restoring of text mode not supported yet\n");
+       }
+};
+
+static struct pci_driver sisfb_driver = {
+       .name           = "sisfb",
+       .id_table       = sisfb_pci_table,
+       .probe          = sisfb_probe,
+       .remove         = __devexit_p(sisfb_remove)
+};
+
+int __init sisfb_init(void)
+{
+       return(pci_module_init(&sisfb_driver));
+}
+
+/*****************************************************/
+/*                      MODULE                       */
+/*****************************************************/
 
 #ifdef MODULE
 
@@ -4989,202 +5734,240 @@ static unsigned int crt1off = 1;
 static unsigned int mem = 0;
 static char         *forcecrt2type = NULL;
 static int          forcecrt1 = -1;
-static char         *queuemode = NULL;
-static int          pdc = 0;
+static int          pdc = -1;
+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          userom = -1;
 static int          useoem = -1;
 static char         *tvstandard = NULL;
 static int         nocrt2rate = 0;
 static int          scalelcd = -1;
 static char        *specialtiming = NULL;
 static int         lvdshl = -1;
+static int         tvxposoffset = 0, tvyposoffset = 0;
+static int         filter = -1;
+#if !defined(__i386__) && !defined(__x86_64__)
+static int         resetcard = 0;
+static int         videoram = 0;
+#endif
 
-MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/651/661/740/741/330/760 framebuffer driver");
+MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/65x/661/74x/330/760 framebuffer device driver");
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>; SiS; Various others");
+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_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)");
+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(filter, "i");
+MODULE_PARM(nocrt2rate, "i");
+MODULE_PARM(inverse, "i");
+#if !defined(__i386__) && !defined(__x86_64__)
+MODULE_PARM(resetcard, "i");
+MODULE_PARM(videoram, "i");
 #endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)         
-MODULE_PARM(mode, "s");
-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"
-        "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
-        "number, it will be interpreted as a VESA mode number. (default: 800x600x8)");
 #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);
+module_param(nomax, int, 0);
+module_param(userom, int, 0);
+module_param(useoem, int, 0);
+module_param(mode, charp, 0);
+module_param(vesa, int, 0);
+module_param(rate, int, 0);
+module_param(forcecrt1, int, 0);
+module_param(forcecrt2type, charp, 0);
+module_param(scalelcd, int, 0);
+module_param(pdc, int, 0);
+module_param(pdc1, int, 0);
+module_param(specialtiming, charp, 0);
+module_param(lvdshl, int, 0);
+module_param(tvstandard, charp, 0);
+module_param(tvxposoffset, int, 0);
+module_param(tvyposoffset, int, 0);
+module_param(filter, int, 0);
+module_param(nocrt2rate, int, 0);
+#if !defined(__i386__) && !defined(__x86_64__)
+module_param(resetcard, int, 0);
+module_param(videoram, int, 0);
+#endif
+#endif
+
+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 and Xabre 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");
+
+MODULE_PARM_DESC(noaccel,
+        "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
+         "(default: 0)\n");
+
+MODULE_PARM_DESC(noypan,
+        "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
+         "will be performed by redrawing the screen. (default: 0)\n");
+
+MODULE_PARM_DESC(nomax,
+        "\nIf y-panning is enabled, sisfb will by default use the entire available video\n"
+         "memory for the virtual screen in order to optimize scrolling performance. If\n"
+         "this is set to anything other than 0, sisfb will not do this and thereby \n"
+         "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(vesa, "i");
+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)");
+        "\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(vesa, "i");
+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"
+        "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
+        "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
+
 MODULE_PARM_DESC(vesa,
        "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
-         "0x117 (default: 0x0103)");
+         "0x117 (default: 0x0103)\n");
 #endif
 
-MODULE_PARM(rate, "i");
 MODULE_PARM_DESC(rate,
        "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
          "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
-         "will be ignored (default: 60)");
-
-MODULE_PARM(crt1off,   "i");
-MODULE_PARM_DESC(crt1off,
-       "(Deprecated, please use forcecrt1)");
+         "will be ignored (default: 60)\n");
 
-MODULE_PARM(filter, "i");
-MODULE_PARM_DESC(filter,
-       "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
-         "(Possible values 0-7, default: [no filter])");
-
-MODULE_PARM(queuemode,   "s");
-MODULE_PARM_DESC(queuemode,
-       "\nSelects the queue mode on 315/550/65x/74x/330/760. Possible choices are AGP, VRAM,\n"
-         "MMIO. AGP is only available if the kernel has AGP support. The queue mode is\n"
-         "important to programs using the 2D/3D accelerator of the SiS chip. The modes\n"
-         "require a totally different way of programming the engines. If any mode than\n"
-         "MMIO is selected, sisfb will disable its own 2D acceleration. On\n"
-         "300/540/630/730, this option is ignored. (default: MMIO)");
-
-/* TW: "Import" the options from the X driver */
-MODULE_PARM(mem,    "i");
-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 and Xabre series, the heap is 1MB by default. The\n"
-         "value is to be specified without 'KB' and should match the MaxXFBMem setting for\n"
-         "XFree 4.x (x>=2).");
+MODULE_PARM_DESC(forcecrt1,
+       "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is \n"
+         "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
+         "0=CRT1 OFF) (default: [autodetected])\n");
 
-MODULE_PARM(forcecrt2type, "s");
 MODULE_PARM_DESC(forcecrt2type,
        "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
          "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
          "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
-         "On systems with a 301(B/LV) bridge, parameters SVIDEO, COMPOSITE or SCART can be\n"
-         "used instead of TV to override the TV detection. (default: [autodetected])");
+         "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
+         "be used instead of TV to override the TV detection. Furthermore, on systems\n"
+         "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
+         "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
+         "depends on the very hardware in use. (default: [autodetected])\n");
 
-MODULE_PARM(forcecrt1, "i");
-MODULE_PARM_DESC(forcecrt1,
-       "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is \n"
-         "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
-         " 0=CRT1 off) (default: [autodetected])");
+MODULE_PARM_DESC(scalelcd,
+       "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
+         "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
+         "show black bars around the image, TMDS panels will probably do the scaling\n"
+         "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
 
-MODULE_PARM(pdc, "i");
 MODULE_PARM_DESC(pdc,
         "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
          "should detect this correctly in most cases; however, sometimes this is not\n"
          "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
-         "on a 300 series chipset; 3 or 51 on a 315 series chipset. If the problem persists,\n"
+         "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
          "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
-         "and value from 0 to 255). (default: [autodetected])");
+         "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
 
-MODULE_PARM(noaccel, "i");
-MODULE_PARM_DESC(noaccel,
-        "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
-         "(default: 0)");
+#ifdef CONFIG_FB_SIS_315
+MODULE_PARM_DESC(pdc1,
+        "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
+         "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
+         "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
+         "implemented yet.\n");
+#endif
 
-MODULE_PARM(noypan, "i");
-MODULE_PARM_DESC(noypan,
-        "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
-         "will be performed by redrawing the screen. (default: 0)");
+MODULE_PARM_DESC(specialtiming,
+       "\nPlease refer to documentation for more information on this option.\n");
 
-MODULE_PARM(nomax, "i");
-MODULE_PARM_DESC(nomax,
-        "\nIf y-panning is enabled, sisfb will by default use the entire available video\n"
-         "memory for the virtual screen in order to optimize scrolling performance. If this\n"
-         "is set to anything other than 0, sisfb will not do this and thereby enable the user\n"
-         "to positively specify a virtual Y size of the screen using fbset. (default: 0)\n");
+MODULE_PARM_DESC(lvdshl,
+       "\nPlease refer to documentation for more information on this option.\n");
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 
-MODULE_PARM(inverse, "i");
-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)");
-#endif 
+MODULE_PARM_DESC(tvstandard,
+       "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
+         "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
 
-MODULE_PARM(userom, "i");
-MODULE_PARM_DESC(userom,
-        "\nSetting this to 0 keeps sisfb from using the video BIOS data which is needed\n"
-         "for some LCD and TV setup. (default: 1)");
+MODULE_PARM_DESC(tvxposoffset,
+       "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
+         "Default: 0\n");
 
-MODULE_PARM(useoem, "i");
-MODULE_PARM_DESC(useoem,
-        "\nSetting this to 0 keeps sisfb from using its internel OEM data for some LCD\n"
-         "panels and TV connector types. (default: [auto])");
+MODULE_PARM_DESC(tvyposoffset,
+       "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
+         "Default: 0\n");
 
-MODULE_PARM(tvstandard, "s");
-MODULE_PARM_DESC(tvstandard,
-       "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
-         "pal and ntsc. (default: [auto])");
+MODULE_PARM_DESC(filter,
+       "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
+         "(Possible values 0-7, default: [no filter])\n");
 
-MODULE_PARM(nocrt2rate, "i");
 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)");
-
-MODULE_PARM(scalelcd, "i");
-MODULE_PARM_DESC(scalelcd,
-       "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
-         "native resolution. Setting it to 0 will disable scaling; if the panel can scale\n"
-         "by itself, it will probably do this, otherwise you will see a black bar around\n"
-         "the screen image. Default: [autodetect if panel can scale]");
-
-MODULE_PARM(specialtiming, "s");
+         "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
 
-MODULE_PARM(lvdshl, "i");
+#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,
+       "\nSet this to 1 in order to reset (POST) the card on non-x86 machines where\n"
+         "the BIOS did not POST the card (only supported for SiS 300/305 currently).\n"
+         "Default: 0\n");
+
+MODULE_PARM_DESC(videoram,
+       "\nSet this to the amount of video RAM (in kilobyte) the card has. Required on\n"
+         "some non-x86 architectures where the memory auto detection fails. Only\n"
+         "relevant if resetcard is set, too. Default: [auto-detect]\n");
+#endif
+#endif
 
-int init_module(void)
+int __init sisfb_init_module(void)
 {
-       int err;
+       sisfb_setdefaultparms();
 
-       SiS_Pr.UsePanelScaler = -1;
-       SiS_Pr.SiS_CustomT = CUT_NONE;
-       SiS_Pr.LVDSHL = -1;
-
-       ivideo.refresh_rate = sisfb_parm_rate = rate;
+       if(rate) sisfb_parm_rate = rate;
 
        if((scalelcd == 0) || (scalelcd == 1)) {
-          SiS_Pr.UsePanelScaler = scalelcd ^ 1;
+          sisfb_scalelcd = scalelcd ^ 1;
        }
 
-       if(mode)
-               sisfb_search_mode(mode, FALSE);
-       else if(vesa != -1)
-               sisfb_search_vesamode(vesa, FALSE);
-       else
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-               /* For 2.4, set mode=none if no mode is given  */
-               sisfb_mode_idx = MODE_INDEX_NONE;
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-               /* For 2.5, we don't need this "mode=none" stuff anymore */
-               sisfb_mode_idx = DEFAULT_MODE;
-#endif
+       /* Need to check crt2 type first for fstn/dstn */
 
        if(forcecrt2type)
                sisfb_search_crt2type(forcecrt2type);
@@ -5192,16 +5975,16 @@ int init_module(void)
        if(tvstandard)
                sisfb_search_tvstd(tvstandard);
 
-       if(crt1off == 0)
-               sisfb_crt1off = 1;
-       else
-               sisfb_crt1off = 0;
+       if(mode)
+               sisfb_search_mode(mode, FALSE);
+       else if(vesa != -1)
+               sisfb_search_vesamode(vesa, FALSE);
+
+       sisfb_crt1off = (crt1off == 0) ? 1 : 0;
 
        sisfb_forcecrt1 = forcecrt1;
-       if(forcecrt1 == 1)
-               sisfb_crt1off = 0;
-       else if(forcecrt1 == 0)
-               sisfb_crt1off = 1;
+       if(forcecrt1 == 1)      sisfb_crt1off = 0;
+       else if(forcecrt1 == 0) sisfb_crt1off = 1;
 
        if(noaccel == 1)      sisfb_accel = 0;
        else if(noaccel == 0) sisfb_accel = 1;
@@ -5214,84 +5997,48 @@ int init_module(void)
        
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
        if(inverse)           sisfb_inverse = 1;
-       sisfb_fontname[0] = '\0';
 #endif
 
-       if(mem)               sisfb_mem = mem;
+       if(mem)               sisfb_parm_mem = mem;
 
-       sisfb_userom = userom;
+       if(userom != -1)      sisfb_userom = userom;
+       if(useoem != -1)      sisfb_useoem = useoem;
 
-       sisfb_useoem = useoem;
-
-       if (queuemode)        sisfb_search_queuemode(queuemode);
-       
-       /* If other queuemode than MMIO, disable 2D accel and ypan */
-       if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
-               sisfb_accel = 0;
-       }
-
-        if(pdc) sisfb_pdc = pdc & 0x3c;
+        if(pdc != -1)  sisfb_pdc  = (pdc  & 0x7f);
+       if(pdc1 != -1) sisfb_pdca = (pdc1 & 0x1f);
 
        sisfb_nocrt2rate = nocrt2rate;
 
        if(specialtiming)
                sisfb_search_specialtiming(specialtiming);
 
-       if((lvdshl >= 0) && (lvdshl <= 3)) SiS_Pr.LVDSHL = lvdshl;
-
-       if((err = sisfb_init()) < 0) return err;
+       if((lvdshl >= 0) && (lvdshl <= 3))  sisfb_lvdshl = lvdshl;
 
-       return 0;
-}
+       if(filter != -1) sisfb_filter = filter;
 
-void cleanup_module(void)
-{
-       /* Unmap */
-       iounmap(ivideo.video_vbase);
-       iounmap(ivideo.mmio_vbase);
+       sisfb_tvxposoffset = tvxposoffset;
+       sisfb_tvyposoffset = tvyposoffset;
 
-       /* Release mem regions */
-       release_mem_region(ivideo.video_base, ivideo.video_size);
-       release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
-
-#ifdef CONFIG_MTRR
-       /* Release MTRR region */
-       if(ivideo.mtrr) {
-               mtrr_del(ivideo.mtrr,
-                     (unsigned int)ivideo.video_base,
-                     (unsigned int)ivideo.video_size);
-       }
+#if !defined(__i386__) && !defined(__x86_64__)
+       sisfb_resetcard = (resetcard) ? 1 : 0;
+       if(videoram)    sisfb_videoram = videoram;
 #endif
 
-       /* Unregister the framebuffer */
-       if(sisfb_registered) {
-               unregister_framebuffer(sis_fb_info);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && (defined(NEWFBDEV))
-               framebuffer_release(sis_fb_info);
-#else
-               kfree(sis_fb_info);
-#endif
-       }
+        return(sisfb_init());
+}
 
-       if(sishw_ext.pSR) vfree(sishw_ext.pSR);
-       if(sishw_ext.pCR) vfree(sishw_ext.pCR);
-       
-       /* TODO: Restore the initial mode
-        * This sounds easy but is as good as impossible
-        * on many machines with SiS chip and video bridge
-        * since text modes are always set up differently
-        * from machine to machine. Depends on the type
-        * of integration between chipset and bridge.
-        */
-       
-       printk(KERN_INFO "sisfb: Module unloaded\n");
+static void __exit sisfb_remove_module(void)
+{
+       pci_unregister_driver(&sisfb_driver);
+       printk(KERN_DEBUG "sisfb: Module unloaded\n");
 }
 
-#endif
+module_init(sisfb_init_module);
+module_exit(sisfb_remove_module);
+
+#endif            /*  /MODULE  */
 
 EXPORT_SYMBOL(sis_malloc);
 EXPORT_SYMBOL(sis_free);
-EXPORT_SYMBOL(sis_dispinfo);
 
-EXPORT_SYMBOL(ivideo);
-                                                                                           
+
index 0402ae7..3f9298d 100644 (file)
@@ -1,6 +1,7 @@
 /*
- * SiS 300/630/730/540/315/550/650/651/M650/661FX/M661FX/740/741/330/760
- * frame buffer driver for Linux kernels 2.4.x and 2.5.x
+ * SiS 300/305/540/630(S)/730(S)
+ * SiS 315(H/PRO)/55x/(M)65x/(M)661(F/M)X/740/741(GX)/330/(M)760
+ * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
  *
  * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
  *
 #ifndef _SISFB_MAIN
 #define _SISFB_MAIN
 
-#include "vstruct.h"
-
-/* ------------------- Constant Definitions ------------------------- */
-
-#define AGPOFF     /* default is turn off AGP */
-
-#define SISFAIL(x) do { printk(x "\n"); return -EINVAL; } while(0)
-
-#define VER_MAJOR                 1
-#define VER_MINOR                 6
-#define VER_LEVEL                 25
+#include <linux/spinlock.h>
 
+#include "vstruct.h"
 #include "sis.h"
 
-/* To be included in pci_ids.h */
-#ifndef PCI_DEVICE_ID_SI_650_VGA
-#define PCI_DEVICE_ID_SI_650_VGA  0x6325
-#endif
-#ifndef PCI_DEVICE_ID_SI_650
-#define PCI_DEVICE_ID_SI_650      0x0650
-#endif
-#ifndef PCI_DEVICE_ID_SI_740
-#define PCI_DEVICE_ID_SI_740      0x0740
-#endif
-#ifndef PCI_DEVICE_ID_SI_330
-#define PCI_DEVICE_ID_SI_330      0x0330
-#endif
-#ifndef PCI_DEVICE_ID_SI_660_VGA
-#define PCI_DEVICE_ID_SI_660_VGA  0x6330
-#endif
-#ifndef PCI_DEVICE_ID_SI_660
-#define PCI_DEVICE_ID_SI_660      0x0661
-#endif
-#ifndef PCI_DEVICE_ID_SI_741
-#define PCI_DEVICE_ID_SI_741      0x0741
-#endif
-#ifndef PCI_DEVICE_ID_SI_660
-#define PCI_DEVICE_ID_SI_660      0x0660
-#endif
-#ifndef PCI_DEVICE_ID_SI_760
-#define PCI_DEVICE_ID_SI_760      0x0760
-#endif
-
-/* To be included in fb.h */
-#ifndef FB_ACCEL_SIS_GLAMOUR_2
-#define FB_ACCEL_SIS_GLAMOUR_2  40     /* SiS 315, 65x, 740, 661, 741  */
-#endif
-#ifndef FB_ACCEL_SIS_XABRE
-#define FB_ACCEL_SIS_XABRE      41     /* SiS 330 ("Xabre"), 760       */
-#endif
-
-#define MAX_ROM_SCAN              0x10000
-
-#define HW_CURSOR_CAP             0x80
-#define TURBO_QUEUE_CAP           0x40
-#define AGP_CMD_QUEUE_CAP         0x20
-#define VM_CMD_QUEUE_CAP          0x10
-#define MMIO_CMD_QUEUE_CAP        0x08
-
-/* For 300 series */
-#ifdef CONFIG_FB_SIS_300
-#define TURBO_QUEUE_AREA_SIZE     0x80000 /* 512K */
-#endif
-
-/* For 315/Xabre series */
-#ifdef CONFIG_FB_SIS_315
-#define COMMAND_QUEUE_AREA_SIZE   0x80000 /* 512K */
-#define COMMAND_QUEUE_THRESHOLD   0x1F
-#endif
-
-#define HW_CURSOR_AREA_SIZE_315   0x4000  /* 16K */
-#define HW_CURSOR_AREA_SIZE_300   0x1000  /* 4K */
-
-#define OH_ALLOC_SIZE             4000
-#define SENTINEL                  0x7fffffff
-
-#define SEQ_ADR                   0x14
-#define SEQ_DATA                  0x15
-#define DAC_ADR                   0x18
-#define DAC_DATA                  0x19
-#define CRTC_ADR                  0x24
-#define CRTC_DATA                 0x25
-#define DAC2_ADR                  (0x16-0x30)
-#define DAC2_DATA                 (0x17-0x30)
-#define VB_PART1_ADR              (0x04-0x30)
-#define VB_PART1_DATA             (0x05-0x30)
-#define VB_PART2_ADR              (0x10-0x30)
-#define VB_PART2_DATA             (0x11-0x30)
-#define VB_PART3_ADR              (0x12-0x30)
-#define VB_PART3_DATA             (0x13-0x30)
-#define VB_PART4_ADR              (0x14-0x30)
-#define VB_PART4_DATA             (0x15-0x30)
-
-#define SISSR                    SiS_Pr.SiS_P3c4
-#define SISCR                     SiS_Pr.SiS_P3d4
-#define SISDACA                   SiS_Pr.SiS_P3c8
-#define SISDACD                   SiS_Pr.SiS_P3c9
-#define SISPART1                  SiS_Pr.SiS_Part1Port
-#define SISPART2                  SiS_Pr.SiS_Part2Port
-#define SISPART3                  SiS_Pr.SiS_Part3Port
-#define SISPART4                  SiS_Pr.SiS_Part4Port
-#define SISPART5                  SiS_Pr.SiS_Part5Port
-#define SISDAC2A                  SISPART5
-#define SISDAC2D                  (SISPART5 + 1)
-#define SISMISCR                  (SiS_Pr.RelIO + 0x1c)
-#define SISMISCW                  SiS_Pr.SiS_P3c2
-#define SISINPSTAT               (SiS_Pr.RelIO + 0x2a)
-#define SISPEL                   SiS_Pr.SiS_P3c6
-
-#define IND_SIS_PASSWORD          0x05  /* SRs */
-#define IND_SIS_COLOR_MODE        0x06
-#define IND_SIS_RAMDAC_CONTROL    0x07
-#define IND_SIS_DRAM_SIZE         0x14
-#define IND_SIS_SCRATCH_REG_16    0x16
-#define IND_SIS_SCRATCH_REG_17    0x17
-#define IND_SIS_SCRATCH_REG_1A    0x1A
-#define IND_SIS_MODULE_ENABLE     0x1E
-#define IND_SIS_PCI_ADDRESS_SET   0x20
-#define IND_SIS_TURBOQUEUE_ADR    0x26
-#define IND_SIS_TURBOQUEUE_SET    0x27
-#define IND_SIS_POWER_ON_TRAP     0x38
-#define IND_SIS_POWER_ON_TRAP2    0x39
-#define IND_SIS_CMDQUEUE_SET      0x26
-#define IND_SIS_CMDQUEUE_THRESHOLD  0x27
-
-#define IND_SIS_SCRATCH_REG_CR30  0x30  /* CRs */
-#define IND_SIS_SCRATCH_REG_CR31  0x31
-#define IND_SIS_SCRATCH_REG_CR32  0x32
-#define IND_SIS_SCRATCH_REG_CR33  0x33
-#define IND_SIS_LCD_PANEL         0x36
-#define IND_SIS_SCRATCH_REG_CR37  0x37
-#define IND_SIS_AGP_IO_PAD        0x48
-
-#define IND_BRI_DRAM_STATUS       0x63 /* PCI config memory size offset */
-
-#define MMIO_QUEUE_PHYBASE        0x85C0
-#define MMIO_QUEUE_WRITEPORT      0x85C4
-#define MMIO_QUEUE_READPORT       0x85C8
-
-#define IND_SIS_CRT2_WRITE_ENABLE_300 0x24
-#define IND_SIS_CRT2_WRITE_ENABLE_315 0x2F
-
-#define SIS_PASSWORD              0x86  /* SR05 */
-#define SIS_INTERLACED_MODE       0x20  /* SR06 */
-#define SIS_8BPP_COLOR_MODE       0x0 
-#define SIS_15BPP_COLOR_MODE      0x1 
-#define SIS_16BPP_COLOR_MODE      0x2 
-#define SIS_32BPP_COLOR_MODE      0x4 
-#define SIS_DRAM_SIZE_MASK        0x3F  /* 300/630/730 SR14 */
-#define SIS_DRAM_SIZE_1MB         0x00
-#define SIS_DRAM_SIZE_2MB         0x01
-#define SIS_DRAM_SIZE_4MB         0x03
-#define SIS_DRAM_SIZE_8MB         0x07
-#define SIS_DRAM_SIZE_16MB        0x0F
-#define SIS_DRAM_SIZE_32MB        0x1F
-#define SIS_DRAM_SIZE_64MB        0x3F
-#define SIS_DATA_BUS_MASK         0xC0
-#define SIS_DATA_BUS_32           0x00
-#define SIS_DATA_BUS_64           0x01
-#define SIS_DATA_BUS_128          0x02
-
-#define SIS315_DATA_BUS_MASK      0x02
-#define SIS315_DATA_BUS_64        0x00
-#define SIS315_DATA_BUS_128       0x01
-#define SIS315_DUAL_CHANNEL_MASK  0x0C
-#define SIS315_SINGLE_CHANNEL_1_RANK   0x0
-#define SIS315_SINGLE_CHANNEL_2_RANK   0x1
-#define SIS315_ASYM_DDR                        0x02
-#define SIS315_DUAL_CHANNEL_1_RANK     0x3
-
-#define SIS_SCRATCH_REG_1A_MASK   0x10
-
-#define SIS_ENABLE_2D             0x40  /* SR1E */
-
-#define SIS_MEM_MAP_IO_ENABLE     0x01  /* SR20 */
-#define SIS_PCI_ADDR_ENABLE       0x80
-
-#define SIS_AGP_CMDQUEUE_ENABLE   0x80  /* 315/650/740 SR26 */
-#define SIS_VRAM_CMDQUEUE_ENABLE  0x40
-#define SIS_MMIO_CMD_ENABLE       0x20
-#define SIS_CMD_QUEUE_SIZE_512k   0x00
-#define SIS_CMD_QUEUE_SIZE_1M     0x04
-#define SIS_CMD_QUEUE_SIZE_2M     0x08
-#define SIS_CMD_QUEUE_SIZE_4M     0x0C
-#define SIS_CMD_QUEUE_RESET       0x01
-#define SIS_CMD_AUTO_CORR        0x02
-
-#define SIS_SIMULTANEOUS_VIEW_ENABLE  0x01  /* CR30 */
-#define SIS_MODE_SELECT_CRT2      0x02
-#define SIS_VB_OUTPUT_COMPOSITE   0x04
-#define SIS_VB_OUTPUT_SVIDEO      0x08
-#define SIS_VB_OUTPUT_SCART       0x10
-#define SIS_VB_OUTPUT_LCD         0x20
-#define SIS_VB_OUTPUT_CRT2        0x40
-#define SIS_VB_OUTPUT_HIVISION    0x80
-
-#define SIS_VB_OUTPUT_DISABLE     0x20  /* CR31 */
-#define SIS_DRIVER_MODE           0x40
-
-#define SIS_VB_COMPOSITE          0x01  /* CR32 */
-#define SIS_VB_SVIDEO             0x02
-#define SIS_VB_SCART              0x04
-#define SIS_VB_LCD                0x08
-#define SIS_VB_CRT2               0x10
-#define SIS_CRT1                  0x20
-#define SIS_VB_HIVISION           0x40
-#define SIS_VB_DVI                0x80
-#define SIS_VB_TV                 (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
-                                   SIS_VB_SCART | SIS_VB_HIVISION)
-
-#define SIS_EXTERNAL_CHIP_MASK            0x0E  /* CR37 (< SiS 660) */
-#define SIS_EXTERNAL_CHIP_SIS301           0x01  /* in CR37 << 1 ! */
-#define SIS_EXTERNAL_CHIP_LVDS             0x02  /* in CR37 << 1 ! */
-#define SIS_EXTERNAL_CHIP_TRUMPION         0x03  /* in CR37 << 1 ! */
-#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL    0x04  /* in CR37 << 1 ! */
-#define SIS_EXTERNAL_CHIP_CHRONTEL         0x05  /* in CR37 << 1 ! */
-#define SIS310_EXTERNAL_CHIP_LVDS          0x02  /* in CR37 << 1 ! */
-#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03  /* in CR37 << 1 ! */
-
-#define SIS_AGP_2X                0x20  /* CR48 */
-
-#define BRI_DRAM_SIZE_MASK        0x70  /* PCI bridge config data */
-#define BRI_DRAM_SIZE_2MB         0x00
-#define BRI_DRAM_SIZE_4MB         0x01
-#define BRI_DRAM_SIZE_8MB         0x02
-#define BRI_DRAM_SIZE_16MB        0x03
-#define BRI_DRAM_SIZE_32MB        0x04
-#define BRI_DRAM_SIZE_64MB        0x05
-
-#define HW_DEVICE_EXTENSION      SIS_HW_INFO
-#define PHW_DEVICE_EXTENSION      PSIS_HW_INFO
-
-#define SR_BUFFER_SIZE            5
-#define CR_BUFFER_SIZE            5
-
-/* entries for disp_state - deprecated as of 1.6.02 */
-#define DISPTYPE_CRT1       0x00000008L
-#define DISPTYPE_CRT2       0x00000004L
-#define DISPTYPE_LCD        0x00000002L
-#define DISPTYPE_TV         0x00000001L
-#define DISPTYPE_DISP1      DISPTYPE_CRT1
-#define DISPTYPE_DISP2      (DISPTYPE_CRT2 | DISPTYPE_LCD | DISPTYPE_TV)
-#define DISPMODE_SINGLE            0x00000020L
-#define DISPMODE_MIRROR            0x00000010L
-#define DISPMODE_DUALVIEW   0x00000040L
-
-/* Deprecated as of 1.6.02 - use vbflags instead */
-#define HASVB_NONE             0x00
-#define HASVB_301              0x01
-#define HASVB_LVDS             0x02
-#define HASVB_TRUMPION         0x04
-#define HASVB_LVDS_CHRONTEL    0x10
-#define HASVB_302              0x20
-#define HASVB_303              0x40
-#define HASVB_CHRONTEL         0x80
-
-/* Useful macros */
-#define inSISREG(base)          inb(base)
-#define outSISREG(base,val)     outb(val,base)
-#define orSISREG(base,val)      do { \
-                                  unsigned char __Temp = inb(base); \
-                                  outSISREG(base, __Temp | (val)); \
-                                } while (0)
-#define andSISREG(base,val)     do { \
-                                  unsigned char __Temp = inb(base); \
-                                  outSISREG(base, __Temp & (val)); \
-                                } while (0)
-#define inSISIDXREG(base,idx,var)   do { \
-                                      outb(idx,base); var=inb((base)+1); \
-                                    } while (0)
-#define outSISIDXREG(base,idx,val)  do { \
-                                      outb(idx,base); outb((val),(base)+1); \
-                                    } while (0)
-#define orSISIDXREG(base,idx,val)   do { \
-                                      unsigned char __Temp; \
-                                      outb(idx,base);   \
-                                      __Temp = inb((base)+1)|(val); \
-                                      outSISIDXREG(base,idx,__Temp); \
-                                    } while (0)
-#define andSISIDXREG(base,idx,and)  do { \
-                                      unsigned char __Temp; \
-                                      outb(idx,base);   \
-                                      __Temp = inb((base)+1)&(and); \
-                                      outSISIDXREG(base,idx,__Temp); \
-                                    } while (0)
-#define setSISIDXREG(base,idx,and,or)   do { \
-                                          unsigned char __Temp; \
-                                          outb(idx,base);   \
-                                          __Temp = (inb((base)+1)&(and))|(or); \
-                                          outSISIDXREG(base,idx,__Temp); \
-                                        } while (0)
-
-/* ------------------- Global Variables ----------------------------- */
-
-/* Fbcon variables */
-static struct fb_info *sis_fb_info;
+#define MODE_INDEX_NONE           0  /* index for mode=none */
 
-static struct fb_var_screeninfo default_var = {
+/* Fbcon stuff */
+static struct fb_var_screeninfo my_default_var = {
        .xres            = 0,
        .yres            = 0,
        .xres_virtual    = 0,
@@ -346,125 +58,110 @@ static struct fb_var_screeninfo default_var = {
        .vsync_len       = 0,
        .sync            = 0,
        .vmode           = FB_VMODE_NONINTERLACED,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       .reserved        = {0, 0, 0, 0, 0, 0}
-#endif
 };
 
+/* Boot-time parameters */
+static int sisfb_off = 0;
+static int sisfb_parm_mem = 0;
+static int sisfb_accel = -1;
+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 struct fb_fix_screeninfo sisfb_fix = {
-       .id             = "SiS",
-       .type           = FB_TYPE_PACKED_PIXELS,
-       .xpanstep       = 0,
-       .ypanstep       = 1,
-};
-static char myid[40];
-static u32 pseudo_palette[17];
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static struct display sis_disp;
-
-static struct display_switch sisfb_sw; 
-
-static struct {
-       u16 blue, green, red, pad;
-} sis_palette[256];
-
-static union {
-#ifdef FBCON_HAS_CFB16
-       u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
-       u32 cfb32[16];
+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
-} sis_fbcon_cmap;
-
-static int sisfb_inverse = 0;
-static int currcon = 0;
+#else
+static int sisfb_mode_idx = -1;               /* Use a default mode if we are inside the kernel */
 #endif
-
-/* global flags */
-static int sisfb_off = 0;
+static int sisfb_parm_rate = -1;
 static int sisfb_crt1off = 0;
 static int sisfb_forcecrt1 = -1;
-static int sisvga_enabled = 0;
-static int sisfb_userom = 1;
-static int sisfb_useoem = -1;
-static int sisfb_parm_rate = -1;
-static int sisfb_registered = 0;
-static int sisfb_mem = 0;
-static int sisfb_pdc = 0;
-static int sisfb_ypan = -1;
-static int sisfb_max = -1;
-static int sisfb_nocrt2rate = 0;
+static int sisfb_crt2type  = -1;       /* CRT2 type (for overriding autodetection) */
+static int sisfb_crt2flags = 0;
+static int sisfb_pdc = 0xff;
+static int sisfb_pdca = 0xff;
+static int sisfb_scalelcd = -1;
+static int sisfb_specialtiming = CUT_NONE;
+static int sisfb_lvdshl = -1;
 static int sisfb_dstn = 0;
 static int sisfb_fstn = 0;
+static int sisfb_tvplug = -1;          /* Tv plug type (for overriding autodetection) */
+static int sisfb_tvstd  = -1;
+static int sisfb_tvxposoffset = 0;
+static int sisfb_tvyposoffset = 0;
+static int sisfb_filter = -1;
+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;
+#endif
 
-VGA_ENGINE sisvga_engine = UNKNOWN_VGA;
-int       sisfb_accel = -1;
-
-/* These are to adapted according to VGA_ENGINE type */
-static int sisfb_hwcursor_size = 0;
-static int sisfb_CRT2_write_enable = 0;
-
-int sisfb_crt2type  = -1;      /* CRT2 type (for overriding autodetection) */
-int sisfb_tvplug    = -1;      /* Tv plug type (for overriding autodetection) */
-
-int sisfb_queuemode = -1;      /* Use MMIO queue mode by default (315 series only) */
-
-unsigned char sisfb_detectedpdc = 0;
-
-unsigned char sisfb_detectedlcda = 0xff;
-
-/* data for sis hardware ("par") */
-struct video_info ivideo;
-
-/* For ioctl SISFB_GET_INFO */
-sisfb_info sisfbinfo;
-
-/* Hardware info; contains data on hardware */
-SIS_HW_INFO sishw_ext;
+/* List of supported chips */
+static struct sisfb_chip_info {
+        int            chip;
+       int             vgaengine;
+       int             mni;
+       int             hwcursor_size;
+       int             CRT2_write_enable;
+       const char      *chip_name;
+} sisfb_chip_info[] __devinitdata = {
+       { SIS_300,    SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 300/305" },
+       { SIS_540,    SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 540" },
+       { SIS_630,    SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 630" },
+       { SIS_315H,   SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 315H" },
+       { SIS_315,    SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 315" },
+       { SIS_315PRO, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 315PRO" },
+       { SIS_550,    SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 55x" },
+       { SIS_650,    SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 650" },
+       { SIS_330,    SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 330" },
+       { SIS_660,    SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 660" },
+};
 
-/* SiS private structure */
-SiS_Private  SiS_Pr;
+static struct pci_device_id __devinitdata sisfb_pci_table[] = {
+#ifdef CONFIG_FB_SIS_300
+       { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300,     PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+       { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+#endif
+#ifdef CONFIG_FB_SIS_315
+       { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315H,    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
+       { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315,     PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
+       { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315PRO,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
+       { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
+       { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
+       { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330,     PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
+       { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
+#endif
+       { 0 }
+};
 
-/* Card parameters */
-static unsigned long sisfb_mmio_size = 0;
-static u8            sisfb_caps = 0;
+MODULE_DEVICE_TABLE(pci, sisfb_pci_table);
 
-typedef enum _SIS_CMDTYPE {
-       MMIO_CMD = 0,
-       AGP_CMD_QUEUE,
-       VM_CMD_QUEUE,
-} SIS_CMDTYPE;
+static struct sis_video_info *card_list = NULL;
 
-/* List of supported chips */
-static struct board {
-       u16 vendor, device;
-       const char *name;
-} sisdev_list[] = {
-       {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300,     "SIS 300"},
-       {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, "SIS 540 VGA"},
-       {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, "SIS 630/730 VGA"},
-       {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315H,    "SIS 315H"},
-       {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315,     "SIS 315"},
-       {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315PRO,  "SIS 315PRO"},
-       {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, "SIS 550 VGA"},
-       {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 65x/M65x/740 VGA"},
-       {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330,     "SIS 330"},
-       {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, "SIS 661FX/M661FX/741/760 VGA"},
-       {0, 0, NULL}
-};
+/* TODO: This is not handled card-wise because the DRM
+   does not refer to a unique fb when calling sis_alloc
+   or sis_free. Therefore, this is handled globally for
+   now (hoping that nobody is crazy enough to run two
+   SiS cards at the same time).
+ */
+SIS_HEAP               sisfb_heap;
 
 #define MD_SIS300 1
 #define MD_SIS315 2
 
 /* Mode table */
-/* NOT const - will be patched for 1280x768 mode number chaos reasons */
-struct _sisbios_mode {
+static const struct _sisbios_mode {
        char name[15];
-       u8 mode_no;
+       u8  mode_no[2];
        u16 vesa_mode_no_1;  /* "SiS defined" VESA mode number */
        u16 vesa_mode_no_2;  /* Real VESA mode numbers */
        u16 xres;
@@ -475,190 +172,231 @@ struct _sisbios_mode {
        u16 rows;
        u8  chipset;
 } sisbios_mode[] = {
-#define MODE_INDEX_NONE           0  /* index for mode=none */
-       {"none",         0xff, 0x0000, 0x0000,    0,    0,  0, 0,   0,  0, MD_SIS300|MD_SIS315},
-       {"320x200x8",    0x59, 0x0138, 0x0000,  320,  200,  8, 1,  40, 12, MD_SIS300|MD_SIS315},
-       {"320x200x16",   0x41, 0x010e, 0x0000,  320,  200, 16, 1,  40, 12, MD_SIS300|MD_SIS315},
-       {"320x200x24",   0x4f, 0x0000, 0x0000,  320,  200, 32, 1,  40, 12, MD_SIS300|MD_SIS315},  /* TW: That's for people who mix up color- and fb depth */
-       {"320x200x32",   0x4f, 0x0000, 0x0000,  320,  200, 32, 1,  40, 12, MD_SIS300|MD_SIS315},
-       {"320x240x8",    0x50, 0x0132, 0x0000,  320,  240,  8, 1,  40, 15, MD_SIS300|MD_SIS315},
-       {"320x240x16",   0x56, 0x0135, 0x0000,  320,  240, 16, 1,  40, 15, MD_SIS300|MD_SIS315},
-       {"320x240x24",   0x53, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
-       {"320x240x32",   0x53, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
-       {"320x240x8",    0x5a, 0x0132, 0x0000,  320,  480,  8, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
-       {"320x240x16",   0x5b, 0x0135, 0x0000,  320,  480, 16, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
-       {"400x300x8",    0x51, 0x0133, 0x0000,  400,  300,  8, 1,  50, 18, MD_SIS300|MD_SIS315},
-       {"400x300x16",   0x57, 0x0136, 0x0000,  400,  300, 16, 1,  50, 18, MD_SIS300|MD_SIS315},
-       {"400x300x24",   0x54, 0x0000, 0x0000,  400,  300, 32, 1,  50, 18, MD_SIS300|MD_SIS315},
-       {"400x300x32",   0x54, 0x0000, 0x0000,  400,  300, 32, 1,  50, 18, MD_SIS300|MD_SIS315},
-       {"512x384x8",    0x52, 0x0000, 0x0000,  512,  384,  8, 1,  64, 24, MD_SIS300|MD_SIS315},
-       {"512x384x16",   0x58, 0x0000, 0x0000,  512,  384, 16, 1,  64, 24, MD_SIS300|MD_SIS315},
-       {"512x384x24",   0x5c, 0x0000, 0x0000,  512,  384, 32, 1,  64, 24, MD_SIS300|MD_SIS315},
-       {"512x384x32",   0x5c, 0x0000, 0x0000,  512,  384, 32, 1,  64, 24, MD_SIS300|MD_SIS315},
-       {"640x400x8",    0x2f, 0x0000, 0x0000,  640,  400,  8, 1,  80, 25, MD_SIS300|MD_SIS315},
-       {"640x400x16",   0x5d, 0x0000, 0x0000,  640,  400, 16, 1,  80, 25, MD_SIS300|MD_SIS315},
-       {"640x400x24",   0x5e, 0x0000, 0x0000,  640,  400, 32, 1,  80, 25, MD_SIS300|MD_SIS315},
-       {"640x400x32",   0x5e, 0x0000, 0x0000,  640,  400, 32, 1,  80, 25, MD_SIS300|MD_SIS315},
-       {"640x480x8",    0x2e, 0x0101, 0x0101,  640,  480,  8, 1,  80, 30, MD_SIS300|MD_SIS315},
-       {"640x480x16",   0x44, 0x0111, 0x0111,  640,  480, 16, 1,  80, 30, MD_SIS300|MD_SIS315},
-       {"640x480x24",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},
-       {"640x480x32",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},
-       {"720x480x8",    0x31, 0x0000, 0x0000,  720,  480,  8, 1,  90, 30, MD_SIS300|MD_SIS315},
-       {"720x480x16",   0x33, 0x0000, 0x0000,  720,  480, 16, 1,  90, 30, MD_SIS300|MD_SIS315},
-       {"720x480x24",   0x35, 0x0000, 0x0000,  720,  480, 32, 1,  90, 30, MD_SIS300|MD_SIS315},
-       {"720x480x32",   0x35, 0x0000, 0x0000,  720,  480, 32, 1,  90, 30, MD_SIS300|MD_SIS315},
-       {"720x576x8",    0x32, 0x0000, 0x0000,  720,  576,  8, 1,  90, 36, MD_SIS300|MD_SIS315},
-       {"720x576x16",   0x34, 0x0000, 0x0000,  720,  576, 16, 1,  90, 36, MD_SIS300|MD_SIS315},
-       {"720x576x24",   0x36, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36, MD_SIS300|MD_SIS315},
-       {"720x576x32",   0x36, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36, MD_SIS300|MD_SIS315},
-       {"768x576x8",    0x5f, 0x0000, 0x0000,  768,  576,  8, 1,  96, 36, MD_SIS300|MD_SIS315},
-       {"768x576x16",   0x60, 0x0000, 0x0000,  768,  576, 16, 1,  96, 36, MD_SIS300|MD_SIS315},
-       {"768x576x24",   0x61, 0x0000, 0x0000,  768,  576, 32, 1,  96, 36, MD_SIS300|MD_SIS315},
-       {"768x576x32",   0x61, 0x0000, 0x0000,  768,  576, 32, 1,  96, 36, MD_SIS300|MD_SIS315},
-       {"800x480x8",    0x70, 0x0000, 0x0000,  800,  480,  8, 1, 100, 30, MD_SIS300|MD_SIS315},
-       {"800x480x16",   0x7a, 0x0000, 0x0000,  800,  480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
-       {"800x480x24",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
-       {"800x480x32",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
+/*0*/  {"none",         {0xff,0xff}, 0x0000, 0x0000,    0,    0,  0, 0,   0,  0, MD_SIS300|MD_SIS315},
+       {"320x200x8",    {0x59,0x59}, 0x0138, 0x0000,  320,  200,  8, 1,  40, 12, MD_SIS300|MD_SIS315},
+       {"320x200x16",   {0x41,0x41}, 0x010e, 0x0000,  320,  200, 16, 1,  40, 12, MD_SIS300|MD_SIS315},
+       {"320x200x24",   {0x4f,0x4f}, 0x0000, 0x0000,  320,  200, 32, 1,  40, 12, MD_SIS300|MD_SIS315},  /* That's for people who mix up color- and fb depth */
+       {"320x200x32",   {0x4f,0x4f}, 0x0000, 0x0000,  320,  200, 32, 1,  40, 12, MD_SIS300|MD_SIS315},
+       {"320x240x8",    {0x50,0x50}, 0x0132, 0x0000,  320,  240,  8, 1,  40, 15, MD_SIS300|MD_SIS315},
+       {"320x240x16",   {0x56,0x56}, 0x0135, 0x0000,  320,  240, 16, 1,  40, 15, MD_SIS300|MD_SIS315},
+       {"320x240x24",   {0x53,0x53}, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
+       {"320x240x32",   {0x53,0x53}, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
+       {"320x240x8",    {0x5a,0x5a}, 0x0132, 0x0000,  320,  480,  8, 1,  40, 30,           MD_SIS315},  /* FSTN */
+/*10*/ {"320x240x16",   {0x5b,0x5b}, 0x0135, 0x0000,  320,  480, 16, 1,  40, 30,           MD_SIS315},  /* FSTN */
+       {"400x300x8",    {0x51,0x51}, 0x0133, 0x0000,  400,  300,  8, 1,  50, 18, MD_SIS300|MD_SIS315},
+       {"400x300x16",   {0x57,0x57}, 0x0136, 0x0000,  400,  300, 16, 1,  50, 18, MD_SIS300|MD_SIS315},
+       {"400x300x24",   {0x54,0x54}, 0x0000, 0x0000,  400,  300, 32, 1,  50, 18, MD_SIS300|MD_SIS315},
+       {"400x300x32",   {0x54,0x54}, 0x0000, 0x0000,  400,  300, 32, 1,  50, 18, MD_SIS300|MD_SIS315},
+       {"512x384x8",    {0x52,0x52}, 0x0000, 0x0000,  512,  384,  8, 1,  64, 24, MD_SIS300|MD_SIS315},
+       {"512x384x16",   {0x58,0x58}, 0x0000, 0x0000,  512,  384, 16, 1,  64, 24, MD_SIS300|MD_SIS315},
+       {"512x384x24",   {0x5c,0x5c}, 0x0000, 0x0000,  512,  384, 32, 1,  64, 24, MD_SIS300|MD_SIS315},
+       {"512x384x32",   {0x5c,0x5c}, 0x0000, 0x0000,  512,  384, 32, 1,  64, 24, MD_SIS300|MD_SIS315},
+       {"640x400x8",    {0x2f,0x2f}, 0x0000, 0x0000,  640,  400,  8, 1,  80, 25, MD_SIS300|MD_SIS315},
+/*20*/ {"640x400x16",   {0x5d,0x5d}, 0x0000, 0x0000,  640,  400, 16, 1,  80, 25, MD_SIS300|MD_SIS315},
+       {"640x400x24",   {0x5e,0x5e}, 0x0000, 0x0000,  640,  400, 32, 1,  80, 25, MD_SIS300|MD_SIS315},
+       {"640x400x32",   {0x5e,0x5e}, 0x0000, 0x0000,  640,  400, 32, 1,  80, 25, MD_SIS300|MD_SIS315},
+       {"640x480x8",    {0x2e,0x2e}, 0x0101, 0x0101,  640,  480,  8, 1,  80, 30, MD_SIS300|MD_SIS315},
+       {"640x480x16",   {0x44,0x44}, 0x0111, 0x0111,  640,  480, 16, 1,  80, 30, MD_SIS300|MD_SIS315},
+       {"640x480x24",   {0x62,0x62}, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},
+       {"640x480x32",   {0x62,0x62}, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},
+       {"720x480x8",    {0x31,0x31}, 0x0000, 0x0000,  720,  480,  8, 1,  90, 30, MD_SIS300|MD_SIS315},
+       {"720x480x16",   {0x33,0x33}, 0x0000, 0x0000,  720,  480, 16, 1,  90, 30, MD_SIS300|MD_SIS315},
+       {"720x480x24",   {0x35,0x35}, 0x0000, 0x0000,  720,  480, 32, 1,  90, 30, MD_SIS300|MD_SIS315},
+/*30*/ {"720x480x32",   {0x35,0x35}, 0x0000, 0x0000,  720,  480, 32, 1,  90, 30, MD_SIS300|MD_SIS315},
+       {"720x576x8",    {0x32,0x32}, 0x0000, 0x0000,  720,  576,  8, 1,  90, 36, MD_SIS300|MD_SIS315},
+       {"720x576x16",   {0x34,0x34}, 0x0000, 0x0000,  720,  576, 16, 1,  90, 36, MD_SIS300|MD_SIS315},
+       {"720x576x24",   {0x36,0x36}, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36, MD_SIS300|MD_SIS315},
+       {"720x576x32",   {0x36,0x36}, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36, MD_SIS300|MD_SIS315},
+       {"768x576x8",    {0x5f,0x5f}, 0x0000, 0x0000,  768,  576,  8, 1,  96, 36, MD_SIS300|MD_SIS315},
+       {"768x576x16",   {0x60,0x60}, 0x0000, 0x0000,  768,  576, 16, 1,  96, 36, MD_SIS300|MD_SIS315},
+       {"768x576x24",   {0x61,0x61}, 0x0000, 0x0000,  768,  576, 32, 1,  96, 36, MD_SIS300|MD_SIS315},
+       {"768x576x32",   {0x61,0x61}, 0x0000, 0x0000,  768,  576, 32, 1,  96, 36, MD_SIS300|MD_SIS315},
+       {"800x480x8",    {0x70,0x70}, 0x0000, 0x0000,  800,  480,  8, 1, 100, 30, MD_SIS300|MD_SIS315},
+/*40*/ {"800x480x16",   {0x7a,0x7a}, 0x0000, 0x0000,  800,  480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
+       {"800x480x24",   {0x76,0x76}, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
+       {"800x480x32",   {0x76,0x76}, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
 #define DEFAULT_MODE              43 /* index for 800x600x8 */
 #define DEFAULT_LCDMODE           43 /* index for 800x600x8 */
 #define DEFAULT_TVMODE            43 /* index for 800x600x8 */
-       {"800x600x8",    0x30, 0x0103, 0x0103,  800,  600,  8, 2, 100, 37, MD_SIS300|MD_SIS315},
-       {"800x600x16",   0x47, 0x0114, 0x0114,  800,  600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
-       {"800x600x24",   0x63, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
-       {"800x600x32",   0x63, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
-       {"848x480x8",    0x39, 0x0000, 0x0000,  848,  480,  8, 2, 106, 30, MD_SIS300|MD_SIS315},
-       {"848x480x16",   0x3b, 0x0000, 0x0000,  848,  480, 16, 2, 106, 30, MD_SIS300|MD_SIS315},
-       {"848x480x24",   0x3e, 0x0000, 0x0000,  848,  480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
-       {"848x480x32",   0x3e, 0x0000, 0x0000,  848,  480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
-       {"856x480x8",    0x3f, 0x0000, 0x0000,  856,  480,  8, 2, 107, 30, MD_SIS300|MD_SIS315},
-       {"856x480x16",   0x42, 0x0000, 0x0000,  856,  480, 16, 2, 107, 30, MD_SIS300|MD_SIS315},
-       {"856x480x24",   0x45, 0x0000, 0x0000,  856,  480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
-       {"856x480x32",   0x45, 0x0000, 0x0000,  856,  480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
-       {"1024x576x8",   0x71, 0x0000, 0x0000, 1024,  576,  8, 1, 128, 36, MD_SIS300|MD_SIS315},
-       {"1024x576x16",  0x74, 0x0000, 0x0000, 1024,  576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
-       {"1024x576x24",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
-       {"1024x576x32",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
-       {"1024x600x8",   0x20, 0x0000, 0x0000, 1024,  600,  8, 1, 128, 37, MD_SIS300          },
-       {"1024x600x16",  0x21, 0x0000, 0x0000, 1024,  600, 16, 1, 128, 37, MD_SIS300          },
-       {"1024x600x24",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
-       {"1024x600x32",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
-       {"1024x768x8",   0x38, 0x0105, 0x0105, 1024,  768,  8, 2, 128, 48, MD_SIS300|MD_SIS315},
-       {"1024x768x16",  0x4a, 0x0117, 0x0117, 1024,  768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
-       {"1024x768x24",  0x64, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
-       {"1024x768x32",  0x64, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
-       {"1152x768x8",   0x23, 0x0000, 0x0000, 1152,  768,  8, 1, 144, 48, MD_SIS300          },
-       {"1152x768x16",  0x24, 0x0000, 0x0000, 1152,  768, 16, 1, 144, 48, MD_SIS300          },
-       {"1152x768x24",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
-       {"1152x768x32",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
-       {"1152x864x8",   0x29, 0x0000, 0x0000, 1152,  864,  8, 1, 144, 54, MD_SIS300|MD_SIS315},
-       {"1152x864x16",  0x2a, 0x0000, 0x0000, 1152,  864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
-       {"1152x864x24",  0x2b, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
-       {"1152x864x32",  0x2b, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
-       {"1280x720x8",   0x79, 0x0000, 0x0000, 1280,  720,  8, 1, 160, 45, MD_SIS300|MD_SIS315},
-       {"1280x720x16",  0x75, 0x0000, 0x0000, 1280,  720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
-       {"1280x720x24",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
-       {"1280x720x32",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
-#define MODEINDEX_1280x768 79
-       {"1280x768x8",   0x23, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48, MD_SIS300|MD_SIS315},
-       {"1280x768x16",  0x24, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48, MD_SIS300|MD_SIS315},
-       {"1280x768x24",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
-       {"1280x768x32",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
-       {"1280x960x8",   0x7c, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_SIS300|MD_SIS315},
-       {"1280x960x16",  0x7d, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
-       {"1280x960x24",  0x7e, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
-       {"1280x960x32",  0x7e, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
-       {"1280x1024x8",  0x3a, 0x0107, 0x0107, 1280, 1024,  8, 2, 160, 64, MD_SIS300|MD_SIS315},
-       {"1280x1024x16", 0x4d, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
-       {"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
-       {"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
-       {"1360x768x8",   0x48, 0x0000, 0x0000, 1360,  768,  8, 1, 170, 48, MD_SIS300|MD_SIS315},
-       {"1360x768x16",  0x4b, 0x0000, 0x0000, 1360,  768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
-       {"1360x768x24",  0x4e, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
-       {"1360x768x32",  0x4e, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
-       {"1360x1024x8",  0x67, 0x0000, 0x0000, 1360, 1024,  8, 1, 170, 64, MD_SIS300          },
-       {"1360x1024x16", 0x6f, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300          },
-       {"1360x1024x24", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
-       {"1360x1024x32", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
-       {"1400x1050x8",  0x26, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,           MD_SIS315},
-       {"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65,           MD_SIS315},
-       {"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
-       {"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
-       {"1600x1200x8",  0x3c, 0x0130, 0x011c, 1600, 1200,  8, 1, 200, 75, MD_SIS300|MD_SIS315},
-       {"1600x1200x16", 0x3d, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
-       {"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
-       {"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
-       {"1920x1440x8",  0x68, 0x013f, 0x0000, 1920, 1440,  8, 1, 240, 75, MD_SIS300|MD_SIS315},
-       {"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
-       {"1920x1440x24", 0x6b, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
-       {"1920x1440x32", 0x6b, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
-       {"2048x1536x8",  0x6c, 0x0000, 0x0000, 2048, 1536,  8, 1, 256, 96,           MD_SIS315},
-       {"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96,           MD_SIS315},
-       {"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
-       {"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
-       {"\0", 0x00, 0, 0, 0, 0, 0, 0, 0}
+       {"800x600x8",    {0x30,0x30}, 0x0103, 0x0103,  800,  600,  8, 2, 100, 37, MD_SIS300|MD_SIS315},
+       {"800x600x16",   {0x47,0x47}, 0x0114, 0x0114,  800,  600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
+       {"800x600x24",   {0x63,0x63}, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
+       {"800x600x32",   {0x63,0x63}, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
+       {"848x480x8",    {0x39,0x39}, 0x0000, 0x0000,  848,  480,  8, 2, 106, 30, MD_SIS300|MD_SIS315},
+       {"848x480x16",   {0x3b,0x3b}, 0x0000, 0x0000,  848,  480, 16, 2, 106, 30, MD_SIS300|MD_SIS315},
+       {"848x480x24",   {0x3e,0x3e}, 0x0000, 0x0000,  848,  480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
+/*50*/ {"848x480x32",   {0x3e,0x3e}, 0x0000, 0x0000,  848,  480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
+       {"856x480x8",    {0x3f,0x3f}, 0x0000, 0x0000,  856,  480,  8, 2, 107, 30, MD_SIS300|MD_SIS315},
+       {"856x480x16",   {0x42,0x42}, 0x0000, 0x0000,  856,  480, 16, 2, 107, 30, MD_SIS300|MD_SIS315},
+       {"856x480x24",   {0x45,0x45}, 0x0000, 0x0000,  856,  480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
+       {"856x480x32",   {0x45,0x45}, 0x0000, 0x0000,  856,  480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
+       {"960x540x8",    {0x1d,0x1d}, 0x0000, 0x0000,  960,  540,  8, 1, 120, 33,           MD_SIS315},
+       {"960x540x16",   {0x1e,0x1e}, 0x0000, 0x0000,  960,  540, 16, 1, 120, 33,           MD_SIS315},
+       {"960x540x24",   {0x1f,0x1f}, 0x0000, 0x0000,  960,  540, 32, 1, 120, 33,           MD_SIS315},
+       {"960x540x32",   {0x1f,0x1f}, 0x0000, 0x0000,  960,  540, 32, 1, 120, 33,           MD_SIS315},
+       {"1024x576x8",   {0x71,0x71}, 0x0000, 0x0000, 1024,  576,  8, 1, 128, 36, MD_SIS300|MD_SIS315},
+/*60*/ {"1024x576x16",  {0x74,0x74}, 0x0000, 0x0000, 1024,  576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
+       {"1024x576x24",  {0x77,0x77}, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
+       {"1024x576x32",  {0x77,0x77}, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
+       {"1024x600x8",   {0x20,0x20}, 0x0000, 0x0000, 1024,  600,  8, 1, 128, 37, MD_SIS300          },
+       {"1024x600x16",  {0x21,0x21}, 0x0000, 0x0000, 1024,  600, 16, 1, 128, 37, MD_SIS300          },
+       {"1024x600x24",  {0x22,0x22}, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
+       {"1024x600x32",  {0x22,0x22}, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
+       {"1024x768x8",   {0x38,0x38}, 0x0105, 0x0105, 1024,  768,  8, 2, 128, 48, MD_SIS300|MD_SIS315},
+       {"1024x768x16",  {0x4a,0x4a}, 0x0117, 0x0117, 1024,  768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
+       {"1024x768x24",  {0x64,0x64}, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
+/*70*/ {"1024x768x32",  {0x64,0x64}, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
+       {"1152x768x8",   {0x23,0x23}, 0x0000, 0x0000, 1152,  768,  8, 1, 144, 48, MD_SIS300          },
+       {"1152x768x16",  {0x24,0x24}, 0x0000, 0x0000, 1152,  768, 16, 1, 144, 48, MD_SIS300          },
+       {"1152x768x24",  {0x25,0x25}, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
+       {"1152x768x32",  {0x25,0x25}, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
+       {"1152x864x8",   {0x29,0x29}, 0x0000, 0x0000, 1152,  864,  8, 1, 144, 54, MD_SIS300|MD_SIS315},
+       {"1152x864x16",  {0x2a,0x2a}, 0x0000, 0x0000, 1152,  864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
+       {"1152x864x24",  {0x2b,0x2b}, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
+       {"1152x864x32",  {0x2b,0x2b}, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
+       {"1280x720x8",   {0x79,0x79}, 0x0000, 0x0000, 1280,  720,  8, 1, 160, 45, MD_SIS300|MD_SIS315},
+/*80*/ {"1280x720x16",  {0x75,0x75}, 0x0000, 0x0000, 1280,  720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
+       {"1280x720x24",  {0x78,0x78}, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
+       {"1280x720x32",  {0x78,0x78}, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
+       {"1280x768x8",   {0x55,0x23}, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48, MD_SIS300|MD_SIS315},
+       {"1280x768x16",  {0x5a,0x24}, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48, MD_SIS300|MD_SIS315},
+       {"1280x768x24",  {0x5b,0x25}, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
+       {"1280x768x32",  {0x5b,0x25}, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
+       {"1280x800x8",   {0x14,0x14}, 0x0000, 0x0000, 1280,  800,  8, 1, 160, 50,           MD_SIS315},
+       {"1280x800x16",  {0x15,0x15}, 0x0000, 0x0000, 1280,  800, 16, 1, 160, 50,           MD_SIS315},
+       {"1280x800x24",  {0x16,0x16}, 0x0000, 0x0000, 1280,  800, 32, 1, 160, 50,           MD_SIS315},
+/*90*/ {"1280x800x32",  {0x16,0x16}, 0x0000, 0x0000, 1280,  800, 32, 1, 160, 50,           MD_SIS315},
+       {"1280x960x8",   {0x7c,0x7c}, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_SIS300|MD_SIS315},
+       {"1280x960x16",  {0x7d,0x7d}, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
+       {"1280x960x24",  {0x7e,0x7e}, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
+       {"1280x960x32",  {0x7e,0x7e}, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
+       {"1280x1024x8",  {0x3a,0x3a}, 0x0107, 0x0107, 1280, 1024,  8, 2, 160, 64, MD_SIS300|MD_SIS315},
+       {"1280x1024x16", {0x4d,0x4d}, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
+       {"1280x1024x24", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
+       {"1280x1024x32", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
+       {"1360x768x8",   {0x48,0x48}, 0x0000, 0x0000, 1360,  768,  8, 1, 170, 48, MD_SIS300|MD_SIS315},
+/*100*/        {"1360x768x16",  {0x4b,0x4b}, 0x0000, 0x0000, 1360,  768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
+       {"1360x768x24",  {0x4e,0x4e}, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
+       {"1360x768x32",  {0x4e,0x4e}, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
+       {"1360x1024x8",  {0x67,0x67}, 0x0000, 0x0000, 1360, 1024,  8, 1, 170, 64, MD_SIS300          },
+       {"1360x1024x16", {0x6f,0x6f}, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300          },
+       {"1360x1024x24", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
+       {"1360x1024x32", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
+       {"1400x1050x8",  {0x26,0x26}, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,           MD_SIS315},
+       {"1400x1050x16", {0x27,0x27}, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65,           MD_SIS315},
+       {"1400x1050x24", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
+/*110*/        {"1400x1050x32", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
+       {"1600x1200x8",  {0x3c,0x3c}, 0x0130, 0x011c, 1600, 1200,  8, 1, 200, 75, MD_SIS300|MD_SIS315},
+       {"1600x1200x16", {0x3d,0x3d}, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
+       {"1600x1200x24", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
+       {"1600x1200x32", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
+       {"1680x1050x8",  {0x17,0x17}, 0x0000, 0x0000, 1680, 1050,  8, 1, 210, 65,           MD_SIS315},
+       {"1680x1050x16", {0x18,0x18}, 0x0000, 0x0000, 1680, 1050, 16, 1, 210, 65,           MD_SIS315},
+       {"1680x1050x24", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65,           MD_SIS315},
+       {"1680x1050x32", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65,           MD_SIS315},
+       {"1920x1080x8",  {0x2c,0x2c}, 0x0000, 0x0000, 1920, 1080,  8, 1, 240, 67,           MD_SIS315},
+/*120*/        {"1920x1080x16", {0x2d,0x2d}, 0x0000, 0x0000, 1920, 1080, 16, 1, 240, 67,           MD_SIS315},
+       {"1920x1080x24", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67,           MD_SIS315},
+       {"1920x1080x32", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67,           MD_SIS315},
+       {"1920x1440x8",  {0x68,0x68}, 0x013f, 0x0000, 1920, 1440,  8, 1, 240, 75, MD_SIS300|MD_SIS315},
+       {"1920x1440x16", {0x69,0x69}, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
+       {"1920x1440x24", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+       {"1920x1440x32", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+       {"2048x1536x8",  {0x6c,0x6c}, 0x0000, 0x0000, 2048, 1536,  8, 1, 256, 96,           MD_SIS315},
+       {"2048x1536x16", {0x6d,0x6d}, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96,           MD_SIS315},
+       {"2048x1536x24", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
+/*130*/        {"2048x1536x32", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
+       {"\0", {0x00,0x00}, 0, 0, 0, 0, 0, 0, 0}
 };
 
-/* mode-related variables */
-#ifdef MODULE
-int sisfb_mode_idx = MODE_INDEX_NONE;  /* Don't use a mode by default if we are a module */
-#else
-int sisfb_mode_idx = -1;               /* Use a default mode if we are inside the kernel */
-#endif
-u8  sisfb_mode_no  = 0;
-u8  sisfb_rate_idx = 0;
+#define SIS_LCD_NUMBER 17
+static const struct _sis_lcd_data {
+       u32 lcdtype;
+       u16 xres;
+       u16 yres;
+       u8  default_mode_idx;
+} sis_lcd_data[] = {
+       { LCD_640x480,    640,  480,  23 },
+       { LCD_800x600,    800,  600,  43 },
+       { LCD_1024x600,  1024,  600,  63 },
+       { LCD_1024x768,  1024,  768,  67 },
+       { LCD_1152x768,  1152,  768,  71 },
+       { LCD_1152x864,  1152,  864,  75 },
+       { LCD_1280x720,  1280,  720,  79 },
+       { LCD_1280x768,  1280,  768,  83 },
+       { LCD_1280x800,  1280,  800,  87 },
+       { LCD_1280x960,  1280,  960,  91 },
+       { LCD_1280x1024, 1280, 1024,  95 },
+       { LCD_1400x1050, 1400, 1050, 107 },
+       { LCD_1680x1050, 1680, 1050, 115 },
+       { LCD_1600x1200, 1600, 1200, 111 },
+       { LCD_640x480_2,  640,  480,  23 },
+       { LCD_640x480_3,  640,  480,  23 },
+       { LCD_320x480,    320,  480,   9 },
+};
 
 /* CR36 evaluation */
 const USHORT sis300paneltype[] =
     { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
       LCD_1280x960,  LCD_640x480,   LCD_1024x600,  LCD_1152x768,
-      LCD_1024x768,  LCD_1024x768,  LCD_1024x768,  LCD_1024x768,
-      LCD_1024x768,  LCD_1024x768,  LCD_320x480,   LCD_1024x768 };
+      LCD_UNKNOWN,   LCD_UNKNOWN,   LCD_UNKNOWN,   LCD_UNKNOWN,
+      LCD_UNKNOWN,   LCD_UNKNOWN,   LCD_UNKNOWN,   LCD_UNKNOWN };
 
 const USHORT sis310paneltype[] =
     { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
       LCD_640x480,   LCD_1024x600,  LCD_1152x864,  LCD_1280x960,
       LCD_1152x768,  LCD_1400x1050, LCD_1280x768,  LCD_1600x1200,
-      LCD_640x480_2, LCD_640x480_3, LCD_320x480,   LCD_1024x768 };
+      LCD_640x480_2, LCD_640x480_3, LCD_UNKNOWN,   LCD_UNKNOWN };
+
+const USHORT sis661paneltype[] =
+    { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
+      LCD_640x480,   LCD_1024x600,  LCD_1152x864,  LCD_1280x960,
+      LCD_1152x768,  LCD_1400x1050, LCD_1280x768,  LCD_1600x1200,
+      LCD_1280x800,  LCD_1680x1050, LCD_1280x720,  LCD_UNKNOWN };
 
 #define FL_550_DSTN 0x01
 #define FL_550_FSTN 0x02
-
-static const struct _sis_crt2type {
-       char name[10];
-       int type_no;
-       int tvplug_no;
-       unsigned short flags;
-} sis_crt2type[] = {
-       {"NONE",        0,              -1,        0},
-       {"LCD",         CRT2_LCD,       -1,        0},
-       {"TV",          CRT2_TV,        -1,        0},
-       {"VGA",         CRT2_VGA,       -1,        0},
-       {"SVIDEO",      CRT2_TV,        TV_SVIDEO, 0},
-       {"COMPOSITE",   CRT2_TV,        TV_AVIDEO, 0},
-       {"SCART",       CRT2_TV,        TV_SCART,  0},
-       {"DSTN",        CRT2_LCD,       -1,        FL_550_DSTN},
-       {"FSTN",        CRT2_LCD,       -1,        FL_550_FSTN},
-       {"\0",          -1,             -1,        0}
-};
-
-/* Queue mode selection for 310 series */
-static const struct _sis_queuemode {
-       char name[6];
-       int type_no;
-} sis_queuemode[] = {
-       {"AGP",         AGP_CMD_QUEUE},
-       {"VRAM",        VM_CMD_QUEUE},
-       {"MMIO",        MMIO_CMD},
-       {"\0",          -1}
+#define FL_300      0x04
+#define FL_315      0x08
+
+static struct _sis_crt2type {
+       char name[32];
+       u32 type_no;
+       u32 tvplug_no;
+       u16 flags;
+} sis_crt2type[] __initdata = {
+       {"NONE",             0,         -1,                     FL_300|FL_315},
+       {"LCD",              CRT2_LCD,  -1,                     FL_300|FL_315},
+       {"TV",               CRT2_TV,   -1,                     FL_300|FL_315},
+       {"VGA",              CRT2_VGA,  -1,                     FL_300|FL_315},
+       {"SVIDEO",           CRT2_TV,   TV_SVIDEO,              FL_300|FL_315},
+       {"COMPOSITE",        CRT2_TV,   TV_AVIDEO,              FL_300|FL_315},
+       {"CVBS",             CRT2_TV,   TV_AVIDEO,              FL_300|FL_315},
+       {"SVIDEO+COMPOSITE", CRT2_TV,   TV_AVIDEO|TV_SVIDEO,    FL_300|FL_315},
+       {"COMPOSITE+SVIDEO", CRT2_TV,   TV_AVIDEO|TV_SVIDEO,    FL_300|FL_315},
+       {"SVIDEO+CVBS",      CRT2_TV,   TV_AVIDEO|TV_SVIDEO,    FL_300|FL_315},
+       {"CVBS+SVIDEO",      CRT2_TV,   TV_AVIDEO|TV_SVIDEO,    FL_300|FL_315},
+       {"SCART",            CRT2_TV,   TV_SCART,               FL_300|FL_315},
+       {"HIVISION",         CRT2_TV,   TV_HIVISION,            FL_315},
+       {"YPBPR480I",        CRT2_TV,   TV_YPBPR|TV_YPBPR525I,  FL_315},
+       {"YPBPR480P",        CRT2_TV,   TV_YPBPR|TV_YPBPR525P,  FL_315},
+       {"YPBPR720P",        CRT2_TV,   TV_YPBPR|TV_YPBPR750P,  FL_315},
+       {"YPBPR1080I",       CRT2_TV,   TV_YPBPR|TV_YPBPR1080I, FL_315},
+       {"DSTN",             CRT2_LCD,  -1,                     FL_315|FL_550_DSTN},
+       {"FSTN",             CRT2_LCD,  -1,                     FL_315|FL_550_FSTN},
+       {"\0",               -1,        -1,                     0}
 };
 
 /* TV standard */
-static const struct _sis_tvtype {
+static struct _sis_tvtype {
        char name[6];
-       int type_no;
-} sis_tvtype[] = {
+       u32 type_no;
+} sis_tvtype[] __initdata = {
        {"PAL",         TV_PAL},
        {"NTSC",        TV_NTSC},
+       {"PALM",        TV_PAL|TV_PALM},
+       {"PALN",        TV_PAL|TV_PALN},
+       {"NTSCJ",       TV_NTSC|TV_NTSCJ},
        {"\0",          -1}
 };
 
@@ -687,6 +425,7 @@ static const struct _sis_vrate {
        {7,  800,  600, 120,  TRUE}, {8,  800,  600, 160,  TRUE},
        {1,  848,  480,  39,  TRUE}, {2,  848,  480,  60,  TRUE},
        {1,  856,  480,  39,  TRUE}, {2,  856,  480,  60,  TRUE},
+       {1,  960,  540,  60,  TRUE},
        {1, 1024,  576,  60,  TRUE}, {2, 1024,  576,  75,  TRUE}, {3, 1024,  576,  85,  TRUE},
        {1, 1024,  600,  60,  TRUE},
        {1, 1024,  768,  43,  TRUE}, {2, 1024,  768,  60,  TRUE}, {3, 1024,  768,  70, FALSE},
@@ -696,6 +435,7 @@ static const struct _sis_vrate {
        {1, 1152,  864,  75,  TRUE}, {2, 1152,  864,  84,  TRUE},
        {1, 1280,  720,  60,  TRUE}, {2, 1280,  720,  75,  TRUE}, {3, 1280,  720,  85,  TRUE},
        {1, 1280,  768,  60,  TRUE},
+       {1, 1280,  800,  60,  TRUE},
        {1, 1280,  960,  60,  TRUE}, {2, 1280,  960,  85,  TRUE},
        {1, 1280, 1024,  43,  TRUE}, {2, 1280, 1024,  60,  TRUE}, {3, 1280, 1024,  75,  TRUE},
        {4, 1280, 1024,  85,  TRUE},
@@ -705,6 +445,8 @@ static const struct _sis_vrate {
        {1, 1600, 1200,  60,  TRUE}, {2, 1600, 1200,  65,  TRUE}, {3, 1600, 1200,  70,  TRUE},
        {4, 1600, 1200,  75,  TRUE}, {5, 1600, 1200,  85,  TRUE}, {6, 1600, 1200, 100,  TRUE},
        {7, 1600, 1200, 120,  TRUE},
+       {1, 1680, 1050,  60,  TRUE},
+       {1, 1920, 1080,  30,  TRUE},
        {1, 1920, 1440,  60,  TRUE}, {2, 1920, 1440,  65,  TRUE}, {3, 1920, 1440,  70,  TRUE},
        {4, 1920, 1440,  75,  TRUE}, {5, 1920, 1440,  85,  TRUE}, {6, 1920, 1440, 100,  TRUE},
        {1, 2048, 1536,  60,  TRUE}, {2, 2048, 1536,  65,  TRUE}, {3, 2048, 1536,  70,  TRUE},
@@ -712,16 +454,6 @@ static const struct _sis_vrate {
        {0,    0,    0,   0, FALSE}
 };
 
-static struct sisfb_monitor {
-       u16 hmin;
-       u16 hmax;
-       u16 vmin;
-       u16 vmax;
-       u32 dclockmax;
-       u8  feature;
-       BOOLEAN datavalid;
-} sisfb_thismonitor;
-
 static const struct _sisfbddcsmodes {
        u32 mask;
        u16 h;
@@ -760,35 +492,33 @@ static const struct _sisfbddcfmodes {
        { 1920, 1440, 75, 113,297000}
 };
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-static u8 sisfb_lastrates[128];
-#endif
-
-static const struct _chswtable {
-    int subsysVendor;
-    int subsysCard;
+#ifdef CONFIG_FB_SIS_300
+static struct _chswtable {
+    u16  subsysVendor;
+    u16  subsysCard;
     char *vendorName;
     char *cardName;
-} mychswtable[] = {
+} mychswtable[] __devinitdata = {
         { 0x1631, 0x1002, "Mitachi", "0x1002" },
        { 0x1071, 0x7521, "Mitac"  , "7521P"  },
        { 0,      0,      ""       , ""       }
 };
+#endif
 
-static const struct _customttable {
-    unsigned short chipID;
-    char *biosversion;
-    char *biosdate;
-    unsigned long bioschksum;
-    unsigned short biosFootprintAddr[5];
-    unsigned char biosFootprintData[5];
-    unsigned short pcisubsysvendor;
-    unsigned short pcisubsyscard;
-    char *vendorName;
-    char *cardName;
-    unsigned long SpecialID;
-    char *optionName;
-} mycustomttable[] = {
+static struct _customttable {
+    u16   chipID;
+    char  *biosversion;
+    char  *biosdate;
+    u32   bioschksum;
+    u16   biosFootprintAddr[5];
+    u8    biosFootprintData[5];
+    u16   pcisubsysvendor;
+    u16   pcisubsyscard;
+    char  *vendorName;
+    char  *cardName;
+    u32   SpecialID;
+    char  *optionName;
+} mycustomttable[] __devinitdata = {
        { SIS_630, "2.00.07", "09/27/2002-13:38:25",
          0x3240A8,
          { 0x220, 0x227, 0x228, 0x229, 0x0ee },
@@ -917,46 +647,6 @@ static const struct _customttable {
        }
 };
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-/* Offscreen layout */
-typedef struct _SIS_GLYINFO {
-       unsigned char ch;
-       int fontwidth;
-       int fontheight;
-       u8 gmask[72];
-       int ngmask;
-} SIS_GLYINFO;
-
-static char sisfb_fontname[40];
-#endif
-
-typedef struct _SIS_OH {
-       struct _SIS_OH *poh_next;
-       struct _SIS_OH *poh_prev;
-       unsigned long offset;
-       unsigned long size;
-} SIS_OH;
-
-typedef struct _SIS_OHALLOC {
-       struct _SIS_OHALLOC *poha_next;
-       SIS_OH aoh[1];
-} SIS_OHALLOC;
-
-typedef struct _SIS_HEAP {
-       SIS_OH oh_free;
-       SIS_OH oh_used;
-       SIS_OH *poh_freelist;
-       SIS_OHALLOC *poha_chain;
-       unsigned long max_freesize;
-} SIS_HEAP;
-
-static unsigned long sisfb_hwcursor_vbase;
-
-static unsigned long sisfb_heap_start;
-static unsigned long sisfb_heap_end;
-static unsigned long sisfb_heap_size;
-static SIS_HEAP      sisfb_heap;
-
 static const struct _sis_TV_filter {
        u8 filter[9][4];
 } sis_TV_filter[] = {
@@ -1106,9 +796,6 @@ static const struct _sis_TV_filter {
           {0xFF,0xFF,0xFF,0xFF} }}
 };
 
-static int           filter = -1;
-static unsigned char filter_tb;
-
 /* ---------------------- Prototypes ------------------------- */
 
 /* Interface used by the world */
@@ -1119,7 +806,11 @@ int             sisfb_setup(char *options);
 /* Interface to the low level console driver */
 int             sisfb_init(void);
 
+
 /* fbdev routines */
+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,
@@ -1130,7 +821,8 @@ static int      sisfb_get_var(struct fb_var_screeninfo *var,
 static int      sisfb_set_var(struct fb_var_screeninfo *var, 
                              int con,
                              struct fb_info *info);
-static void     sisfb_crtc_to_var(struct fb_var_screeninfo *var);                            
+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,
@@ -1153,108 +845,67 @@ static int      sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
                              struct fb_info *fb_info);
 static void     sisfb_do_install_cmap(int con, 
                                       struct fb_info *info);
-static void     sis_get_glyph(struct fb_info *info, 
-                              SIS_GLYINFO *gly);
-static int     sisfb_mmap(struct fb_info *info, struct file *file,
-                          struct vm_area_struct *vma); 
 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)
+static int      sisfb_ioctl(struct inode *inode, struct file *file,
+                           unsigned int cmd, unsigned long arg,
+                           struct fb_info *info);
 static int      sisfb_set_par(struct fb_info *info);
 static int      sisfb_blank(int blank, 
                             struct fb_info *info);                     
-static int     sisfb_mmap(struct fb_info *info, struct file *file,
-                          struct vm_area_struct *vma);                     
 extern void     fbcon_sis_fillrect(struct fb_info *info, 
                                    const struct fb_fillrect *rect);
 extern void     fbcon_sis_copyarea(struct fb_info *info, 
                                    const struct fb_copyarea *area);
 extern int      fbcon_sis_sync(struct fb_info *info);
-static int      sisfb_ioctl(struct inode *inode, 
-                           struct file *file,
-                           unsigned int cmd, 
-                           unsigned long arg, 
-                           struct fb_info *info);
-extern int     sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, 
-                             PSIS_HW_INFO HwDeviceExtension,
-                             unsigned char modeno, unsigned char rateindex);   
-extern int      sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
-                        unsigned char modeno, unsigned char rateindex,
-                        unsigned int *left_margin, unsigned int *right_margin, 
-                        unsigned int *upper_margin, unsigned int *lower_margin,
-                        unsigned int *hsync_len, unsigned int *vsync_len,
-                        unsigned int *sync, unsigned int *vmode);
 #endif
                        
-static int      sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-                             struct fb_info *info);
-
 /* Internal 2D accelerator functions */
-extern int      sisfb_initaccel(void);
-extern void     sisfb_syncaccel(void);
+extern int      sisfb_initaccel(struct sis_video_info *ivideo);
+extern void     sisfb_syncaccel(struct sis_video_info *ivideo);
 
 /* Internal general routines */
 static void     sisfb_search_mode(char *name, BOOLEAN quiet);
-static int      sisfb_validate_mode(int modeindex, unsigned long vbflags);
-static u8       sisfb_search_refresh_rate(unsigned int rate, int index);
+static int      sisfb_validate_mode(struct sis_video_info *ivideo, int modeindex, u32 vbflags);
+static u8       sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate,
+                       int index);
 static int      sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
                        unsigned blue, unsigned transp,
                        struct fb_info *fb_info);
 static int      sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
                        struct fb_info *info);
-static void     sisfb_pre_setmode(void);
-static void     sisfb_post_setmode(void);
-
-static char *   sis_find_rom(void);
-static BOOLEAN  sisfb_CheckVBRetrace(void);
-static BOOLEAN  sisfbcheckvretracecrt2(void);
-static BOOLEAN  sisfbcheckvretracecrt1(void);
-static BOOLEAN  sisfb_bridgeisslave(void);
-static void     sisfb_detect_VB_connect(void);
-static void     sisfb_get_VB_type(void);
-
-static void     sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno);
-static BOOLEAN  sisfb_interpret_edid(struct sisfb_monitor *monitor, unsigned char *buffer);
-
-/* SiS-specific Export functions */
-void            sis_dispinfo(struct ap_data *rec);
+static void     sisfb_pre_setmode(struct sis_video_info *ivideo);
+static void     sisfb_post_setmode(struct sis_video_info *ivideo);
+static char *   sis_find_rom(struct pci_dev *pdev);
+static BOOLEAN  sisfb_CheckVBRetrace(struct sis_video_info *ivideo);
+static BOOLEAN  sisfbcheckvretracecrt2(struct sis_video_info *ivideo);
+static BOOLEAN  sisfbcheckvretracecrt1(struct sis_video_info *ivideo);
+static BOOLEAN  sisfb_bridgeisslave(struct sis_video_info *ivideo);
+static void     sisfb_detect_VB_connect(struct sis_video_info *ivideo);
+static void     sisfb_get_VB_type(struct sis_video_info *ivideo);
+static void     sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val);
+static void     sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val);
+
+/* SiS-specific exported functions */
 void            sis_malloc(struct sis_memreq *req);
-void            sis_free(unsigned long base);
-
-/* Internal hardware access routines */
-void            sisfb_set_reg4(u16 port, unsigned long data);
-u32             sisfb_get_reg3(u16 port);
-
-/* Chipset-dependent internal routines */
-#ifdef CONFIG_FB_SIS_300
-static int      sisfb_get_dram_size_300(void);
-#endif
-#ifdef CONFIG_FB_SIS_315
-static int      sisfb_get_dram_size_315(void);
-#endif
+void            sis_free(u32 base);
 
 /* Internal heap routines */
-static int      sisfb_heap_init(void);
+static int      sisfb_heap_init(struct sis_video_info *ivideo);
 static SIS_OH   *sisfb_poh_new_node(void);
-static SIS_OH   *sisfb_poh_allocate(unsigned long size);
+static SIS_OH   *sisfb_poh_allocate(u32 size);
 static void     sisfb_delete_node(SIS_OH *poh);
 static void     sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh);
-static SIS_OH   *sisfb_poh_free(unsigned long base);
+static SIS_OH   *sisfb_poh_free(u32 base);
 static void     sisfb_free_node(SIS_OH *poh);
 
-/* Internal routines to access PCI configuration space */
-BOOLEAN         sisfb_query_VGA_config_space(PSIS_HW_INFO psishw_ext,
-                       unsigned long offset, unsigned long set, unsigned long *value);
-BOOLEAN         sisfb_query_north_bridge_space(PSIS_HW_INFO psishw_ext,
-                       unsigned long offset, unsigned long set, unsigned long *value);
-
 /* Sensing routines */
-static void     SiS_Sense30x(void);
-static int      SISDoSense(int tempbl, int tempbh, int tempcl, int tempch);
-static void     SiS_SenseCh(void);
+static void     SiS_Sense30x(struct sis_video_info *ivideo);
+static void     SiS_SenseCh(struct sis_video_info *ivideo);
 
 /* Routines from init.c/init301.c */
 extern USHORT   SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN);
@@ -1268,10 +919,20 @@ extern BOOLEAN  SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo, USHOR
 extern void     SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
 extern void     SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
 
+extern BOOLEAN  SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+
 extern BOOLEAN  sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
                       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(SiS_Private *SiS_Pr,
+                       PSIS_HW_INFO HwDeviceExtension,
+                       unsigned char modeno, unsigned char rateindex);
+extern int      sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
+                       unsigned char modeno, unsigned char rateindex,
+                       struct fb_var_screeninfo *var);
+#endif
 
-/* Chrontel TV functions */
+/* Chrontel TV, DDC and DPMS functions */
 extern USHORT  SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
 extern void    SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
 extern USHORT  SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
@@ -1279,13 +940,13 @@ extern void      SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
 extern void     SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
 extern void     SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
 extern void     SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
-extern USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+extern USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine,
                              USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
 extern USHORT   SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
 extern void    SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
 extern void    SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
 extern void    SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
 extern void    SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
-
-                       
 #endif
+
+
index 9e96c3b..ca7caf0 100644 (file)
@@ -1,4 +1,5 @@
 /* $XFree86$ */
+/* $XdotOrg$ */
 /*
  * General type definitions for universal mode switching modules
  *
  * * 2) Redistributions in binary form must reproduce the above copyright
  * *    notice, this list of conditions and the following disclaimer in the
  * *    documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * *    must display the following acknowledgement: "This product includes
- * *    software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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,
@@ -121,21 +119,17 @@ typedef IOADDRESS SISIOADDRESS;
 #endif
 #endif
 
-#ifndef LINUX_KERNEL   /* For the linux kernel, this is defined in sisfb.h */
-#ifndef SIS_CHIP_TYPE
-typedef enum _SIS_CHIP_TYPE {
+enum _SIS_CHIP_TYPE {
     SIS_VGALegacy = 0,
-#ifdef LINUX_XF86
     SIS_530,
     SIS_OLD,
-#endif
     SIS_300,
     SIS_630,
     SIS_730,
     SIS_540,
     SIS_315H,   /* SiS 310 */
     SIS_315,
-    SIS_315PRO, /* SiS 325 */
+    SIS_315PRO,
     SIS_550,
     SIS_650,
     SIS_740,
@@ -144,29 +138,13 @@ typedef enum _SIS_CHIP_TYPE {
     SIS_741,
     SIS_660,
     SIS_760,
+    SIS_761,
+    SIS_340,
     MAX_SIS_CHIP
-} SIS_CHIP_TYPE;
-#endif
-#endif
-
-#ifndef SIS_VB_CHIP_TYPE
-typedef enum _SIS_VB_CHIP_TYPE {
-    VB_CHIP_Legacy = 0,
-    VB_CHIP_301,
-    VB_CHIP_301B,
-    VB_CHIP_301LV,
-    VB_CHIP_302,
-    VB_CHIP_302B,
-    VB_CHIP_302LV,
-    VB_CHIP_301C,
-    VB_CHIP_302ELV,
-    VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */
-    MAX_VB_CHIP
-} SIS_VB_CHIP_TYPE;
-#endif
+};
 
-#ifndef SIS_LCD_TYPE
-typedef enum _SIS_LCD_TYPE {
+#ifdef LINUX_KERNEL
+enum _SIS_LCD_TYPE {
     LCD_INVALID = 0,
     LCD_800x600,
     LCD_1024x768,
@@ -176,28 +154,22 @@ typedef enum _SIS_LCD_TYPE {
     LCD_1600x1200,
     LCD_1920x1440,
     LCD_2048x1536,
-    LCD_320x480,       /* FSTN, DSTN */
+    LCD_320x480,       /* FSTN */
     LCD_1400x1050,
     LCD_1152x864,
     LCD_1152x768,
     LCD_1280x768,
     LCD_1024x600,
-    LCD_640x480_2,     /* FSTN, DSTN */
-    LCD_640x480_3,     /* FSTN, DSTN */
+    LCD_640x480_2,     /* DSTN */
+    LCD_640x480_3,     /* DSTN */
     LCD_848x480,
     LCD_1280x800,
     LCD_1680x1050,
+    LCD_1280x720,
     LCD_CUSTOM,
     LCD_UNKNOWN
-} SIS_LCD_TYPE;
-#endif
-
-#ifndef PSIS_DSReg
-typedef struct _SIS_DSReg
-{
-  UCHAR  jIdx;
-  UCHAR  jVal;
-} SIS_DSReg, *PSIS_DSReg;
+};
+typedef unsigned int SIS_LCD_TYPE;
 #endif
 
 #ifndef SIS_HW_INFO
@@ -220,97 +192,84 @@ struct _SIS_HW_INFO
                                  /* of Linear VGA memory */
 
     ULONG  ulVideoMemorySize;    /* size, in bytes, of the memory on the board */
-    SISIOADDRESS ulIOAddress;    /* base I/O address of VGA ports (0x3B0) */
+
+    SISIOADDRESS ulIOAddress;    /* base I/O address of VGA ports (0x3B0; relocated) */
+
     UCHAR  jChipType;            /* Used to Identify SiS Graphics Chip */
-                                 /* defined in the data structure type  */
-                                 /* "SIS_CHIP_TYPE" */
+                                 /* defined in the enum "SIS_CHIP_TYPE" (above or sisfb.h) */
 
     UCHAR  jChipRevision;        /* Used to Identify SiS Graphics Chip Revision */
-    UCHAR  ujVBChipID;           /* the ID of video bridge */
-                                 /* defined in the data structure type */
-                                 /* "SIS_VB_CHIP_TYPE" */
-#ifdef LINUX_KERNEL
-    BOOLEAN Is301BDH;
-#endif
 
-    USHORT usExternalChip;       /* NO VB or other video bridge (other than  */
-                                 /* SiS video bridge) */
-
-    ULONG  ulCRT2LCDType;        /* defined in the data structure type */
-                                 /* "SIS_LCD_TYPE" */
-                                     
     BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
-                                      
-    BOOLEAN bSkipDramSizing;     /* True: Skip video memory sizing. */
 
 #ifdef LINUX_KERNEL
-    PSIS_DSReg  pSR;             /* restore SR registers in initial function. */
-                                 /* end data :(idx, val) =  (FF, FF). */
-                                 /* Note : restore SR registers if  */
-                                 /* bSkipDramSizing = TRUE */
-
-    PSIS_DSReg  pCR;             /* restore CR registers in initial function. */
-                                 /* end data :(idx, val) =  (FF, FF) */
-                                 /* Note : restore cR registers if  */
-                                 /* bSkipDramSizing = TRUE */
+    ULONG  ulCRT2LCDType;        /* defined in the data structure type */
+                                 /* "SIS_LCD_TYPE" */
 #endif
-
-    PSIS_QUERYSPACE  pQueryVGAConfigSpace; /* Get/Set VGA Configuration  */
-                                           /* space */
-    PSIS_QUERYSPACE  pQueryNorthBridgeSpace;/* Get/Set North Bridge  */
-                                            /* space  */
 };
 #endif
 
-/* Addtional IOCTL for communication sisfb <> X driver        */
+/* Addtional IOCTLs for communication sisfb <> X driver        */
 /* If changing this, sisfb.h must also be changed (for sisfb) */
 
 #ifdef LINUX_XF86  /* We don't want the X driver to depend on the kernel source */
 
 /* ioctl for identifying and giving some info (esp. memory heap start) */
-#define SISFB_GET_INFO    0x80046ef8  /* Wow, what a terrible hack... */
+#define SISFB_GET_INFO_SIZE    0x8004f300
+#define SISFB_GET_INFO         0x8000f301  /* Must be patched with result from ..._SIZE at D[29:16] */
+/* deprecated ioctl number (for older versions of sisfb) */
+#define SISFB_GET_INFO_OLD     0x80046ef8
+
+/* ioctls for tv parameters (position) */
+#define SISFB_SET_TVPOSOFFSET   0x4004f304
+
+/* lock sisfb from register access */
+#define SISFB_SET_LOCK         0x4004f306
 
 /* Structure argument for SISFB_GET_INFO ioctl  */
 typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
 
 struct _SISFB_INFO {
-       unsigned long sisfb_id;         /* for identifying sisfb */
+       CARD32  sisfb_id;               /* for identifying sisfb */
 #ifndef SISFB_ID
 #define SISFB_ID         0x53495346    /* Identify myself with 'SISF' */
 #endif
-       int    chip_id;                 /* PCI ID of detected chip */
-       int    memory;                  /* video memory in KB which sisfb manages */
-       int    heapstart;               /* heap start (= sisfb "mem" argument) in KB */
-       unsigned char fbvidmode;        /* current sisfb mode */
+       CARD32  chip_id;                /* PCI ID of detected chip */
+       CARD32  memory;                 /* video memory in KB which sisfb manages */
+       CARD32  heapstart;              /* heap start (= sisfb "mem" argument) in KB */
+       CARD8   fbvidmode;              /* current sisfb mode */
+
+       CARD8   sisfb_version;
+       CARD8   sisfb_revision;
+       CARD8   sisfb_patchlevel;
+
+       CARD8   sisfb_caps;             /* sisfb's capabilities */
+
+       CARD32  sisfb_tqlen;            /* turbo queue length (in KB) */
 
-       unsigned char sisfb_version;
-       unsigned char sisfb_revision;
-       unsigned char sisfb_patchlevel;
+       CARD32  sisfb_pcibus;           /* The card's PCI ID */
+       CARD32  sisfb_pcislot;
+       CARD32  sisfb_pcifunc;
 
-       unsigned char sisfb_caps;       /* sisfb's capabilities */
+       CARD8   sisfb_lcdpdc;
 
-       int    sisfb_tqlen;             /* turbo queue length (in KB) */
+       CARD8   sisfb_lcda;
 
-       unsigned int sisfb_pcibus;      /* The card's PCI ID */
-       unsigned int sisfb_pcislot;
-       unsigned int sisfb_pcifunc;
+       CARD32  sisfb_vbflags;
+       CARD32  sisfb_currentvbflags;
 
-       unsigned char sisfb_lcdpdc;
-       
-       unsigned char sisfb_lcda;
+       CARD32  sisfb_scalelcd;
+       CARD32  sisfb_specialtiming;
 
-       unsigned long sisfb_vbflags;
-       unsigned long sisfb_currentvbflags;
+       CARD8   sisfb_haveemi;
+       CARD8   sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
+       CARD8   sisfb_haveemilcd;
 
-       int sisfb_scalelcd;
-       unsigned long sisfb_specialtiming;
+       CARD8   sisfb_lcdpdca;
 
-       unsigned char sisfb_haveemi;
-       unsigned char sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
-       unsigned char sisfb_haveemilcd;
+       CARD16  sisfb_tvxpos, sisfb_tvypos;     /* Warning: Values + 32 ! */
 
-       char reserved[213];             /* for future use */
+       CARD8 reserved[208];                    /* for future use */
 };
 #endif
 
index d7431ab..e3da799 100644 (file)
@@ -1,4 +1,5 @@
 /* $XFree86$ */
+/* $XdotOrg$ */
 /*
  * General structure definitions for universal mode switching modules
  *
  * * 2) Redistributions in binary form must reproduce the above copyright
  * *    notice, this list of conditions and the following disclaimer in the
  * *    documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * *    must display the following acknowledgement: "This product includes
- * *    software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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,
@@ -164,7 +162,6 @@ typedef struct _SiS_ExtStruct
 {
        UCHAR  Ext_ModeID;
        USHORT Ext_ModeFlag;
-       UCHAR  Ext_ModeOffset;
        USHORT Ext_VESAID;
        UCHAR  Ext_RESINFO;
        UCHAR  VB_ExtTVFlickerIndex;
@@ -172,6 +169,7 @@ typedef struct _SiS_ExtStruct
        UCHAR  VB_ExtTVYFilterIndex;
        UCHAR  VB_ExtTVYFilterIndexROM661;
        UCHAR  REFindex;
+       CHAR   ROMMODEIDX661;
 } SiS_ExtStruct;
 
 typedef struct _SiS_Ext2Struct
@@ -180,6 +178,7 @@ typedef struct _SiS_Ext2Struct
        UCHAR  Ext_CRT1CRTC;
        UCHAR  Ext_CRTVCLK;
        UCHAR  Ext_CRT2CRTC;
+       UCHAR  Ext_CRT2CRTC_NS;
        UCHAR  ModeID;
        USHORT XRes;
        USHORT YRes;
@@ -228,6 +227,8 @@ typedef struct _SiS_ModeResInfoStruct
        UCHAR  YChar;
 } SiS_ModeResInfoStruct;
 
+
+
 typedef UCHAR DRAM4Type[4];
 
 /* Defines for SiS_CustomT */
@@ -289,18 +290,21 @@ typedef struct _SiS_Private
         USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
 #endif
        BOOLEAN SiS_UseROM;
-       int    SiS_CHOverScan;
+       BOOLEAN SiS_ROMNew;
+       BOOLEAN SiS_NeedRomModeData;
+       BOOLEAN PanelSelfDetected;
+       int     SiS_CHOverScan;
        BOOLEAN SiS_CHSOverScan;
        BOOLEAN SiS_ChSW;
        BOOLEAN SiS_UseLCDA;
-       int    SiS_UseOEM;
-       ULONG  SiS_CustomT;
-       USHORT SiS_Backup70xx;
+       int     SiS_UseOEM;
+       ULONG   SiS_CustomT;
+       USHORT  SiS_Backup70xx;
        BOOLEAN HaveEMI;
        BOOLEAN HaveEMILCD;
        BOOLEAN OverruleEMI;
        UCHAR  EMI_30,EMI_31,EMI_32,EMI_33;
-       UCHAR  PDC;
+       SHORT  PDC, PDCA;
        UCHAR  SiS_MyCR63;
        USHORT SiS_CRT1Mode;
        USHORT SiS_flag_clearbuffer;
@@ -346,28 +350,13 @@ typedef struct _SiS_Private
        USHORT SiS_DDC_DeviceAddr;
        USHORT SiS_DDC_ReadAddr;
        USHORT SiS_DDC_SecAddr;
+       USHORT SiS_ChrontelInit;
        BOOLEAN SiS_SensibleSR11;
-       USHORT SiS_Panel800x600;
-       USHORT SiS_Panel1024x768;
-       USHORT SiS_Panel1280x1024;
-       USHORT SiS_Panel1600x1200;
-       USHORT SiS_Panel1280x960;
-       USHORT SiS_Panel1400x1050;
-       USHORT SiS_Panel320x480;
-       USHORT SiS_Panel1152x768;
-       USHORT SiS_Panel1280x768;
-       USHORT SiS_Panel1024x600;
-       USHORT SiS_Panel640x480;
-       USHORT SiS_Panel640x480_2;
-       USHORT SiS_Panel640x480_3;
-       USHORT SiS_Panel1152x864;
-       USHORT SiS_PanelCustom;
-       USHORT SiS_PanelBarco1366;
-       USHORT SiS_PanelMax;
+       USHORT SiS661LCD2TableSize;
+
        USHORT SiS_PanelMinLVDS;
        USHORT SiS_PanelMin301;
-       USHORT SiS_ChrontelInit;
-       
+
        const SiS_StStruct          *SiS_SModeIDTable;
        SiS_StandTableStruct        *SiS_StandTable;
        const SiS_ExtStruct         *SiS_EModeIDTable;
@@ -376,11 +365,10 @@ typedef struct _SiS_Private
        const SiS_CRT1TableStruct   *SiS_CRT1Table;
        const SiS_MCLKDataStruct    *SiS_MCLKData_0;
        const SiS_MCLKDataStruct    *SiS_MCLKData_1;
-       const SiS_VCLKDataStruct    *SiS_VCLKData;
-       const SiS_VBVCLKDataStruct  *SiS_VBVCLKData;
+       SiS_VCLKDataStruct          *SiS_VCLKData;
+       SiS_VBVCLKDataStruct        *SiS_VBVCLKData;
        const SiS_StResInfoStruct   *SiS_StResInfo;
        const SiS_ModeResInfoStruct *SiS_ModeResInfo;
-       const UCHAR                 *SiS_ScreenOffset;
 
        const UCHAR                 *pSiS_OutputSelect;
        const UCHAR                 *pSiS_SoftSetting;
@@ -410,6 +398,12 @@ typedef struct _SiS_Private
        const USHORT *pSiS_VideoSenseData2;
        const USHORT *pSiS_YCSenseData2;
 #endif
+
+       const SiS_PanelDelayTblStruct *SiS_PanelDelayTbl;
+       const SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS;
+
+       /* SiS bridge */
+
        const UCHAR *SiS_NTSCPhase;
        const UCHAR *SiS_PALPhase;
        const UCHAR *SiS_NTSCPhase2;
@@ -421,24 +415,21 @@ typedef struct _SiS_Private
        const UCHAR *SiS_SpecialPhase;
        const UCHAR *SiS_SpecialPhaseM;
        const UCHAR *SiS_SpecialPhaseJ;
-       const SiS_LCDDataStruct  *SiS_StLCD1024x768Data;
        const SiS_LCDDataStruct  *SiS_ExtLCD1024x768Data;
        const SiS_LCDDataStruct  *SiS_St2LCD1024x768Data;
-       const SiS_LCDDataStruct  *SiS_StLCD1280x1024Data;
+       const SiS_LCDDataStruct  *SiS_LCD1280x720Data;
+       const SiS_LCDDataStruct  *SiS_StLCD1280x768_2Data;
+       const SiS_LCDDataStruct  *SiS_ExtLCD1280x768_2Data;
+       const SiS_LCDDataStruct  *SiS_LCD1280x768_3Data;
+       const SiS_LCDDataStruct  *SiS_LCD1280x800Data;
+       const SiS_LCDDataStruct  *SiS_LCD1280x960Data;
        const SiS_LCDDataStruct  *SiS_ExtLCD1280x1024Data;
        const SiS_LCDDataStruct  *SiS_St2LCD1280x1024Data;
-       const SiS_LCDDataStruct  *SiS_NoScaleData1024x768;
-       const SiS_LCDDataStruct  *SiS_NoScaleData1280x1024;
-       const SiS_LCDDataStruct  *SiS_LCD1280x960Data;
-       const SiS_LCDDataStruct  *SiS_NoScaleData1400x1050;
-       const SiS_LCDDataStruct  *SiS_NoScaleData1600x1200;
-       const SiS_LCDDataStruct  *SiS_NoScaleData1280x768;
        const SiS_LCDDataStruct  *SiS_StLCD1400x1050Data;
-       const SiS_LCDDataStruct  *SiS_StLCD1600x1200Data;
-       const SiS_LCDDataStruct  *SiS_StLCD1280x768Data;
        const SiS_LCDDataStruct  *SiS_ExtLCD1400x1050Data;
+       const SiS_LCDDataStruct  *SiS_StLCD1600x1200Data;
        const SiS_LCDDataStruct  *SiS_ExtLCD1600x1200Data;
-       const SiS_LCDDataStruct  *SiS_ExtLCD1280x768Data;
+       const SiS_LCDDataStruct  *SiS_LCD1680x1050Data;
        const SiS_LCDDataStruct  *SiS_NoScaleData;
        const SiS_TVDataStruct   *SiS_StPALData;
        const SiS_TVDataStruct   *SiS_ExtPALData;
@@ -464,8 +455,16 @@ typedef struct _SiS_Private
        const UCHAR *SiS_HiTVTextTiming;
        const UCHAR *SiS_HiTVGroup3Text;
 #endif
-       const SiS_PanelDelayTblStruct *SiS_PanelDelayTbl;
-       const SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS;
+
+       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
+       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
+       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_2;
+       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_2;
+       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_3;
+       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_3;
+
+       /* LVDS, Chrontel */
+
        const SiS_LVDSDataStruct  *SiS_LVDS800x600Data_1;
        const SiS_LVDSDataStruct  *SiS_LVDS800x600Data_2;
        const SiS_LVDSDataStruct  *SiS_LVDS1024x768Data_1;
@@ -487,14 +486,6 @@ typedef struct _SiS_Private
        const SiS_LVDSDataStruct  *SiS_LVDS640x480Data_1;
        const SiS_LVDSDataStruct  *SiS_LVDS640x480Data_2;
        const SiS_LVDSDataStruct  *SiS_LVDS320x480Data_1;
-       const SiS_LVDSDataStruct  *SiS_LCDA1024x768Data_1;
-       const SiS_LVDSDataStruct  *SiS_LCDA1024x768Data_2;
-       const SiS_LVDSDataStruct  *SiS_LCDA1280x1024Data_1;
-       const SiS_LVDSDataStruct  *SiS_LCDA1280x1024Data_2;
-       const SiS_LVDSDataStruct  *SiS_LCDA1400x1050Data_1;
-       const SiS_LVDSDataStruct  *SiS_LCDA1400x1050Data_2;
-       const SiS_LVDSDataStruct  *SiS_LCDA1600x1200Data_1;
-       const SiS_LVDSDataStruct  *SiS_LCDA1600x1200Data_2;
        const SiS_LVDSDataStruct  *SiS_LVDSXXXxXXXData_1;
        const SiS_LVDSDataStruct  *SiS_LVDSBARCO1366Data_1;
        const SiS_LVDSDataStruct  *SiS_LVDSBARCO1366Data_2;
@@ -511,6 +502,7 @@ typedef struct _SiS_Private
        const SiS_LVDSDataStruct  *SiS_CHTVUPALNData;
        const SiS_LVDSDataStruct  *SiS_CHTVOPALNData;
        const SiS_LVDSDataStruct  *SiS_CHTVSOPALData;
+
        const SiS_LVDSDesStruct  *SiS_PanelType00_1;
        const SiS_LVDSDesStruct  *SiS_PanelType01_1;
        const SiS_LVDSDesStruct  *SiS_PanelType02_1;
@@ -545,20 +537,11 @@ typedef struct _SiS_Private
        const SiS_LVDSDesStruct  *SiS_PanelType0e_2;
        const SiS_LVDSDesStruct  *SiS_PanelType0f_2;
        const SiS_LVDSDesStruct  *SiS_PanelTypeNS_2;
-
-       const SiS_LVDSDesStruct  *LVDS1024x768Des_1;
-       const SiS_LVDSDesStruct  *LVDS1280x1024Des_1;
-       const SiS_LVDSDesStruct  *LVDS1400x1050Des_1;
-       const SiS_LVDSDesStruct  *LVDS1600x1200Des_1;
-       const SiS_LVDSDesStruct  *LVDS1024x768Des_2;
-       const SiS_LVDSDesStruct  *LVDS1280x1024Des_2;
-       const SiS_LVDSDesStruct  *LVDS1400x1050Des_2;
-       const SiS_LVDSDesStruct  *LVDS1600x1200Des_2;
-
        const SiS_LVDSDesStruct  *SiS_CHTVUNTSCDesData;
        const SiS_LVDSDesStruct  *SiS_CHTVONTSCDesData;
        const SiS_LVDSDesStruct  *SiS_CHTVUPALDesData;
        const SiS_LVDSDesStruct  *SiS_CHTVOPALDesData;
+
        const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_1;
        const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_1;
        const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_1;
@@ -599,44 +582,13 @@ typedef struct _SiS_Private
        const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_2_H;
        const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_3;
        const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_3_H;
+       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1320x480_1;
        const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UNTSC;
        const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1ONTSC;
        const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UPAL;
        const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1OPAL;
        const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1SOPAL;
 
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1320x480_1;
-
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_1;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_1;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_1;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_1;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_1_H;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_1_H;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_1_H;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_1_H;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_2;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_2;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_2;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_2;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_2_H;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_2_H;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_2_H;
-       const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_2_H;
-
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_1;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_1;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_2;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_2;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_2;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_2;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_3;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_3;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_3;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_3;
-
        const SiS_CHTVRegDataStruct *SiS_CHTVReg_UNTSC;
        const SiS_CHTVRegDataStruct *SiS_CHTVReg_ONTSC;
        const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPAL;
@@ -646,6 +598,7 @@ typedef struct _SiS_Private
        const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALN;
        const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALN;
        const SiS_CHTVRegDataStruct *SiS_CHTVReg_SOPAL;
+
        const UCHAR *SiS_CHTVVCLKUNTSC;
        const UCHAR *SiS_CHTVVCLKONTSC;
        const UCHAR *SiS_CHTVVCLKUPAL;
@@ -656,9 +609,13 @@ typedef struct _SiS_Private
        const UCHAR *SiS_CHTVVCLKOPALN;
        const UCHAR *SiS_CHTVVCLKSOPAL;
 
-       USHORT  PanelXRes;
-       USHORT  PanelYRes;
-       
+       USHORT  PanelXRes, PanelHT;
+       USHORT  PanelYRes, PanelVT;
+       USHORT  PanelHRS,  PanelHRE;
+       USHORT  PanelVRS,  PanelVRE;
+       USHORT  PanelVCLKIdx300;
+       USHORT  PanelVCLKIdx315;
+
        BOOLEAN UseCustomMode;
        BOOLEAN CRT1UsesCustomMode;
        USHORT  CHDisplay;
@@ -700,10 +657,11 @@ typedef struct _SiS_Private
        UCHAR Backup_1d;
        
        int     UsePanelScaler;
+       int     CenterScreen;
 
        USHORT  CP_Vendor, CP_Product;
        BOOLEAN CP_HaveCustomData;
-       int     CP_PreferredX, CP_PreferredY;
+       int     CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
        int     CP_MaxX, CP_MaxY, CP_MaxClock;
        BOOLEAN CP_Supports64048075;
        int     CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */
index 947ddfb..75ab629 100644 (file)
@@ -539,7 +539,13 @@ int __init xxxfb_init(void)
     info.fbops = &xxxfb_ops;
     info.fix = xxxfb_fix;
     info.pseudo_palette = pseudo_palette;
-    info.flags = FBINFO_FLAG_DEFAULT;
+
+    /*
+     * Set up flags to indicate what sort of acceleration your
+     * driver can provide (pan/wrap/copyarea/etc.) and whether it
+     * is a module -- see FBINFO_* in include/linux/fb.h
+     */
+    info.flags = FBINFO_DEFAULT;
     info.par = current_par;
 
     /*
index d08d459..d57b394 100644 (file)
@@ -790,7 +790,7 @@ static int sstfb_ioctl(struct inode *inode, struct file *file,
                
        /* fills lfb with #arg pixels */
        case _IOW('F', 0xdc, u32):      /* 0x46dc */
-               if (copy_from_user(&val, (void *)arg, sizeof(val)))
+               if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
                        return -EFAULT;
                if (val > info->fix.smem_len)
                        val = info->fix.smem_len;
@@ -801,7 +801,7 @@ static int sstfb_ioctl(struct inode *inode, struct file *file,
                
        /* change VGA pass_through mode */
        case _IOW('F', 0xdd, u32):      /* 0x46dd */
-               if (copy_from_user(&val, (void *)arg, sizeof(val)))
+               if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
                        return -EFAULT;
                pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);
                pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
index 820769e..bdcc8ec 100644 (file)
@@ -1372,8 +1372,6 @@ int __init vga16fb_init(void)
        vga16fb.par = &vga16_par;
        vga16fb.flags = FBINFO_FLAG_DEFAULT;
 
-       vga16fb.fix.smem_start  = VGA_MAP_MEM(vga16fb.fix.smem_start);
-
        i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16;
        ret = fb_alloc_cmap(&vga16fb.cmap, i, 0);
        if (ret) {
index 928e3b1..6b6bb7c 100644 (file)
@@ -31,8 +31,8 @@ static int afs_file_readpage(struct file *file, struct page *page);
 static int afs_file_invalidatepage(struct page *page, unsigned long offset);
 static int afs_file_releasepage(struct page *page, int gfp_flags);
 
-static ssize_t afs_file_write(struct file *file, const char *buf, size_t size,
-                             loff_t *off);
+static ssize_t afs_file_write(struct file *file, const char __user *buf,
+                             size_t size, loff_t *off);
 
 struct inode_operations afs_file_inode_operations = {
        .getattr        = afs_inode_getattr,
@@ -61,8 +61,8 @@ struct address_space_operations afs_fs_aops = {
 /*
  * AFS file write
  */
-static ssize_t afs_file_write(struct file *file, const char *buf, size_t size,
-                             loff_t *off)
+static ssize_t afs_file_write(struct file *file, const char __user *buf,
+                             size_t size, loff_t *off)
 {
        struct afs_vnode *vnode;
 
index 4659940..9c81b8f 100644 (file)
@@ -27,7 +27,7 @@ static void *afs_proc_cells_start(struct seq_file *p, loff_t *pos);
 static void *afs_proc_cells_next(struct seq_file *p, void *v, loff_t *pos);
 static void afs_proc_cells_stop(struct seq_file *p, void *v);
 static int afs_proc_cells_show(struct seq_file *m, void *v);
-static ssize_t afs_proc_cells_write(struct file *file, const char *buf,
+static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
                                    size_t size, loff_t *_pos);
 
 static struct seq_operations afs_proc_cells_ops = {
@@ -47,9 +47,10 @@ static struct file_operations afs_proc_cells_fops = {
 
 static int afs_proc_rootcell_open(struct inode *inode, struct file *file);
 static int afs_proc_rootcell_release(struct inode *inode, struct file *file);
-static ssize_t afs_proc_rootcell_read(struct file *file, char *buf,
+static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf,
                                      size_t size, loff_t *_pos);
-static ssize_t afs_proc_rootcell_write(struct file *file, const char *buf,
+static ssize_t afs_proc_rootcell_write(struct file *file,
+                                      const char __user *buf,
                                       size_t size, loff_t *_pos);
 
 static struct file_operations afs_proc_rootcell_fops = {
@@ -278,7 +279,7 @@ static int afs_proc_cells_show(struct seq_file *m, void *v)
  * handle writes to /proc/fs/afs/cells
  * - to add cells: echo "add <cellname> <IP>[:<IP>][:<IP>]"
  */
-static ssize_t afs_proc_cells_write(struct file *file, const char *buf,
+static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
                                    size_t size, loff_t *_pos)
 {
        char *kbuf, *name, *args;
@@ -363,7 +364,7 @@ static int afs_proc_rootcell_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t afs_proc_rootcell_read(struct file *file, char *buf,
+static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf,
                                      size_t size, loff_t *_pos)
 {
        return 0;
@@ -374,7 +375,8 @@ static ssize_t afs_proc_rootcell_read(struct file *file, char *buf,
  * handle writes to /proc/fs/afs/rootcell
  * - to initialize rootcell: echo "cell.name:192.168.231.14"
  */
-static ssize_t afs_proc_rootcell_write(struct file *file, const char *buf,
+static ssize_t afs_proc_rootcell_write(struct file *file,
+                                      const char __user *buf,
                                       size_t size, loff_t *_pos)
 {
        char *kbuf, *s;
index a2cf986..6788528 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -15,7 +15,7 @@
 #include <linux/aio_abi.h>
 #include <linux/module.h>
 
-//#define DEBUG 1
+#define DEBUG 0
 
 #include <linux/sched.h>
 #include <linux/fs.h>
@@ -27,6 +27,7 @@
 #include <linux/aio.h>
 #include <linux/highmem.h>
 #include <linux/workqueue.h>
+#include <linux/security.h>
 
 #include <asm/kmap_types.h>
 #include <asm/uaccess.h>
@@ -394,7 +395,7 @@ static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx)
        req->ki_ctx = ctx;
        req->ki_cancel = NULL;
        req->ki_retry = NULL;
-       req->ki_user_obj = NULL;
+       req->ki_obj.user = NULL;
 
        /* Check if the completion queue has enough free space to
         * accept an event from this io.
@@ -437,7 +438,7 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req)
 {
        req->ki_ctx = NULL;
        req->ki_filp = NULL;
-       req->ki_user_obj = NULL;
+       req->ki_obj.user = NULL;
        kmem_cache_free(kiocb_cachep, req);
        ctx->reqs_active--;
 
@@ -605,7 +606,7 @@ void fastcall kick_iocb(struct kiocb *iocb)
         * single context. */
        if (is_sync_kiocb(iocb)) {
                kiocbSetKicked(iocb);
-               wake_up_process(iocb->ki_user_obj);
+               wake_up_process(iocb->ki_obj.tsk);
                return;
        }
 
@@ -653,7 +654,7 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2)
                        spin_unlock_irq(&ctx->ctx_lock);
                }
                /* sync iocbs put the task here for us */
-               wake_up_process(iocb->ki_user_obj);
+               wake_up_process(iocb->ki_obj.tsk);
                return ret;
        }
 
@@ -673,13 +674,13 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2)
        event = aio_ring_event(info, tail, KM_IRQ0);
        tail = (tail + 1) % info->nr;
 
-       event->obj = (u64)(unsigned long)iocb->ki_user_obj;
+       event->obj = (u64)(unsigned long)iocb->ki_obj.user;
        event->data = iocb->ki_user_data;
        event->res = res;
        event->res2 = res2;
 
        dprintk("aio_complete: %p[%lu]: %p: %p %Lx %lx %lx\n",
-               ctx, tail, iocb, iocb->ki_user_obj, iocb->ki_user_data,
+               ctx, tail, iocb, iocb->ki_obj.user, iocb->ki_user_data,
                res, res2);
 
        /* after flagging the request as done, we
@@ -777,19 +778,11 @@ static inline void init_timeout(struct timeout *to)
 static inline void set_timeout(long start_jiffies, struct timeout *to,
                               const struct timespec *ts)
 {
-       unsigned long how_long;
-
-       if (ts->tv_sec < 0 || (!ts->tv_sec && !ts->tv_nsec)) {
+       to->timer.expires = start_jiffies + timespec_to_jiffies(ts);
+       if (time_after(to->timer.expires, jiffies))
+               add_timer(&to->timer);
+       else
                to->timed_out = 1;
-               return;
-       }
-
-       how_long = ts->tv_sec * HZ;
-#define HZ_NS (1000000000 / HZ)
-       how_long += (ts->tv_nsec + HZ_NS - 1) / HZ_NS;
-       
-       to->timer.expires = jiffies + how_long;
-       add_timer(&to->timer);
 }
 
 static inline void clear_timeout(struct timeout *to)
@@ -962,6 +955,7 @@ asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp)
                ret = put_user(ioctx->user_id, ctxp);
                if (!ret)
                        return 0;
+               get_ioctx(ioctx);
                io_destroy(ioctx);
        }
 
@@ -1029,7 +1023,7 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
                goto out_put_req;
        }
 
-       req->ki_user_obj = user_iocb;
+       req->ki_obj.user = user_iocb;
        req->ki_user_data = iocb->aio_data;
        req->ki_pos = iocb->aio_offset;
 
@@ -1043,6 +1037,9 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
                ret = -EFAULT;
                if (unlikely(!access_ok(VERIFY_WRITE, buf, iocb->aio_nbytes)))
                        goto out_put_req;
+               ret = security_file_permission (file, MAY_READ);
+               if (ret)
+                       goto out_put_req;
                ret = -EINVAL;
                if (file->f_op->aio_read)
                        ret = file->f_op->aio_read(req, buf,
@@ -1055,6 +1052,9 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
                ret = -EFAULT;
                if (unlikely(!access_ok(VERIFY_READ, buf, iocb->aio_nbytes)))
                        goto out_put_req;
+               ret = security_file_permission (file, MAY_WRITE);
+               if (ret)
+                       goto out_put_req;
                ret = -EINVAL;
                if (file->f_op->aio_write)
                        ret = file->f_op->aio_write(req, buf,
@@ -1155,7 +1155,7 @@ struct kiocb *lookup_kiocb(struct kioctx *ctx, struct iocb __user *iocb, u32 key
        /* TODO: use a hash or array, this sucks. */
        list_for_each(pos, &ctx->active_reqs) {
                struct kiocb *kiocb = list_kiocb(pos);
-               if (kiocb->ki_user_obj == iocb && kiocb->ki_key == key)
+               if (kiocb->ki_obj.user == iocb && kiocb->ki_key == key)
                        return kiocb;
        }
        return NULL;
@@ -1202,7 +1202,7 @@ asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb,
                struct io_event tmp;
                pr_debug("calling cancel\n");
                memset(&tmp, 0, sizeof(tmp));
-               tmp.obj = (u64)(unsigned long)kiocb->ki_user_obj;
+               tmp.obj = (u64)(unsigned long)kiocb->ki_obj.user;
                tmp.data = kiocb->ki_user_data;
                ret = cancel(kiocb, &tmp);
                if (!ret) {
index 74ad37a..5637061 100644 (file)
@@ -468,7 +468,7 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
 /* Get/set timeout ioctl() operation */
 static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi,
-                                        unsigned long *p)
+                                        unsigned long __user *p)
 {
        unsigned long ntimeout;
 
@@ -485,7 +485,7 @@ static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi,
 }
 
 /* Return protocol version */
-static inline int autofs_get_protover(int *p)
+static inline int autofs_get_protover(int __user *p)
 {
        return put_user(AUTOFS_PROTO_VERSION, p);
 }
@@ -494,7 +494,7 @@ static inline int autofs_get_protover(int *p)
 static inline int autofs_expire_run(struct super_block *sb,
                                    struct autofs_sb_info *sbi,
                                    struct vfsmount *mnt,
-                                   struct autofs_packet_expire *pkt_p)
+                                   struct autofs_packet_expire __user *pkt_p)
 {
        struct autofs_dir_ent *ent;
        struct autofs_packet_expire pkt;
@@ -526,6 +526,7 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp,
                             unsigned int cmd, unsigned long arg)
 {
        struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);
+       void __user *argp = (void __user *)arg;
 
        DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,process_group(current)));
 
@@ -545,12 +546,12 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp,
                autofs_catatonic_mode(sbi);
                return 0;
        case AUTOFS_IOC_PROTOVER: /* Get protocol version */
-               return autofs_get_protover((int *)arg);
+               return autofs_get_protover(argp);
        case AUTOFS_IOC_SETTIMEOUT:
-               return autofs_get_set_timeout(sbi,(unsigned long *)arg);
+               return autofs_get_set_timeout(sbi, argp);
        case AUTOFS_IOC_EXPIRE:
                return autofs_expire_run(inode->i_sb, sbi, filp->f_vfsmnt,
-                                        (struct autofs_packet_expire *)arg);
+                                        argp);
        default:
                return -ENOSYS;
        }
index a31cba5..7d26697 100644 (file)
@@ -27,7 +27,6 @@
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/pgalloc.h>
 #include <asm/cacheflush.h>
 
 static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
@@ -141,14 +140,14 @@ static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
 /* make sure we actually have a data and stack area to dump */
        set_fs(USER_DS);
 #ifdef __sparc__
-       if (verify_area(VERIFY_READ, (void *) START_DATA(dump), dump.u_dsize))
+       if (verify_area(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize))
                dump.u_dsize = 0;
-       if (verify_area(VERIFY_READ, (void *) START_STACK(dump), dump.u_ssize))
+       if (verify_area(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize))
                dump.u_ssize = 0;
 #else
-       if (verify_area(VERIFY_READ, (void *) START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
+       if (verify_area(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
                dump.u_dsize = 0;
-       if (verify_area(VERIFY_READ, (void *) START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
+       if (verify_area(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
                dump.u_ssize = 0;
 #endif
 
@@ -194,17 +193,18 @@ end_coredump:
  * memory and creates the pointer tables from them, and puts their
  * addresses on the "stack", returning the new stack pointer value.
  */
-static unsigned long * create_aout_tables(char * p, struct linux_binprm * bprm)
+static unsigned long __user *create_aout_tables(char __user *p, struct linux_binprm * bprm)
 {
-       char **argv, **envp;
-       unsigned long * sp;
+       char __user * __user *argv;
+       char __user * __user *envp;
+       unsigned long __user *sp;
        int argc = bprm->argc;
        int envc = bprm->envc;
 
-       sp = (unsigned long *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p);
+       sp = (void __user *)((-(unsigned long)sizeof(char *)) & (unsigned long) p);
 #ifdef __sparc__
        /* This imposes the proper stack alignment for a new process. */
-       sp = (unsigned long *) (((unsigned long) sp) & ~7);
+       sp = (void __user *) (((unsigned long) sp) & ~7);
        if ((envc+argc+3)&1) --sp;
 #endif
 #ifdef __alpha__
@@ -221,9 +221,9 @@ static unsigned long * create_aout_tables(char * p, struct linux_binprm * bprm)
        put_user(0x3e9, --sp);
 #endif
        sp -= envc+1;
-       envp = (char **) sp;
+       envp = (char __user * __user *) sp;
        sp -= argc+1;
-       argv = (char **) sp;
+       argv = (char __user * __user *) sp;
 #if defined(__i386__) || defined(__mc68000__) || defined(__arm__) || defined(__arch_um__)
        put_user((unsigned long) envp,--sp);
        put_user((unsigned long) argv,--sp);
@@ -422,7 +422,7 @@ beyond_if:
        }
 
        current->mm->start_stack =
-               (unsigned long) create_aout_tables((char *) bprm->p, bprm);
+               (unsigned long) create_aout_tables((char __user *) bprm->p, bprm);
 #ifdef __alpha__
        regs->gp = ex.a_gpvalue;
 #endif
index b69d18a..6a1cb4a 100644 (file)
@@ -40,7 +40,6 @@
 
 #include <asm/uaccess.h>
 #include <asm/param.h>
-#include <asm/pgalloc.h>
 
 #include <linux/elf.h>
 
index 465133c..64fea54 100644 (file)
@@ -40,7 +40,6 @@
 #include <asm/byteorder.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/pgalloc.h>
 #include <asm/unaligned.h>
 #include <asm/cacheflush.h>
 
index 6ba6a2f..ea351ba 100644 (file)
@@ -39,6 +39,8 @@ static int enabled = 1;
 
 enum {Enabled, Magic};
 #define MISC_FMT_PRESERVE_ARGV0 (1<<31)
+#define MISC_FMT_OPEN_BINARY (1<<30)
+#define MISC_FMT_CREDENTIALS (1<<29)
 
 typedef struct {
        struct list_head list;
@@ -102,10 +104,13 @@ static Node *check_file(struct linux_binprm *bprm)
 static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 {
        Node *fmt;
-       struct file * file;
+       struct file * interp_file = NULL;
        char iname[BINPRM_BUF_SIZE];
        char *iname_addr = iname;
        int retval;
+       int fd_binary = -1;
+       char fd_str[12];
+       struct files_struct *files = NULL;
 
        retval = -ENOEXEC;
        if (!enabled)
@@ -120,33 +125,102 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        if (!fmt)
                goto _ret;
 
-       allow_write_access(bprm->file);
-       fput(bprm->file);
-       bprm->file = NULL;
-
-       /* Build args for interpreter */
        if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
                remove_arg_zero(bprm);
        }
-       retval = copy_strings_kernel(1, &bprm->interp, bprm);
-       if (retval < 0) goto _ret; 
-       bprm->argc++;
-       retval = copy_strings_kernel(1, &iname_addr, bprm);
-       if (retval < 0) goto _ret; 
-       bprm->argc++;
-       bprm->interp = iname;   /* for binfmt_script */
 
-       file = open_exec(iname);
-       retval = PTR_ERR(file);
-       if (IS_ERR(file))
-               goto _ret;
-       bprm->file = file;
+       if (fmt->flags & MISC_FMT_OPEN_BINARY) {
+               char *fdsp = fd_str;
+
+               files = current->files;
+               retval = unshare_files();
+               if (retval < 0)
+                       goto _ret;
+               if (files == current->files) {
+                       put_files_struct(files);
+                       files = NULL;
+               }
+               /* if the binary should be opened on behalf of the
+                * interpreter than keep it open and assign descriptor
+                * to it */
+               fd_binary = get_unused_fd();
+               if (fd_binary < 0) {
+                       retval = fd_binary;
+                       goto _unshare;
+               }
+               fd_install(fd_binary, bprm->file);
+
+               /* if the binary is not readable than enforce mm->dumpable=0
+                  regardless of the interpreter's permissions */
+               if (permission(bprm->file->f_dentry->d_inode, MAY_READ, NULL))
+                       bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
+
+               allow_write_access(bprm->file);
+               bprm->file = NULL;
+
+               /* make argv[1] be the file descriptor of the binary */
+               snprintf(fd_str, sizeof(fd_str), "%d", fd_binary);
+               retval = copy_strings_kernel(1, &fdsp, bprm);
+               if (retval < 0)
+                       goto _error;
+               bprm->argc++;
+
+       } else {
+               allow_write_access(bprm->file);
+               fput(bprm->file);
+               bprm->file = NULL;
+               /* make argv[1] be the path to the binary */
+               retval = copy_strings_kernel (1, &bprm->interp, bprm);
+               if (retval < 0)
+                       goto _error;
+               bprm->argc++;
+       }
+       retval = copy_strings_kernel (1, &iname_addr, bprm);
+       if (retval < 0)
+               goto _error;
+       bprm->argc ++;
+       bprm->interp = iname;   /* for binfmt_script */
 
-       retval = prepare_binprm(bprm);
-       if (retval >= 0)
-               retval = search_binary_handler(bprm, regs);
+       interp_file = open_exec (iname);
+       retval = PTR_ERR (interp_file);
+       if (IS_ERR (interp_file))
+               goto _error;
+
+       bprm->file = interp_file;
+       if (fmt->flags & MISC_FMT_CREDENTIALS) {
+               /*
+                * No need to call prepare_binprm(), it's already been
+                * done.  bprm->buf is stale, update from interp_file.
+                */
+               memset(bprm->buf, 0, BINPRM_BUF_SIZE);
+               retval = kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE);
+       } else
+               retval = prepare_binprm (bprm);
+
+       if (retval < 0)
+               goto _error;
+
+       retval = search_binary_handler (bprm, regs);
+       if (retval < 0)
+               goto _error;
+
+       if (files) {
+               steal_locks(files);
+               put_files_struct(files);
+               files = NULL;
+       }
 _ret:
        return retval;
+_error:
+       if (fd_binary > 0)
+               sys_close(fd_binary);
+       bprm->interp_flags = 0;
+_unshare:
+       if (files) {
+               put_files_struct(current->files);
+               current->files = files;
+       }
+       goto _ret;
 }
 
 /* Command parsers */
@@ -191,12 +265,42 @@ static int unquote(char *from)
        return p - from;
 }
 
+static inline char * check_special_flags (char * sfs, Node * e)
+{
+       char * p = sfs;
+       int cont = 1;
+
+       /* special flags */
+       while (cont) {
+               switch (*p) {
+                       case 'P':
+                               p++;
+                               e->flags |= MISC_FMT_PRESERVE_ARGV0;
+                               break;
+                       case 'O':
+                               p++;
+                               e->flags |= MISC_FMT_OPEN_BINARY;
+                               break;
+                       case 'C':
+                               p++;
+                               /* this flags also implies the
+                                  open-binary flag */
+                               e->flags |= (MISC_FMT_CREDENTIALS |
+                                               MISC_FMT_OPEN_BINARY);
+                               break;
+                       default:
+                               cont = 0;
+               }
+       }
+
+       return p;
+}
 /*
  * This registers a new binary format, it recognises the syntax
- * ':name:type:offset:magic:mask:interpreter:'
+ * ':name:type:offset:magic:mask:interpreter:flags'
  * where the ':' is the IFS, that can be chosen with the first char
  */
-static Node *create_entry(const char *buffer, size_t count)
+static Node *create_entry(const char __user *buffer, size_t count)
 {
        Node *e;
        int memsize, err;
@@ -293,10 +397,8 @@ static Node *create_entry(const char *buffer, size_t count)
        if (!e->interpreter[0])
                goto Einval;
 
-       if (*p == 'P') {
-               p++;
-               e->flags |= MISC_FMT_PRESERVE_ARGV0;
-       }
+
+       p = check_special_flags (p, e);
 
        if (*p == '\n')
                p++;
@@ -319,7 +421,7 @@ Einval:
  * Set status of entry/binfmt_misc:
  * '1' enables, '0' disables and '-1' clears entry/binfmt_misc
  */
-static int parse_command(const char *buffer, size_t count)
+static int parse_command(const char __user *buffer, size_t count)
 {
        char s[4];
 
@@ -346,6 +448,7 @@ static void entry_status(Node *e, char *page)
 {
        char *dp;
        char *status = "disabled";
+       const char * flags = "flags: ";
 
        if (test_bit(Enabled, &e->flags))
                status = "enabled";
@@ -357,6 +460,22 @@ static void entry_status(Node *e, char *page)
 
        sprintf(page, "%s\ninterpreter %s\n", status, e->interpreter);
        dp = page + strlen(page);
+
+       /* print the special flags */
+       sprintf (dp, "%s", flags);
+       dp += strlen (flags);
+       if (e->flags & MISC_FMT_PRESERVE_ARGV0) {
+               *dp ++ = 'P';
+       }
+       if (e->flags & MISC_FMT_OPEN_BINARY) {
+               *dp ++ = 'O';
+       }
+       if (e->flags & MISC_FMT_CREDENTIALS) {
+               *dp ++ = 'C';
+       }
+       *dp ++ = '\n';
+
+
        if (!test_bit(Magic, &e->flags)) {
                sprintf(dp, "extension .%s\n", e->magic);
        } else {
@@ -424,7 +543,7 @@ static void kill_node(Node *e)
 /* /<entry> */
 
 static ssize_t
-bm_entry_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+bm_entry_read(struct file * file, char __user * buf, size_t nbytes, loff_t *ppos)
 {
        Node *e = file->f_dentry->d_inode->u.generic_ip;
        loff_t pos = *ppos;
@@ -456,7 +575,7 @@ out:
        return res;
 }
 
-static ssize_t bm_entry_write(struct file *file, const char *buffer,
+static ssize_t bm_entry_write(struct file *file, const char __user *buffer,
                                size_t count, loff_t *ppos)
 {
        struct dentry *root;
@@ -488,7 +607,7 @@ static struct file_operations bm_entry_operations = {
 
 /* /register */
 
-static ssize_t bm_register_write(struct file *file, const char *buffer,
+static ssize_t bm_register_write(struct file *file, const char __user *buffer,
                               size_t count, loff_t *ppos)
 {
        Node *e;
@@ -556,7 +675,7 @@ static struct file_operations bm_register_operations = {
 /* /status */
 
 static ssize_t
-bm_status_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+bm_status_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
        char *s = enabled ? "enabled" : "disabled";
        int len = strlen(s);
@@ -574,7 +693,7 @@ bm_status_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
        return nbytes;
 }
 
-static ssize_t bm_status_write(struct file * file, const char * buffer,
+static ssize_t bm_status_write(struct file * file, const char __user * buffer,
                size_t count, loff_t *ppos)
 {
        int res = parse_command(buffer, count);
index 0759aab..ac23902 100644 (file)
@@ -23,6 +23,7 @@ Amrut Joshi
 Shobhit Dayal
 Sergey Vlasov
 Richard Hughes
+Yury Umanets
 
 Test case and Bug Report contributors
 -------------------------------------
@@ -30,5 +31,7 @@ Thanks to those in the community who have submitted detailed bug reports
 and debug of problems they have found:  Jochen Dolze, David Blaine,
 Rene Scharfe, Martin Josefsson, Alexander Wild, Anthony Liguori,
 Lars Muller, Urban Widmark, Massimiliano Ferrero, Howard Owen,
-Kieron Briggs and others. 
+Olaf Kirch, Kieron Briggs and others. 
 
+And thanks to the IBM LTC and Power test teams and SuSE testers for
+finding multiple bugs during excellent stress test runs.
index c1028f9..cae2bfb 100644 (file)
@@ -1,3 +1,20 @@
+Version 1.18
+------------
+Do not rename hardlinked files (since that should be a noop). Flush
+cached write behind data when reopening a file after session abend,
+except when already in write. Grab per socket sem during reconnect 
+to avoid oops in sendmsg if overlapping with reconnect.
+
+
+Version 1.17
+------------
+Update number of blocks in file so du command is happier (in Linux a fake
+blocksize of 512 is required for calculating number of blocks in inode).
+Fix prepare write of partial pages to read in data from server if possible.
+Fix race on tcpStatus field between unmount and reconnection code, causing
+cifsd process sometimes to hang around forever. Improve out of memory
+checks in cifs_filldir
+
 Version 1.16
 ------------
 Fix incorrect file size in file handle based setattr on big endian hardware.
index 8dba57f..09b49c8 100644 (file)
@@ -97,7 +97,9 @@ Linux:
 
        case sensitive = yes
        delete readonly = yes 
+       ea support = yes
+
+Note that ea support is required for supporting Linux xattrs. 
 Some administrators also change the "map archive" and the "create mask" 
 parameters from their default values.  Creating special devices (mknod) remotely 
 may require specifying a mkdev function to Samba.  For more information on these 
@@ -268,11 +270,12 @@ Misc /proc/fs/cifs Flags and Debug Info
 =======================================
 Informational pseudo-files:
 DebugData              Displays information about active CIFS sessions
-                       as well as per share statistics (if CONFIG_CIFS_STATS
-                       is enabled in the kernel configuration).
+                       and shares.
 SimultaneousOps                Counter which holds maximum number of
                        simultaneous outstanding SMB/CIFS requests.
-Stats                  Lists summary resource usage information
+Stats                  Lists summary resource usage information as well as per
+                       share statistics, if CONFIG_CIFS_STATS in enabled
+                       in the kernel configuration.
 
 Configuration pseudo-files:
 MultiuserMount         If set to one, more than one CIFS session to 
index b7e5ef2..c4ee810 100644 (file)
@@ -80,27 +80,13 @@ symlink text beginning with slash
 but recognizes them
 3) create of new files to FAT partitions on Windows servers can
 succeed but still return access denied (appears to be Windows 
-not client problem) and has not been reproduced recently.
+server not cifs client problem) and has not been reproduced recently.
 NTFS partitions do not have this problem.
 4) debug connectation lock test case 10 which fails against
 Samba (may be unmappable due to POSIX to Windows lock model
 differences but worth investigating).  Also debug Samba to 
 see why lock test case 7 takes longer to complete to Samba
 than to Windows.
-5) prepare_write does not initialize pages properly when partial
-page writes begin in the middle of a page (pages can get zeroed).
-6) Write caching done incorrectly when files are only opened
-with write permission by the application.
-7) Rename of files that are hardlinked does not work correctly e.g.
-       ln source target
-       mv source target 
-This should be no op since files are linked but in cifs it causes
-the source file to go away. This may require implementation of
-the cifs POSIX extensions (Unix Extensions version 2) for
-it to be done correctly since Samba is failing the rename,
-(rather than ignoring it) so the client not knowing they
-are linked proceeds to delete the target and then retry the
-move which succeeds this time (but the source is gone).
 
 Misc testing to do
 ==================
index 0b114f0..2c3d9a8 100644 (file)
@@ -142,30 +142,10 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
                            sprintf(buf, " type: %d ",
                                    tcon->fsDevInfo.DeviceType);
                buf += length;
-               if(tcon->tidStatus == CifsNeedReconnect)
+               if(tcon->tidStatus == CifsNeedReconnect) {
                        buf += sprintf(buf, "\tDISCONNECTED ");
-#ifdef CONFIG_CIFS_STATS
-               length = sprintf(buf,"\nSMBs: %d Oplock Breaks: %d",
-                       atomic_read(&tcon->num_smbs_sent),
-                       atomic_read(&tcon->num_oplock_brks));
-               buf += length;
-               length = sprintf(buf,"\nReads: %d Bytes %lld",
-                       atomic_read(&tcon->num_reads),
-                       (long long)(tcon->bytes_read));
-               buf += length;
-               length = sprintf(buf,"\nWrites: %d Bytes: %lld",
-                       atomic_read(&tcon->num_writes),
-                       (long long)(tcon->bytes_written));
-               buf += length;
-               length = sprintf(buf,
-                        "\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d",
-                       atomic_read(&tcon->num_opens),
-                       atomic_read(&tcon->num_deletes),
-                       atomic_read(&tcon->num_mkdirs),
-                       atomic_read(&tcon->num_rmdirs));
-               buf += length;
-#endif
-
+                       length += 14;
+               }
        }
        read_unlock(&GlobalSMBSeslock);
 
@@ -200,32 +180,80 @@ cifs_total_xid_read(char *buf, char **beginBuffer, off_t offset,
        return length;
 }
 
+#ifdef CONFIG_CIFS_STATS
 int
 cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
                  int length, int *eof, void *data)
 {
-       int item_length;
-       length =
-           sprintf(buf,
-                   "Currently Allocated structures\nCIFS Sessions: %d\n",sesInfoAllocCount.counter);
+       int item_length,i;
+       struct list_head *tmp;
+       struct cifsTconInfo *tcon;
+
+       length = sprintf(buf,
+                       "Resources in use\nCIFS Session: %d\n",
+                       sesInfoAllocCount.counter);
        buf += length;
        item_length = 
-               sprintf(buf,"Shares (unique mount targets): %d\n",tconInfoAllocCount.counter);
+               sprintf(buf,"Share (unique mount targets): %d\n",
+                       tconInfoAllocCount.counter);
        length += item_length;
        buf += item_length;      
        item_length = 
-                       sprintf(buf,"Allocated SMB Request and Response Buffers: %d\n",bufAllocCount.counter);
+               sprintf(buf,"SMB Request/Response Buffer: %d\n",
+                       bufAllocCount.counter);
        length += item_length;
        buf += item_length;      
        item_length = 
-               sprintf(buf,"Active Operations (MIDs in use): %d\n",midCount.counter);
+               sprintf(buf,"Operations (MIDs): %d\n",
+                       midCount.counter);
        length += item_length;
        buf += item_length;
-       item_length = sprintf(buf,"%d sessions and %d shares reconnected after failure\n",tcpSesReconnectCount.counter,tconInfoReconnectCount.counter);
+       item_length = sprintf(buf,
+               "\n%d session %d share reconnects\n",
+               tcpSesReconnectCount.counter,tconInfoReconnectCount.counter);
        length += item_length;
+       buf += item_length;
+
+       i = 0;
+       read_lock(&GlobalSMBSeslock);
+       list_for_each(tmp, &GlobalTreeConnectionList) {
+               i++;
+               tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
+               item_length = sprintf(buf,"\n%d) %s",i, tcon->treeName);
+               buf += item_length;
+               length += item_length;
+               if(tcon->tidStatus == CifsNeedReconnect) {
+                       buf += sprintf(buf, "\tDISCONNECTED ");
+                       length += 14;
+               }
+               item_length = sprintf(buf,"\nSMBs: %d Oplock Breaks: %d",
+                       atomic_read(&tcon->num_smbs_sent),
+                       atomic_read(&tcon->num_oplock_brks));
+               buf += item_length;
+               length += item_length;
+               item_length = sprintf(buf,"\nReads: %d Bytes %lld",
+                       atomic_read(&tcon->num_reads),
+                       (long long)(tcon->bytes_read));
+               buf += item_length;
+               item_length = sprintf(buf,"\nWrites: %d Bytes: %lld",
+                       atomic_read(&tcon->num_writes),
+                       (long long)(tcon->bytes_written));
+               buf += item_length;
+               item_length = sprintf(buf,
+                       "\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d",
+                       atomic_read(&tcon->num_opens),
+                       atomic_read(&tcon->num_deletes),
+                       atomic_read(&tcon->num_mkdirs),
+                       atomic_read(&tcon->num_rmdirs));
+               buf += item_length;
+               length += item_length;
+       }
+       read_unlock(&GlobalSMBSeslock);
+
 
        return length;
 }
+#endif
 
 struct proc_dir_entry *proc_fs_cifs;
 read_proc_t cifs_txanchor_read;
@@ -265,10 +293,10 @@ cifs_proc_init(void)
 
        create_proc_read_entry("SimultaneousOps", 0, proc_fs_cifs,
                                cifs_total_xid_read, 0);
-
+#ifdef CONFIG_CIFS_STATS
        create_proc_read_entry("Stats", 0, proc_fs_cifs,
                                cifs_stats_read, 0);
-
+#endif
        pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs,
                                cifsFYI_read, 0);
        if (pde)
@@ -336,7 +364,9 @@ cifs_proc_clean(void)
        remove_proc_entry("cifsFYI", proc_fs_cifs);
        remove_proc_entry("traceSMB", proc_fs_cifs);
        remove_proc_entry("SimultaneousOps", proc_fs_cifs);
+#ifdef CONFIG_CIFS_STATS
        remove_proc_entry("Stats", proc_fs_cifs);
+#endif
        remove_proc_entry("MultiuserMount", proc_fs_cifs);
        remove_proc_entry("OplockEnabled", proc_fs_cifs);
        remove_proc_entry("NTLMV2Enabled",proc_fs_cifs);
@@ -370,7 +400,7 @@ cifsFYI_read(char *page, char **start, off_t off, int count,
        return len;
 }
 static int
-cifsFYI_write(struct file *file, const char *buffer,
+cifsFYI_write(struct file *file, const char __user *buffer,
              unsigned long count, void *data)
 {
        char c;
@@ -409,7 +439,7 @@ oplockEnabled_read(char *page, char **start, off_t off,
        return len;
 }
 static int
-oplockEnabled_write(struct file *file, const char *buffer,
+oplockEnabled_write(struct file *file, const char __user *buffer,
                    unsigned long count, void *data)
 {
        char c;
@@ -449,7 +479,7 @@ quotaEnabled_read(char *page, char **start, off_t off,
         return len;
 }
 static int
-quotaEnabled_write(struct file *file, const char *buffer,
+quotaEnabled_write(struct file *file, const char __user *buffer,
                     unsigned long count, void *data)
 {
         char c;
@@ -489,7 +519,7 @@ linuxExtensionsEnabled_read(char *page, char **start, off_t off,
         return len;
 }
 static int
-linuxExtensionsEnabled_write(struct file *file, const char *buffer,
+linuxExtensionsEnabled_write(struct file *file, const char __user *buffer,
                     unsigned long count, void *data)
 {
         char c;
@@ -529,7 +559,7 @@ lookupFlag_read(char *page, char **start, off_t off,
        return len;
 }
 static int
-lookupFlag_write(struct file *file, const char *buffer,
+lookupFlag_write(struct file *file, const char __user *buffer,
                    unsigned long count, void *data)
 {
        char c;
@@ -567,7 +597,7 @@ traceSMB_read(char *page, char **start, off_t off, int count,
        return len;
 }
 static int
-traceSMB_write(struct file *file, const char *buffer,
+traceSMB_write(struct file *file, const char __user *buffer,
               unsigned long count, void *data)
 {
        char c;
@@ -606,7 +636,7 @@ multiuser_mount_read(char *page, char **start, off_t off,
        return len;
 }
 static int
-multiuser_mount_write(struct file *file, const char *buffer,
+multiuser_mount_write(struct file *file, const char __user *buffer,
                      unsigned long count, void *data)
 {
        char c;
@@ -645,7 +675,7 @@ extended_security_read(char *page, char **start, off_t off,
        return len;
 }
 static int
-extended_security_write(struct file *file, const char *buffer,
+extended_security_write(struct file *file, const char __user *buffer,
                        unsigned long count, void *data)
 {
        char c;
@@ -684,7 +714,7 @@ ntlmv2_enabled_read(char *page, char **start, off_t off,
        return len;
 }
 static int
-ntlmv2_enabled_write(struct file *file, const char *buffer,
+ntlmv2_enabled_write(struct file *file, const char __user *buffer,
                        unsigned long count, void *data)
 {
        char c;
@@ -723,7 +753,7 @@ packet_signing_enabled_read(char *page, char **start, off_t off,
        return len;
 }
 static int
-packet_signing_enabled_write(struct file *file, const char *buffer,
+packet_signing_enabled_write(struct file *file, const char __user *buffer,
                        unsigned long count, void *data)
 {
        char c;
index 03d91f1..1fe2654 100644 (file)
@@ -426,7 +426,7 @@ cifs_get_sb(struct file_system_type *fs_type,
 }
 
 static ssize_t
-cifs_read_wrapper(struct file * file, char *read_data, size_t read_size,
+cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size,
           loff_t * poffset)
 {
        if(file == NULL)
@@ -455,7 +455,7 @@ cifs_read_wrapper(struct file * file, char *read_data, size_t read_size,
 }
 
 static ssize_t
-cifs_write_wrapper(struct file * file, const char *write_data,
+cifs_write_wrapper(struct file * file, const char __user *write_data,
            size_t write_size, loff_t * poffset) 
 {
        ssize_t written;
index d960b35..b8be30c 100644 (file)
@@ -85,7 +85,7 @@ extern struct dentry_operations cifs_dentry_ops;
 
 /* Functions related to symlinks */
 extern int cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
-extern int cifs_readlink(struct dentry *direntry, char *buffer, int buflen);
+extern int cifs_readlink(struct dentry *direntry, char __user *buffer, int buflen);
 extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
                        const char *symname);
 extern int     cifs_removexattr(struct dentry *, const char *);
@@ -93,5 +93,5 @@ extern int    cifs_setxattr(struct dentry *, const char *, const void *,
                         size_t, int);
 extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
 extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
-#define CIFS_VERSION   "1.16"
+#define CIFS_VERSION   "1.18"
 #endif                         /* _CIFSFS_H */
index 4a57daf..067eb4e 100644 (file)
@@ -862,6 +862,10 @@ typedef struct smb_com_create_directory_rsp {
        __u16 ByteCount;        /* bct = 0 */
 } CREATE_DIRECTORY_RSP;
 
+/***************************************************/
+/* NT Transact structure defintions follow         */
+/* Currently only ioctl and notify are implemented */
+/***************************************************/
 typedef struct smb_com_transaction_ioctl_req {
        struct smb_hdr hdr;     /* wct = 23 */
        __u8 MaxSetupCount;
@@ -904,29 +908,45 @@ typedef struct smb_com_transaction_ioctl_rsp {
 } TRANSACT_IOCTL_RSP;
 
 typedef struct smb_com_transaction_change_notify_req {
-        struct smb_hdr hdr;     /* wct = 23 */
-        __u8 MaxSetupCount;
-        __u16 Reserved;
-        __u32 TotalParameterCount;
-        __u32 TotalDataCount;
-        __u32 MaxParameterCount;
-        __u32 MaxDataCount;
-        __u32 ParameterCount;
-        __u32 ParameterOffset;
-        __u32 DataCount;
-        __u32 DataOffset;
-        __u8 SetupCount; /* four setup words follow subcommand */
-        /* SNIA spec incorrectly included spurious pad here */
-        __u16 SubCommand;/* 4 = Change Notify */
+       struct smb_hdr hdr;     /* wct = 23 */
+       __u8 MaxSetupCount;
+       __u16 Reserved;
+       __u32 TotalParameterCount;
+       __u32 TotalDataCount;
+       __u32 MaxParameterCount;
+       __u32 MaxDataCount;
+       __u32 ParameterCount;
+       __u32 ParameterOffset;
+       __u32 DataCount;
+       __u32 DataOffset;
+       __u8 SetupCount; /* four setup words follow subcommand */
+       /* SNIA spec incorrectly included spurious pad here */
+       __u16 SubCommand;/* 4 = Change Notify */
        __u32 CompletionFilter;  /* operation to monitor */
        __u16 Fid;
        __u8 WatchTree;  /* 1 = Monitor subdirectories */
+       __u8 Reserved2;
        __u16 ByteCount;
-       __u8 Pad[3];
-       __u8 Data[1];
+/* __u8 Pad[3];*/
+/*     __u8 Data[1];*/
 } TRANSACT_CHANGE_NOTIFY_REQ;
 
-/* Completion Filter flags */
+typedef struct smb_com_transaction_change_notify_rsp {
+       struct smb_hdr hdr;     /* wct = 18 */
+       __u8 Reserved[3];
+       __u32 TotalParameterCount;
+       __u32 TotalDataCount;
+       __u32 ParameterCount;
+       __u32 ParameterOffset;
+       __u32 ParameterDisplacement;
+       __u32 DataCount;
+       __u32 DataOffset;
+       __u32 DataDisplacement;
+       __u8 SetupCount;   /* 0 */
+       __u16 ByteCount;
+       /* __u8 Pad[3]; */
+} TRANSACT_CHANGE_NOTIFY_RSP;
+/* Completion Filter flags for Notify */
 #define FILE_NOTIFY_CHANGE_FILE_NAME    0x00000001
 #define FILE_NOTIFY_CHANGE_DIR_NAME     0x00000002
 #define FILE_NOTIFY_CHANGE_NAME         0x00000003
@@ -1026,9 +1046,12 @@ typedef union smb_com_transaction2 {
 
 /* PathInfo/FileInfo infolevels */
 #define SMB_INFO_STANDARD                   1
+#define SMB_INFO_QUERY_EAS_FROM_LIST        3
+#define SMB_INFO_QUERY_ALL_EAS              4
 #define SMB_INFO_IS_NAME_VALID              6
 #define SMB_QUERY_FILE_BASIC_INFO       0x101
 #define SMB_QUERY_FILE_STANDARD_INFO    0x102
+#define SMB_QUERY_FILE_EA_INFO          0x103
 #define SMB_QUERY_FILE_NAME_INFO        0x104
 #define SMB_QUERY_FILE_ALLOCATION_INFO  0x105
 #define SMB_QUERY_FILE_END_OF_FILEINFO  0x106
@@ -1667,16 +1690,17 @@ struct gealist {
 };
 
 struct fea {
-       unsigned char fEA;
-       unsigned char cbName;
-       unsigned short cbValue;
+       unsigned char EA_flags;
+       __u8 name_len;
+       __u16 value_len;
        char szName[1];
+       /* optionally followed by value */
 };
 /* flags for _FEA.fEA */
 #define FEA_NEEDEA         0x80        /* need EA bit */
 
 struct fealist {
-       unsigned long cbList;
+       __u32 list_len;
        struct fea list[1];
 };
 
index cc68715..cf99e22 100644 (file)
@@ -244,4 +244,11 @@ extern int CIFSSMBCopy(int xid,
                        const __u16 target_tid,
                        const char *toName, const int flags,
                        const struct nls_table *nls_codepage);
+extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 
+                       const int notify_subdirs,const __u16 netfid,__u32 filter,
+                       const struct nls_table *nls_codepage);
+extern int CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
+                const unsigned char *searchName,
+                char * EAData, size_t size,
+                const struct nls_table *nls_codepage);
 #endif                 /* _CIFSPROTO_H */
index 6a26f8c..420742a 100644 (file)
@@ -383,8 +383,11 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
                         smb_buffer_response, &length, 0);
        if (ses->server) {
                atomic_dec(&ses->server->socketUseCount);
-               if (atomic_read(&ses->server->socketUseCount) == 0)
+               if (atomic_read(&ses->server->socketUseCount) == 0) {
+                       spin_lock(&GlobalMid_Lock);
                        ses->server->tcpStatus = CifsExiting;
+                       spin_unlock(&GlobalMid_Lock);
+               }
        }
        if (pSMB)
                cifs_buf_release(pSMB);
@@ -1464,9 +1467,9 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
 
        pSMB->TotalParameterCount = 0 ;
        pSMB->TotalDataCount = 0;
-       pSMB->MaxParameterCount = cpu_to_le16(2);
+       pSMB->MaxParameterCount = cpu_to_le32(2);
        /* BB find exact data count max from sess structure BB */
-       pSMB->MaxDataCount = cpu_to_le16(4000);
+       pSMB->MaxDataCount = cpu_to_le32(4000);
        pSMB->MaxSetupCount = 4;
        pSMB->Reserved = 0;
        pSMB->ParameterOffset = 0;
@@ -1593,6 +1596,8 @@ QPathInfoRetry:
        } else {                /* decode response */
                pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
                /* BB also check enough total bytes returned */
+               /* BB we need to improve the validity checking
+               of these trans2 responses */
                if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) 
                        rc = -EIO;      /* bad smb */
                else if (pFindData){
@@ -2828,3 +2833,149 @@ setPermsRetry:
                goto setPermsRetry;
        return rc;
 }
+
+int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 
+                       const int notify_subdirs, const __u16 netfid,
+                       __u32 filter, const struct nls_table *nls_codepage)
+{
+       int rc = 0;
+       struct smb_com_transaction_change_notify_req * pSMB = NULL;
+       struct smb_com_transaction_change_notify_rsp * pSMBr = NULL;
+       int bytes_returned;
+
+       cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid));
+       rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
+                      (void **) &pSMBr);
+       if (rc)
+               return rc;
+
+       pSMB->TotalParameterCount = 0 ;
+       pSMB->TotalDataCount = 0;
+       pSMB->MaxParameterCount = cpu_to_le32(2);
+       /* BB find exact data count max from sess structure BB */
+       pSMB->MaxDataCount = 0; /* same in little endian or be */
+       pSMB->MaxSetupCount = 4;
+       pSMB->Reserved = 0;
+       pSMB->ParameterOffset = 0;
+       pSMB->DataCount = 0;
+       pSMB->DataOffset = 0;
+       pSMB->SetupCount = 4; /* single byte does not need le conversion */
+       pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
+       pSMB->ParameterCount = pSMB->TotalParameterCount;
+       if(notify_subdirs)
+               pSMB->WatchTree = 1; /* one byte - no le conversion needed */
+       pSMB->Reserved2 = 0;
+       pSMB->CompletionFilter = cpu_to_le32(filter);
+       pSMB->Fid = netfid; /* file handle always le */
+       pSMB->ByteCount = 0;
+
+       pSMB->hdr.smb_buf_length += pSMB->ByteCount;
+       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+       if (rc) {
+               cFYI(1, ("Error in Notify = %d", rc));
+       }
+       if (pSMB)
+               cifs_buf_release(pSMB);
+/*             if (rc == -EAGAIN)
+                       goto NotifyRetry; */
+       return rc;      
+}
+#ifdef CONFIG_CIFS_XATTR
+int
+CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
+                const unsigned char *searchName,
+                char * EAData, size_t size,
+                const struct nls_table *nls_codepage)
+{
+               /* BB assumes one setup word */
+       TRANSACTION2_QPI_REQ *pSMB = NULL;
+       TRANSACTION2_QPI_RSP *pSMBr = NULL;
+       int rc = 0;
+       int bytes_returned;
+       int name_len;
+
+       cFYI(1, ("In Query All EAs path %s", searchName));
+QAllEAsRetry:
+       rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+                     (void **) &pSMBr);
+       if (rc)
+               return rc;
+
+       if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
+               name_len =
+                   cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
+                                 /* find define for this maxpathcomponent */
+                                 , nls_codepage);
+               name_len++;     /* trailing null */
+               name_len *= 2;
+       } else {                /* BB improve the check for buffer overruns BB */
+               name_len = strnlen(searchName, 530);
+               name_len++;     /* trailing null */
+               strncpy(pSMB->FileName, searchName, name_len);
+       }
+
+       pSMB->TotalParameterCount = 2 /* level */  + 4 /* reserved */  +
+           name_len /* includes null */ ;
+       pSMB->TotalDataCount = 0;
+       pSMB->MaxParameterCount = cpu_to_le16(2);
+       pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
+       pSMB->MaxSetupCount = 0;
+       pSMB->Reserved = 0;
+       pSMB->Flags = 0;
+       pSMB->Timeout = 0;
+       pSMB->Reserved2 = 0;
+       pSMB->ParameterOffset = cpu_to_le16(offsetof(
+        struct smb_com_transaction2_qpi_req ,InformationLevel) - 4);
+       pSMB->DataCount = 0;
+       pSMB->DataOffset = 0;
+       pSMB->SetupCount = 1;
+       pSMB->Reserved3 = 0;
+       pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
+       pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
+       pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
+       pSMB->ParameterCount = pSMB->TotalParameterCount;
+       pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
+       pSMB->Reserved4 = 0;
+       pSMB->hdr.smb_buf_length += pSMB->ByteCount;
+       pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
+
+       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+                        (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+       if (rc) {
+               cFYI(1, ("Send error in QueryAllEAs = %d", rc));
+       } else {                /* decode response */
+               pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
+               /* BB also check enough total bytes returned */
+               /* BB we need to improve the validity checking
+               of these trans2 responses */
+               if ((pSMBr->ByteCount < 4) || (pSMBr->DataOffset > 512)) 
+                       rc = -EIO;      /* bad smb */
+          /* else if (pFindData){
+                       memcpy((char *) pFindData,
+                              (char *) &pSMBr->hdr.Protocol +
+                              pSMBr->DataOffset, kl);
+               }*/ else {
+                       /* check that length of list is not more than bcc */
+                       /* check that each entry does not go beyond length
+                          of list */
+                       /* check that each element of each entry does not
+                          go beyond end of list */
+                       struct fealist * ea_response_data;
+                       rc = 0;
+                       /* validate_trans2_offsets() */
+                       /* BB to check if(start of smb + pSMBr->DataOffset > &bcc+ bcc)*/
+                       ea_response_data = (struct fealist *)
+                               (((char *) &pSMBr->hdr.Protocol) +
+                               pSMBr->DataOffset);
+                       cFYI(1,("ea length %d",ea_response_data->list_len));
+               }
+       }
+       if (pSMB)
+               cifs_buf_release(pSMB);
+       if (rc == -EAGAIN)
+               goto QAllEAsRetry;
+
+       return rc;
+}
+#endif
index 3f1261a..befbff5 100644 (file)
@@ -95,9 +95,15 @@ cifs_reconnect(struct TCP_Server_Info *server)
        struct cifsTconInfo *tcon;
        struct mid_q_entry * mid_entry;
        
-       if(server->tcpStatus == CifsExiting)
+       spin_lock(&GlobalMid_Lock);
+       if(server->tcpStatus == CifsExiting) {
+               /* the demux thread will exit normally 
+               next time through the loop */
+               spin_unlock(&GlobalMid_Lock);
                return rc;
-       server->tcpStatus = CifsNeedReconnect;
+       } else
+               server->tcpStatus = CifsNeedReconnect;
+       spin_unlock(&GlobalMid_Lock);
        server->maxBuf = 0;
 
        cFYI(1, ("Reconnecting tcp session "));
@@ -122,7 +128,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
                }
        }
        read_unlock(&GlobalSMBSeslock);
-
+       /* do not want to be sending data on a socket we are freeing */
+       down(&server->tcpSem); 
        if(server->ssocket) {
                cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state,
                        server->ssocket->flags));
@@ -148,7 +155,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
                }
        }
        spin_unlock(&GlobalMid_Lock);
-
+       up(&server->tcpSem); 
 
        while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood))
        {
@@ -164,7 +171,10 @@ cifs_reconnect(struct TCP_Server_Info *server)
                        schedule_timeout(3 * HZ);
                } else {
                        atomic_inc(&tcpSesReconnectCount);
-                       server->tcpStatus = CifsGood;
+                       spin_lock(&GlobalMid_Lock);
+                       if(server->tcpStatus != CifsExiting)
+                               server->tcpStatus = CifsGood;
+                       spin_unlock(&GlobalMid_Lock);
                        atomic_set(&server->inFlight,0);
                        wake_up(&server->response_q);
                }
@@ -243,12 +253,14 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                                /* some servers kill tcp session rather than returning
                                        smb negprot error in which case reconnecting here is
                                        not going to help - return error to mount */
+                               spin_lock(&GlobalMid_Lock);
                                server->tcpStatus = CifsExiting;
+                               spin_unlock(&GlobalMid_Lock);
                                wake_up(&server->response_q);
                                break;
                        }
 
-                       cFYI(1,("Reconnecting after unexpected rcvmsg error "));
+                       cFYI(1,("Reconnecting after unexpected peek error %d",length));
                        cifs_reconnect(server);
                        csocket = server->ssocket;
                        wake_up(&server->response_q);
@@ -268,7 +280,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                                length = sock_recvmsg(csocket, &smb_msg, 4, 0);
                                cFYI(0,("Received 4 byte keep alive packet"));
                        } else if (temp[0] == (char) RFC1002_POSITIVE_SESSION_RESPONSE) {
-                               iov.iov_base = smb_buffer;
+                                       iov.iov_base = smb_buffer;
                                        iov.iov_len = 4;
                                        length = sock_recvmsg(csocket, &smb_msg, 4, 0);
                                        cFYI(1,("Good RFC 1002 session rsp"));
@@ -280,7 +292,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                                        /* if nack on negprot (rather than 
                                        ret of smb negprot error) reconnecting
                                        not going to help, ret error to mount */
+                                       spin_lock(&GlobalMid_Lock);
                                        server->tcpStatus = CifsExiting;
+                                       spin_unlock(&GlobalMid_Lock);
                                        /* wake up thread doing negprot */
                                        wake_up(&server->response_q);
                                        break;
@@ -391,7 +405,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                        }
                }
        }
+       spin_lock(&GlobalMid_Lock);
        server->tcpStatus = CifsExiting;
+       spin_unlock(&GlobalMid_Lock);
        atomic_set(&server->inFlight, 0);
        /* Although there should not be any requests blocked on 
        this queue it can not hurt to be paranoid and try to wake up requests
@@ -595,6 +611,8 @@ cifs_parse_mount_options(char *options, const char *devname, struct smb_vol *vol
                        }
                        if ((temp_len = strnlen(value, 300)) < 300) {
                                vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
+                               if(vol->UNC == NULL)
+                                       return 1;
                                strcpy(vol->UNC,value);
                                if (strncmp(vol->UNC, "//", 2) == 0) {
                                        vol->UNC[0] = '\\';
@@ -742,6 +760,8 @@ cifs_parse_mount_options(char *options, const char *devname, struct smb_vol *vol
                }
                if ((temp_len = strnlen(devname, 300)) < 300) {
                        vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
+                       if(vol->UNC == NULL)
+                               return 1;
                        strcpy(vol->UNC,devname);
                        if (strncmp(vol->UNC, "//", 2) == 0) {
                                vol->UNC[0] = '\\';
@@ -1030,7 +1050,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
                } else {
                /* BB other socket options to set KEEPALIVE, NODELAY? */
                         cFYI(1,("ipv6 Socket created"));
-                        (*csocket)->sk->sk_allocation = GFP_NOFS;
+                       (*csocket)->sk->sk_allocation = GFP_NOFS;
                }
        }
 
@@ -1226,6 +1246,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        init_waitqueue_head(&srvTcp->response_q);
                        init_waitqueue_head(&srvTcp->request_q);
                        INIT_LIST_HEAD(&srvTcp->pending_mid_q);
+                       /* at this point we are the only ones with the pointer
+                       to the struct since the kernel thread not created yet
+                       so no need to spinlock this init of tcpStatus */
                        srvTcp->tcpStatus = CifsNew;
                        init_MUTEX(&srvTcp->tcpSem);
                        kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp,
@@ -1342,9 +1365,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 
 /* on error free sesinfo and tcon struct if needed */
        if (rc) {
-               if(atomic_read(&srvTcp->socketUseCount) == 0)
-                       srvTcp->tcpStatus = CifsExiting;
-                          /* If find_unc succeeded then rc == 0 so we can not end */
+               if(atomic_read(&srvTcp->socketUseCount) == 0) {
+                       spin_lock(&GlobalMid_Lock);
+                       srvTcp->tcpStatus = CifsExiting;
+                       spin_unlock(&GlobalMid_Lock);
+               }
+                /* If find_unc succeeded then rc == 0 so we can not end */
                if (tcon)  /* up here accidently freeing someone elses tcon struct */
                        tconInfoFree(tcon);
                if (existingCifsSes == 0) {
@@ -1534,7 +1560,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                        bcc_ptr +=
                                            pSMBr->resp.SecurityBlobLength;
 
-                               if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+                               if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
                                        if ((long) (bcc_ptr) % 2) {
                                                remaining_words =
                                                    (BCC(smb_buffer_response)
@@ -1787,7 +1813,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                              pSMBr->resp.SecurityBlobLength));
                                }
 
-                               if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+                               if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
                                        if ((long) (bcc_ptr) % 2) {
                                                remaining_words =
                                                    (BCC(smb_buffer_response)
@@ -2098,7 +2124,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                                ses->server->secMode |= 
                                                        SECMODE_SIGN_ENABLED;
 
-                               if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+                               if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
                                        if ((long) (bcc_ptr) % 2) {
                                                remaining_words =
                                                    (BCC(smb_buffer_response)
@@ -2494,7 +2520,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                cFYI(1,
                                     ("NTLMSSP response to Authenticate "));
 
-                               if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+                               if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
                                        if ((long) (bcc_ptr) % 2) {
                                                remaining_words =
                                                    (BCC(smb_buffer_response)
@@ -2693,7 +2719,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
         /* skip service field (NB: this field is always ASCII) */
                bcc_ptr += length + 1;  
                strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
-               if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+               if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
                        length = UniStrnlen((wchar_t *) bcc_ptr, 512);
                        if (((long) bcc_ptr + (2 * length)) -
                            (long) pByteArea(smb_buffer_response) <=
@@ -2791,7 +2817,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
        char ntlm_session_key[CIFS_SESSION_KEY_SIZE];
        int ntlmv2_flag = FALSE;
 
-    /* what if server changes its buffer size after dropping the session? */
+       /* what if server changes its buffer size after dropping the session? */
        if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
                rc = CIFSSMBNegotiate(xid, pSesInfo);
                if(rc == -EAGAIN) /* retry only once on 1st time connection */ {
@@ -2799,8 +2825,15 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
                        if(rc == -EAGAIN) 
                                rc = -EHOSTDOWN;
                }
-               if(rc == 0)
-                       pSesInfo->server->tcpStatus = CifsGood;
+               if(rc == 0) {
+                       spin_lock(&GlobalMid_Lock);
+                       if(pSesInfo->server->tcpStatus != CifsExiting)
+                               pSesInfo->server->tcpStatus = CifsGood;
+                       else
+                               rc = -EHOSTDOWN;
+                       spin_unlock(&GlobalMid_Lock);
+
+               }
        }
        if (!rc) {
                pSesInfo->capabilities = pSesInfo->server->capabilities;
index 7f12af1..85cccbb 100644 (file)
@@ -159,6 +159,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
        struct cifsFileInfo * pCifsFile = NULL;
        struct cifsInodeInfo * pCifsInode;
        int disposition = FILE_OVERWRITE_IF;
+       int write_only = FALSE;
 
        xid = GetXid();
 
@@ -176,9 +177,10 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
        if(nd) {
                if ((nd->intent.open.flags & O_ACCMODE) == O_RDONLY)
                        desiredAccess = GENERIC_READ;
-               else if ((nd->intent.open.flags & O_ACCMODE) == O_WRONLY)
+               else if ((nd->intent.open.flags & O_ACCMODE) == O_WRONLY) {
                        desiredAccess = GENERIC_WRITE;
-               else if ((nd->intent.open.flags & O_ACCMODE) == O_RDWR) {
+                       write_only = TRUE;
+               } else if ((nd->intent.open.flags & O_ACCMODE) == O_RDWR) {
                        /* GENERIC_ALL is too much permission to request */
                        /* can cause unnecessary access denied on create */
                        /* desiredAccess = GENERIC_ALL; */
@@ -262,16 +264,25 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                                pCifsFile->invalidHandle = FALSE;
                                pCifsFile->closePend     = FALSE;
                                init_MUTEX(&pCifsFile->fh_sem);
-                               /* pCifsFile->pfile = file; */ /* put in at open time */
+                               /* put the following in at open now */
+                               /* pCifsFile->pfile = file; */ 
                                write_lock(&GlobalSMBSeslock);
                                list_add(&pCifsFile->tlist,&pTcon->openFileList);
                                pCifsInode = CIFS_I(newinode);
                                if(pCifsInode) {
-                                       list_add(&pCifsFile->flist,&pCifsInode->openFileList);
+                               /* if readable file instance put first in list*/
+                                       if (write_only == TRUE) {
+                                               list_add_tail(&pCifsFile->flist,
+                                                       &pCifsInode->openFileList);
+                                       } else {
+                                               list_add(&pCifsFile->flist,
+                                                       &pCifsInode->openFileList);
+                                       }
                                        if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
                                                pCifsInode->clientCanCacheAll = TRUE;
                                                pCifsInode->clientCanCacheRead = TRUE;
-                                               cFYI(1,("Exclusive Oplock granted on inode %p",newinode));
+                                               cFYI(1,("Exclusive Oplock granted on inode %p",
+                                                       newinode));
                                        } else if((oplock & 0xF) == OPLOCK_READ)
                                                pCifsInode->clientCanCacheRead = TRUE;
                                }
index 39d7b89..1469a40 100644 (file)
@@ -32,9 +32,12 @@ int cifs_directory_notify(unsigned long arg, struct file * file)
 {
        int xid;
        int rc = -EINVAL;
+       int oplock = FALSE;
        struct cifs_sb_info *cifs_sb;
        struct cifsTconInfo *pTcon;
        char *full_path = NULL;
+       __u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES;
+    __u16 netfid;
 
        xid = GetXid();
        cifs_sb = CIFS_SB(file->f_dentry->d_sb);
@@ -48,7 +51,20 @@ int cifs_directory_notify(unsigned long arg, struct file * file)
                rc = -ENOMEM;
        } else {
                cFYI(1,("cifs dir notify on file %s",full_path));
-               /* CIFSSMBNotify(xid, pTcon, full_path, cifs_sb->local_nls);*/
+               rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, 
+                       GENERIC_READ | SYNCHRONIZE, 0 /* create options */,
+                       &netfid, &oplock,NULL, cifs_sb->local_nls);
+               /* BB fixme - add this handle to a notify handle list */
+               if(rc) {
+                       cFYI(1,("Could not open directory for notify"));
+               } else {
+                       rc = CIFSSMBNotify(xid, pTcon, 1 /* subdirs */, netfid, 
+                               filter, cifs_sb->local_nls);
+                       /* BB add code to close file eventually (at unmount
+                       it would close automatically but may be a way
+                       to do it easily when inode freed or when
+                       notify info is cleared/changed */
+               }
        }
        
        FreeXid(xid);
index 87d2896..7d0ac51 100644 (file)
@@ -143,6 +143,10 @@ cifs_open(struct inode *inode, struct file *file)
        /* Also refresh inode by passing in file_info buf returned by SMBOpen 
           and calling get_inode_info with returned buf (at least 
           helps non-Unix server case */
+
+       /* BB we can not do this if this is the second open of a file 
+       and the first handle has writebehind data, we might be 
+       able to simply do a filemap_fdatawrite/filemap_fdatawait first */
        buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
        if(buf==0) {
                if (full_path)
@@ -173,7 +177,14 @@ cifs_open(struct inode *inode, struct file *file)
                        list_add(&pCifsFile->tlist,&pTcon->openFileList);
                        pCifsInode = CIFS_I(file->f_dentry->d_inode);
                        if(pCifsInode) {
-                               list_add(&pCifsFile->flist,&pCifsInode->openFileList);
+                               /* want handles we can use to read with first */
+                               /* in the list so we do not have to walk the */
+                               /* list to search for one in prepare_write */
+                               if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
+                                       list_add_tail(&pCifsFile->flist,&pCifsInode->openFileList);
+                               } else {
+                                       list_add(&pCifsFile->flist,&pCifsInode->openFileList);
+                               }
                                write_unlock(&GlobalSMBSeslock);
                                write_unlock(&file->f_owner.lock);
                                if(pCifsInode->clientCanCacheRead) {
@@ -256,7 +267,7 @@ static int cifs_relock_file(struct cifsFileInfo * cifsFile)
        return rc;
 }
 
-static int cifs_reopen_file(struct inode *inode, struct file *file)
+static int cifs_reopen_file(struct inode *inode, struct file *file, int can_flush)
 {
        int rc = -EACCES;
        int xid, oplock;
@@ -268,7 +279,6 @@ static int cifs_reopen_file(struct inode *inode, struct file *file)
        int desiredAccess = 0x20197;
        int disposition = FILE_OPEN;
        __u16 netfid;
-       FILE_ALL_INFO * buf = NULL;
 
        if(inode == NULL)
                return -EBADF;
@@ -321,21 +331,23 @@ and we can never tell if the caller already has the rename_sem */
        else
                oplock = FALSE;
 
-               /* BB pass O_SYNC flag through on file attributes .. BB */
+       
+       /* Can not refresh inode by passing in file_info buf to be returned
+        by SMBOpen and then calling get_inode_info with returned buf 
+        since file might have write behind data that needs to be flushed 
+        and server version of file size can be stale. If we 
+        knew for sure that inode was not dirty locally we could do this */
 
-               /* Also refresh inode by passing in file_info buf returned by SMBOpen
-                  and calling get_inode_info with returned buf (at least
-                  helps non-Unix server case */
-       buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
+/*     buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
        if(buf==0) {
                up(&pCifsFile->fh_sem);
                if (full_path)
                        kfree(full_path);
                FreeXid(xid);
                return -ENOMEM;
-       }
+       }*/
        rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
-                               CREATE_NOT_DIR, &netfid, &oplock, buf, cifs_sb->local_nls);
+                               CREATE_NOT_DIR, &netfid, &oplock, NULL, cifs_sb->local_nls);
        if (rc) {
                up(&pCifsFile->fh_sem);
                cFYI(1, ("cifs_open returned 0x%x ", rc));
@@ -346,13 +358,25 @@ and we can never tell if the caller already has the rename_sem */
                up(&pCifsFile->fh_sem);
                pCifsInode = CIFS_I(inode);
                if(pCifsInode) {
-                       if (pTcon->ses->capabilities & CAP_UNIX)
-                               rc = cifs_get_inode_info_unix(&inode,
+                       if(can_flush) {
+                               filemap_fdatawrite(inode->i_mapping);
+                               filemap_fdatawait(inode->i_mapping);
+                       /* temporarily disable caching while we
+                       go to server to get inode info */
+                               pCifsInode->clientCanCacheAll = FALSE;
+                               pCifsInode->clientCanCacheRead = FALSE;
+                               if (pTcon->ses->capabilities & CAP_UNIX)
+                                       rc = cifs_get_inode_info_unix(&inode,
                                                full_path, inode->i_sb);
-                       else
-                               rc = cifs_get_inode_info(&inode,
-                                               full_path, buf, inode->i_sb);
-
+                               else
+                                       rc = cifs_get_inode_info(&inode,
+                                               full_path, NULL, inode->i_sb);
+                       } /* else we are writing out data to server already
+                       and could deadlock if we tried to flush data, and 
+                       since we do not know if we have data that would
+                       invalidate the current end of file on the server
+                       we can not go to the server to get the new
+                       inod info */
                        if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
                                pCifsInode->clientCanCacheAll =  TRUE;
                                pCifsInode->clientCanCacheRead = TRUE;
@@ -368,8 +392,6 @@ and we can never tell if the caller already has the rename_sem */
                }
        }
 
-       if (buf)
-               kfree(buf);
        if (full_path)
                kfree(full_path);
        FreeXid(xid);
@@ -605,7 +627,11 @@ cifs_write(struct file * file, const char *write_data,
                                        FreeXid(xid);
                                        return total_written;
                                }
-                               rc = cifs_reopen_file(file->f_dentry->d_inode,file);
+                               /* we could deadlock if we called
+                                filemap_fdatawait from here so tell
+                               reopen_file not to flush data to server now */
+                               rc = cifs_reopen_file(file->f_dentry->d_inode,
+                                       file,FALSE);
                                if(rc != 0)
                                        break;
                        }
@@ -701,6 +727,7 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
 
        cifsInode = CIFS_I(mapping->host);
        read_lock(&GlobalSMBSeslock); 
+       /* BB we should start at the end */
        list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {            
                open_file = list_entry(tmp,struct cifsFileInfo, flist);
                if(open_file->closePend)
@@ -770,6 +797,9 @@ cifs_writepage(struct page* page, struct writeback_control *wbc)
        xid = GetXid();
 /* BB add check for wbc flags */
        page_cache_get(page);
+        if (!PageUptodate(page)) {
+               cFYI(1,("ppw - page not up to date"));
+       }
        
        rc = cifs_partialpagewrite(page,0,PAGE_CACHE_SIZE);
        SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
@@ -787,8 +817,7 @@ cifs_commit_write(struct file *file, struct page *page, unsigned offset,
        int rc = 0;
        struct inode *inode = page->mapping->host;
        loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
-       /* struct cifsFileInfo *open_file;
-       struct cifs_sb_info *cifs_sb; */
+       char * page_data;
 
        xid = GetXid();
        cFYI(1,("commit write for page %p up to position %lld for %d",page,position,to));
@@ -819,7 +848,31 @@ cifs_commit_write(struct file *file, struct page *page, unsigned offset,
                        cFYI(1,(" SetEOF (commit write) rc = %d",rc));
                }*/
        }
-       set_page_dirty(page);
+       if (!PageUptodate(page)) {
+               position =  ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
+               /* can not rely on (or let) writepage write this data */
+               if(to < offset) {
+                       cFYI(1,("Illegal offsets, can not copy from %d to %d",
+                               offset,to));
+                       FreeXid(xid);
+                       return rc;
+               }
+               /* this is probably better than directly calling 
+               partialpage_write since in this function
+               the file handle is known which we might as well
+               leverage */
+               /* BB check if anything else missing out of ppw */
+               /* such as updating last write time */
+               page_data = kmap(page);
+               rc = cifs_write(file, page_data+offset,to-offset,
+                                        &position);
+               if(rc > 0)
+                       rc = 0;
+               /* else if rc < 0 should we set writebehind rc? */
+               kunmap(page);
+       } else {        
+               set_page_dirty(page);
+       }
 
        FreeXid(xid);
        return rc;
@@ -924,13 +977,18 @@ cifs_read(struct file * file, char *read_data, size_t read_size,
        }
        open_file = (struct cifsFileInfo *)file->private_data;
 
+       if((file->f_flags & O_ACCMODE) == O_WRONLY) {
+               cFYI(1,("attempting read on write only file instance"));
+       }
+
        for (total_read = 0,current_offset=read_data; read_size > total_read;
                                total_read += bytes_read,current_offset+=bytes_read) {
                current_read_size = min_t(const int,read_size - total_read,cifs_sb->rsize);
                rc = -EAGAIN;
                while(rc == -EAGAIN) {
                        if ((open_file->invalidHandle) && (!open_file->closePend)) {
-                               rc = cifs_reopen_file(file->f_dentry->d_inode,file);
+                               rc = cifs_reopen_file(file->f_dentry->d_inode,
+                                       file,TRUE);
                                if(rc != 0)
                                        break;
                        }
@@ -1085,7 +1143,8 @@ cifs_readpages(struct file *file, struct address_space *mapping,
                rc = -EAGAIN;
                while(rc == -EAGAIN) {
                        if ((open_file->invalidHandle) && (!open_file->closePend)) {
-                               rc = cifs_reopen_file(file->f_dentry->d_inode,file);
+                               rc = cifs_reopen_file(file->f_dentry->d_inode,
+                                       file, TRUE);
                                if(rc != 0)
                                        break;
                        }
@@ -1169,53 +1228,105 @@ cifs_readpages(struct file *file, struct address_space *mapping,
        return rc;
 }
 
-static int
-cifs_readpage(struct file *file, struct page *page)
+static int cifs_readpage_worker(struct file *file, struct page *page, loff_t * poffset)
 {
-       loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
        char * read_data;
-       int rc = -EACCES;
-       int xid;
-
-       xid = GetXid();
-
-       if (file->private_data == NULL) {
-               FreeXid(xid);
-               return -EBADF;
-       }
-
-       cFYI(0,("readpage %p at offset %d 0x%x\n",page,(int)offset,(int)offset));
+       int rc;
 
        page_cache_get(page);
        read_data = kmap(page);
        /* for reads over a certain size could initiate async read ahead */
-
-       rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, &offset);
-
+                                                                                                                           
+       rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset);
+                                                                                                                           
        if (rc < 0)
                goto io_error;
        else {
                cFYI(1,("Bytes read %d ",rc));
        }
-
+                                                                                                                           
        file->f_dentry->d_inode->i_atime = CURRENT_TIME;
-
+                                                                                                                           
        if(PAGE_CACHE_SIZE > rc) {
                memset(read_data+rc, 0, PAGE_CACHE_SIZE - rc);
        }
        flush_dcache_page(page);
        SetPageUptodate(page);
        rc = 0;
-
+                                                                                                                           
 io_error:
-       kunmap(page);
+        kunmap(page);
+       page_cache_release(page);
+       return rc;
+}
+
+static int
+cifs_readpage(struct file *file, struct page *page)
+{
+       loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
+       int rc = -EACCES;
+       int xid;
+
+       xid = GetXid();
+
+       if (file->private_data == NULL) {
+               FreeXid(xid);
+               return -EBADF;
+       }
+
+       cFYI(1,("readpage %p at offset %d 0x%x\n",page,(int)offset,(int)offset));
+
+       rc = cifs_readpage_worker(file,page,&offset);
+
        unlock_page(page);
 
-       page_cache_release(page);
        FreeXid(xid);
        return rc;
 }
 
+/* We do not want to update the file size from server for inodes
+   open for write - to avoid races with writepage extending
+   the file - in the future we could consider allowing
+   refreshing the inode only on increases in the file size 
+   but this is tricky to do without racing with writebehind
+   page caching in the current Linux kernel design */
+   
+int is_size_safe_to_change(struct cifsInodeInfo * cifsInode)
+{
+       struct list_head *tmp;
+       struct list_head *tmp1;
+       struct cifsFileInfo *open_file = NULL;
+       int rc = TRUE;
+
+       if(cifsInode == NULL)
+               return rc;
+
+       read_lock(&GlobalSMBSeslock); 
+       list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {            
+               open_file = list_entry(tmp,struct cifsFileInfo, flist);
+               if(open_file == NULL)
+                       break;
+               if(open_file->closePend)
+                       continue;
+       /* We check if file is open for writing,   
+       BB we could supplement this with a check to see if file size
+       changes have been flushed to server - ie inode metadata dirty */
+               if((open_file->pfile) && 
+          ((open_file->pfile->f_flags & O_RDWR) || 
+               (open_file->pfile->f_flags & O_WRONLY))) {
+                        rc = FALSE;
+                        break;
+               }
+               if(tmp->next == NULL) {
+                       cFYI(1,("File instance %p removed",tmp));
+                       break;
+               }
+       }
+       read_unlock(&GlobalSMBSeslock);
+       return rc;
+}
+
+
 void
 fill_in_inode(struct inode *tmp_inode,
              FILE_DIRECTORY_INFO * pfindData, int *pobject_type)
@@ -1275,9 +1386,16 @@ fill_in_inode(struct inode *tmp_inode,
                atomic_set(&cifsInfo->inUse,1);
        }
 
-       i_size_write(tmp_inode,pfindData->EndOfFile);
-       tmp_inode->i_blocks =
-               (tmp_inode->i_blksize - 1 + pfindData->AllocationSize) >> tmp_inode->i_blkbits;
+       if(is_size_safe_to_change(cifsInfo)) {
+               /* can not safely change the file size here if the 
+               client is writing to it due to potential races */
+               i_size_write(tmp_inode,pfindData->EndOfFile);
+
+       /* 512 bytes (2**9) is the fake blocksize that must be used */
+       /* for this calculation, even though the reported blocksize is larger */
+               tmp_inode->i_blocks = (512 - 1 + pfindData->AllocationSize) >> 9;
+       }
+
        if (pfindData->AllocationSize < pfindData->EndOfFile)
                cFYI(1, ("Possible sparse file: allocation size less than end of file "));
        cFYI(1,
@@ -1348,10 +1466,17 @@ unix_fill_in_inode(struct inode *tmp_inode,
        tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks);
 
        pfindData->NumOfBytes = le64_to_cpu(pfindData->NumOfBytes);
-       pfindData->EndOfFile = le64_to_cpu(pfindData->EndOfFile);
-       i_size_write(tmp_inode,pfindData->EndOfFile);
-       tmp_inode->i_blocks =
-                (tmp_inode->i_blksize - 1 + pfindData->NumOfBytes) >> tmp_inode->i_blkbits;
+
+       if(is_size_safe_to_change(cifsInfo)) {
+               /* can not safely change the file size here if the 
+               client is writing to it due to potential races */
+               pfindData->EndOfFile = le64_to_cpu(pfindData->EndOfFile);
+               i_size_write(tmp_inode,pfindData->EndOfFile);
+
+       /* 512 bytes (2**9) is the fake blocksize that must be used */
+       /* for this calculation, not the real blocksize */
+               tmp_inode->i_blocks = (512 - 1 + pfindData->NumOfBytes) >> 9;
+       }
 
        if (S_ISREG(tmp_inode->i_mode)) {
                cFYI(1, ("File inode"));
@@ -1393,12 +1518,15 @@ construct_dentry(struct qstr *qstring, struct file *file,
                /* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */
                if(*ptmp_inode == NULL) {
                        *ptmp_inode = new_inode(file->f_dentry->d_sb);
+                       if(*ptmp_inode == NULL)
+                               return;
                        d_instantiate(tmp_dentry, *ptmp_inode);
                }
        } else {
                tmp_dentry = d_alloc(file->f_dentry, qstring);
                if(tmp_dentry == NULL) {
                        cERROR(1,("Failed allocating dentry"));
+                       *ptmp_inode = NULL;
                        return;
                }
                        
@@ -1406,6 +1534,8 @@ construct_dentry(struct qstr *qstring, struct file *file,
                tmp_dentry->d_op = &cifs_dentry_ops;
                cFYI(0, (" instantiate dentry 0x%p with inode 0x%p ",
                         tmp_dentry, *ptmp_inode));
+               if(*ptmp_inode == NULL)
+                       return;
                d_instantiate(tmp_dentry, *ptmp_inode);
                d_rehash(tmp_dentry);
        }
@@ -1462,7 +1592,9 @@ cifs_filldir(struct qstr *pqstring, FILE_DIRECTORY_INFO * pfindData,
        pqstring->len = pfindData->FileNameLength;
 
        construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
-
+       if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
+               return -ENOMEM;
+       }
        fill_in_inode(tmp_inode, pfindData, &object_type);
        rc = filldir(direntry, pfindData->FileName, pqstring->len, file->f_pos,
                tmp_inode->i_ino, object_type);
@@ -1488,6 +1620,9 @@ cifs_filldir_unix(struct qstr *pqstring,
        pqstring->len = strnlen(pUnixFindData->FileName, MAX_PATHCONF);
 
        construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
+       if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
+               return -ENOMEM;
+       }
 
        unix_fill_in_inode(tmp_inode, pUnixFindData, &object_type);
        rc = filldir(direntry, pUnixFindData->FileName, pqstring->len,
@@ -1950,17 +2085,34 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
 int cifs_prepare_write(struct file *file, struct page *page,
                        unsigned from, unsigned to)
 {
+       int rc = 0;
+        loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
        cFYI(1,("prepare write for page %p from %d to %d",page,from,to));
        if (!PageUptodate(page)) {
-               if (to - from != PAGE_CACHE_SIZE) {
+       /*      if (to - from != PAGE_CACHE_SIZE) {
                        void *kaddr = kmap_atomic(page, KM_USER0);
                        memset(kaddr, 0, from);
                        memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
                        flush_dcache_page(page);
                        kunmap_atomic(kaddr, KM_USER0);
+               } */
+               /* If we are writing a full page it will be up to date,
+               no need to read from the server */
+               if((to==PAGE_CACHE_SIZE) && (from == 0))
+                       SetPageUptodate(page);
+
+               /* might as well read a page, it is fast enough */
+               if((file->f_flags & O_ACCMODE) != O_WRONLY) {
+                       rc = cifs_readpage_worker(file,page,&offset);
+               } else {
+               /* should we try using another
+               file handle if there is one - how would we lock it
+               to prevent close of that handle racing with this read? */
+               /* In any case this will be written out by commit_write */
                }
-               SetPageUptodate(page);
        }
+
+       /* BB should we pass any errors back? e.g. if we do not have read access to the file */
        return 0;
 }
 
@@ -1969,8 +2121,7 @@ struct address_space_operations cifs_addr_ops = {
        .readpage = cifs_readpage,
        .readpages = cifs_readpages,
        .writepage = cifs_writepage,
-       .prepare_write = simple_prepare_write, /* BB fixme BB */
-/*     .prepare_write = cifs_prepare_write, */  /* BB removeme BB */
+       .prepare_write = cifs_prepare_write, 
        .commit_write = cifs_commit_write,
    /* .sync_page = cifs_sync_page, */
        /*.direct_IO = */
index e3c47ee..c12231b 100644 (file)
@@ -30,6 +30,8 @@
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
 
+extern int is_size_safe_to_change(struct cifsInodeInfo *);
+
 int
 cifs_get_inode_info_unix(struct inode **pinode,
                         const unsigned char *search_path,
@@ -43,9 +45,6 @@ cifs_get_inode_info_unix(struct inode **pinode,
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
        char *tmp_path;
 
-/* BB add caching check so we do not go to server to overwrite inode info to cached file
-       where the local file sizes are correct and the server info is stale  BB */
-
        xid = GetXid();
 
        pTcon = cifs_sb->tcon;
@@ -125,13 +124,29 @@ cifs_get_inode_info_unix(struct inode **pinode,
                inode->i_nlink = le64_to_cpu(findData.Nlinks);
                findData.NumOfBytes = le64_to_cpu(findData.NumOfBytes);
                findData.EndOfFile = le64_to_cpu(findData.EndOfFile);
-               i_size_write(inode,findData.EndOfFile);
+
+               if(is_size_safe_to_change(cifsInfo)) {
+               /* can not safely change the file size here if the 
+                  client is writing to it due to potential races */
+
+                       i_size_write(inode,findData.EndOfFile);
 /* blksize needs to be multiple of two. So safer to default to blksize
        and blkbits set in superblock so 2**blkbits and blksize will match */
 /*             inode->i_blksize =
                    (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
-               inode->i_blocks = 
-                       (inode->i_blksize - 1 + findData.NumOfBytes) >> inode->i_blkbits;
+
+               /* This seems incredibly stupid but it turns out that
+               i_blocks is not related to (i_size / i_blksize), instead a
+               size of 512 is required to be used for calculating num blocks */
+                
+
+/*             inode->i_blocks = 
+                       (inode->i_blksize - 1 + findData.NumOfBytes) >> inode->i_blkbits;*/
+
+               /* 512 bytes (2**9) is the fake blocksize that must be used */
+               /* for this calculation */
+                       inode->i_blocks = (512 - 1 + findData.NumOfBytes) >> 9;
+               }
 
                if (findData.NumOfBytes < findData.EndOfFile)
                        cFYI(1, ("Server inconsistency Error: it says allocation size less than end of file "));
@@ -273,10 +288,18 @@ cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path,
                                inode->i_mode &= ~(S_IWUGO);
    /* BB add code here - validate if device or weird share or device type? */
                }
-               i_size_write(inode,le64_to_cpu(pfindData->EndOfFile));
+               if(is_size_safe_to_change(cifsInfo)) {
+               /* can not safely change the file size here if the 
+               client is writing to it due to potential races */
+
+                       i_size_write(inode,le64_to_cpu(pfindData->EndOfFile));
+
+               /* 512 bytes (2**9) is the fake blocksize that must be used */
+               /* for this calculation */
+                       inode->i_blocks = (512 - 1 + pfindData->AllocationSize)
+                                >> 9;
+               }
                pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize);
-               inode->i_blocks =
-                       (inode->i_blksize - 1 + pfindData->AllocationSize) >> inode->i_blkbits;
 
                inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks);
 
@@ -556,9 +579,38 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
        rc = CIFSSMBRename(xid, pTcon, fromName, toName,
                           cifs_sb_source->local_nls);
        if(rc == -EEXIST) {
-               cifs_unlink(target_inode, target_direntry);
-               rc = CIFSSMBRename(xid, pTcon, fromName, toName,
-                                  cifs_sb_source->local_nls);
+               /* check if they are the same file 
+               because rename of hardlinked files is a noop */
+               FILE_UNIX_BASIC_INFO * info_buf_source;
+               FILE_UNIX_BASIC_INFO * info_buf_target;
+
+               info_buf_source = 
+                       kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),GFP_KERNEL);
+               if(info_buf_source != NULL) {
+                       info_buf_target = info_buf_source+1;
+                       rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, 
+                               info_buf_source, cifs_sb_source->local_nls);
+                       if(rc == 0) {
+                               rc = CIFSSMBUnixQPathInfo(xid,pTcon,toName,
+                                               info_buf_target,
+                                               cifs_sb_target->local_nls);
+                       }
+                       if((rc == 0) && 
+                               (info_buf_source->UniqueId == 
+                                info_buf_target->UniqueId)) {
+                       /* do not rename since the files are hardlinked 
+                          which is a noop */
+                       } else {
+                       /* we either can not tell the files are hardlinked
+                       (as with Windows servers) or files are not hardlinked 
+                       so delete the target manually before renaming to
+                       follow POSIX rather than Windows semantics */
+                               cifs_unlink(target_inode, target_direntry);
+                               rc = CIFSSMBRename(xid, pTcon, fromName, toName,
+                                       cifs_sb_source->local_nls);
+                       }
+                       kfree(info_buf_source);
+               } /* if we can not get memory just leave rc as EEXIST */
        }
 
        if((rc == -EIO)||(rc == -EEXIST)) {
index 38cb122..f257ff0 100644 (file)
@@ -210,7 +210,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
 }
 
 int
-cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
+cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
 {
        struct inode *inode = direntry->d_inode;
        int rc = -EACCES;
index c55118c..3668ab0 100644 (file)
@@ -120,13 +120,13 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
         unsigned int smb_buf_length, struct sockaddr *sin)
 {
        int rc = 0;
+       int i = 0;
        struct msghdr smb_msg;
        struct iovec iov;
        mm_segment_t temp_fs;
 
        if(ssocket == NULL)
                return -ENOTSOCK; /* BB eventually add reconnect code here */
-/*  ssocket->sk->allocation = GFP_BUFFER; *//* BB is this spurious? */
        iov.iov_base = smb_buffer;
        iov.iov_len = smb_buf_length + 4;
 
@@ -152,6 +152,14 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
        while(iov.iov_len > 0) {
                rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4);
                if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
+                       i++;
+                       if(i > 60) {
+                               cERROR(1,
+                                  ("sends on sock %p stuck for 30 seconds",
+                                   ssocket));
+                               rc = -EAGAIN;
+                               break;
+                       }
                        set_current_state(TASK_INTERRUPTIBLE);
                        schedule_timeout(HZ/2);
                        continue;
@@ -260,7 +268,17 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
        midQ->midState = MID_REQUEST_SUBMITTED;
        rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
                      (struct sockaddr *) &(ses->server->addr.sockAddr));
-       up(&ses->server->tcpSem);
+       if(rc < 0) {
+               DeleteMidQEntry(midQ);
+               up(&ses->server->tcpSem);
+               /* If not lock req, update # of requests on wire to server */
+               if(long_op < 3) {
+                       atomic_dec(&ses->server->inFlight); 
+                       wake_up(&ses->server->request_q);
+               }
+               return rc;
+       } else
+               up(&ses->server->tcpSem);
        if (long_op == -1)
                goto cifs_no_response_exit;
        else if (long_op == 2) /* writes past end of file can take looooong time */
index e377fa0..dd6a2c0 100644 (file)
  */
 
 #include <linux/fs.h>
+#include "cifsfs.h"
+#include "cifspdu.h"
+#include "cifsglob.h"
+#include "cifsproto.h"
+#include "cifs_debug.h"
 
 int cifs_removexattr(struct dentry * direntry, const char * name)
 {
-        int rc = -EOPNOTSUPP;
-        return rc;
+       int rc = -EOPNOTSUPP;
+       return rc;
 }
 
 int cifs_setxattr(struct dentry * direntry, const char * name,
         const void * value, size_t size, int flags)
 {
-        int rc = -EOPNOTSUPP;
-        return rc;
+       int rc = -EOPNOTSUPP;
+       return rc;
 }
 
 ssize_t cifs_getxattr(struct dentry * direntry, const char * name,
          void * value, size_t size)
 {
-        ssize_t rc = -EOPNOTSUPP;
-        return rc;
+       ssize_t rc = -EOPNOTSUPP;
+       return rc;
 }
 
 ssize_t cifs_listxattr(struct dentry * direntry, char * ea_data, size_t ea_size)
 {
-        ssize_t rc = -EOPNOTSUPP;
+       ssize_t rc = -EOPNOTSUPP;
+#ifdef CONFIG_CIFS_XATTR
+       int xid;
+       struct cifs_sb_info *cifs_sb;
+       struct cifsTconInfo *pTcon;
+       struct super_block * sb;
+       char * full_path;
+       if(direntry == NULL)
+               return -EIO;
+       if(direntry->d_inode == NULL)
+               return -EIO;
+       sb = direntry->d_inode->i_sb;
+       if(sb == NULL)
+               return -EIO;
+       xid = GetXid();
 
+       cifs_sb = CIFS_SB(sb);
+       pTcon = cifs_sb->tcon;
+
+       down(&sb->s_vfs_rename_sem);
+       full_path = build_path_from_dentry(direntry);
+       up(&sb->s_vfs_rename_sem);
+       if(full_path == NULL) {
+               FreeXid(xid);
+               return -ENOMEM;
+       }
        /* return dosattributes as pseudo xattr */
        /* return alt name if available as pseudo attr */
 
        /* if proc/fs/cifs/streamstoxattr is set then
                search server for EAs or streams to 
                returns as xattrs */
-
-        return rc;
+       rc = CIFSSMBQAllEAs(xid,pTcon,full_path,ea_data,ea_size,cifs_sb->local_nls);
+       FreeXid(xid);
+#endif
+       return rc;
 }
index 768b2a1..f0c867c 100644 (file)
@@ -29,7 +29,7 @@
 int use_coda_close;
 
 static ssize_t
-coda_file_read(struct file *coda_file, char *buf, size_t count, loff_t *ppos)
+coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *ppos)
 {
        struct coda_file_info *cfi;
        struct file *host_file;
@@ -45,7 +45,7 @@ coda_file_read(struct file *coda_file, char *buf, size_t count, loff_t *ppos)
 }
 
 static ssize_t
-coda_file_write(struct file *coda_file, const char *buf, size_t count, loff_t *ppos)
+coda_file_write(struct file *coda_file, const char __user *buf, size_t count, loff_t *ppos)
 {
        struct inode *host_inode, *coda_inode = coda_file->f_dentry->d_inode;
        struct coda_file_info *cfi;
index e10ac76..1277149 100644 (file)
@@ -58,7 +58,7 @@ static int coda_pioctl(struct inode * inode, struct file * filp,
         struct coda_inode_info *cnp;
 
         /* get the Pioctl data arguments from user space */
-        if (copy_from_user(&data, (int *)user_data, sizeof(data))) {
+        if (copy_from_user(&data, (void __user *)user_data, sizeof(data))) {
            return -EINVAL;
        }
        
index 14f665e..7d55a28 100644 (file)
@@ -88,7 +88,7 @@ static int coda_psdev_ioctl(struct inode * inode, struct file * filp,
        switch(cmd) {
        case CIOC_KERNEL_VERSION:
                data = CODA_KERNEL_VERSION;
-               return put_user(data, (int *) arg);
+               return put_user(data, (int __user *) arg);
        default:
                return -ENOTTY;
        }
@@ -100,7 +100,7 @@ static int coda_psdev_ioctl(struct inode * inode, struct file * filp,
  *     Receive a message written by Venus to the psdev
  */
  
-static ssize_t coda_psdev_write(struct file *file, const char *buf, 
+static ssize_t coda_psdev_write(struct file *file, const char __user *buf, 
                                size_t nbytes, loff_t *off)
 {
         struct venus_comm *vcp = (struct venus_comm *) file->private_data;
@@ -212,7 +212,7 @@ out:
  *     Read a message from the kernel to Venus
  */
 
-static ssize_t coda_psdev_read(struct file * file, char * buf, 
+static ssize_t coda_psdev_read(struct file * file, char __user * buf, 
                               size_t nbytes, loff_t *off)
 {
        DECLARE_WAITQUEUE(wait, current);
index 7c8a136..f1692b5 100644 (file)
@@ -69,7 +69,7 @@ void reset_coda_cache_inv_stats( void )
 }
 
 int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
-                            void * buffer, size_t * lenp )
+                            void __user * buffer, size_t * lenp )
 {
        if ( write ) {
                reset_coda_vfs_stats();
@@ -83,7 +83,7 @@ int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
 }
 
 int do_reset_coda_cache_inv_stats( ctl_table * table, int write, 
-                                  struct file * filp, void * buffer, 
+                                  struct file * filp, void __user * buffer, 
                                   size_t * lenp )
 {
        if ( write ) {
@@ -214,7 +214,7 @@ struct proc_dir_entry* proc_fs_coda;
 #define coda_proc_create(name,get_info) \
        create_proc_info_entry(name, 0, proc_fs_coda, get_info)
 
-void coda_sysctl_init()
+void coda_sysctl_init(void)
 {
        reset_coda_vfs_stats();
        reset_coda_cache_inv_stats();
@@ -234,7 +234,7 @@ void coda_sysctl_init()
 #endif 
 }
 
-void coda_sysctl_clean() 
+void coda_sysctl_clean(void
 {
 
 #ifdef CONFIG_SYSCTL
index 689fdd0..0d61f0f 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/syscalls.h>
 #include <linux/ctype.h>
 #include <linux/module.h>
+#include <linux/dirent.h>
 #include <linux/dnotify.h>
 #include <linux/highuid.h>
 #include <linux/sunrpc/svc.h>
@@ -797,6 +798,260 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
        return retval;
 }
 
+#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
+#define COMPAT_ROUND_UP(x) (((x)+sizeof(compat_long_t)-1) & \
+                               ~(sizeof(compat_long_t)-1))
+
+struct compat_old_linux_dirent {
+       compat_ulong_t  d_ino;
+       compat_ulong_t  d_offset;
+       unsigned short  d_namlen;
+       char            d_name[1];
+};
+
+struct compat_readdir_callback {
+       struct compat_old_linux_dirent __user *dirent;
+       int result;
+};
+
+static int compat_fillonedir(void *__buf, const char *name, int namlen,
+                       loff_t offset, ino_t ino, unsigned int d_type)
+{
+       struct compat_readdir_callback *buf = __buf;
+       struct compat_old_linux_dirent __user *dirent;
+
+       if (buf->result)
+               return -EINVAL;
+       buf->result++;
+       dirent = buf->dirent;
+       if (!access_ok(VERIFY_WRITE, (unsigned long)dirent,
+                       (unsigned long)(dirent->d_name + namlen + 1) -
+                               (unsigned long)dirent))
+               goto efault;
+       if (    __put_user(ino, &dirent->d_ino) ||
+               __put_user(offset, &dirent->d_offset) ||
+               __put_user(namlen, &dirent->d_namlen) ||
+               __copy_to_user(dirent->d_name, name, namlen) ||
+               __put_user(0, dirent->d_name + namlen))
+               goto efault;
+       return 0;
+efault:
+       buf->result = -EFAULT;
+       return -EFAULT;
+}
+
+asmlinkage long compat_old_readdir(unsigned int fd,
+       struct compat_old_linux_dirent __user *dirent, unsigned int count)
+{
+       int error;
+       struct file *file;
+       struct compat_readdir_callback buf;
+
+       error = -EBADF;
+       file = fget(fd);
+       if (!file)
+               goto out;
+
+       buf.result = 0;
+       buf.dirent = dirent;
+
+       error = vfs_readdir(file, compat_fillonedir, &buf);
+       if (error >= 0)
+               error = buf.result;
+
+       fput(file);
+out:
+       return error;
+}
+
+struct compat_linux_dirent {
+       compat_ulong_t  d_ino;
+       compat_ulong_t  d_off;
+       unsigned short  d_reclen;
+       char            d_name[1];
+};
+
+struct compat_getdents_callback {
+       struct compat_linux_dirent __user *current_dir;
+       struct compat_linux_dirent __user *previous;
+       int count;
+       int error;
+};
+
+static int compat_filldir(void *__buf, const char *name, int namlen,
+               loff_t offset, ino_t ino, unsigned int d_type)
+{
+       struct compat_linux_dirent __user * dirent;
+       struct compat_getdents_callback *buf = __buf;
+       int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
+
+       buf->error = -EINVAL;   /* only used if we fail.. */
+       if (reclen > buf->count)
+               return -EINVAL;
+       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))
+               goto efault;
+       if (__put_user(reclen, &dirent->d_reclen))
+               goto efault;
+       if (copy_to_user(dirent->d_name, name, namlen))
+               goto efault;
+       if (__put_user(0, dirent->d_name + namlen))
+               goto efault;
+       if (__put_user(d_type, (char  __user *) dirent + reclen - 1))
+               goto efault;
+       buf->previous = dirent;
+       dirent = (void __user *)dirent + reclen;
+       buf->current_dir = dirent;
+       buf->count -= reclen;
+       return 0;
+efault:
+       buf->error = -EFAULT;
+       return -EFAULT;
+}
+
+asmlinkage long compat_sys_getdents(unsigned int fd,
+               struct compat_linux_dirent __user *dirent, unsigned int count)
+{
+       struct file * file;
+       struct compat_linux_dirent __user * lastdirent;
+       struct compat_getdents_callback buf;
+       int error;
+
+       error = -EFAULT;
+       if (!access_ok(VERIFY_WRITE, dirent, count))
+               goto out;
+
+       error = -EBADF;
+       file = fget(fd);
+       if (!file)
+               goto out;
+
+       buf.current_dir = dirent;
+       buf.previous = NULL;
+       buf.count = count;
+       buf.error = 0;
+
+       error = vfs_readdir(file, compat_filldir, &buf);
+       if (error < 0)
+               goto out_putf;
+       error = buf.error;
+       lastdirent = buf.previous;
+       if (lastdirent) {
+               if (put_user(file->f_pos, &lastdirent->d_off))
+                       error = -EFAULT;
+               else
+                       error = count - buf.count;
+       }
+
+out_putf:
+       fput(file);
+out:
+       return error;
+}
+
+#ifndef __ARCH_OMIT_COMPAT_SYS_GETDENTS64
+#define COMPAT_ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
+
+struct compat_getdents_callback64 {
+       struct linux_dirent64 __user *current_dir;
+       struct linux_dirent64 __user *previous;
+       int count;
+       int error;
+};
+
+static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset,
+                    ino_t ino, unsigned int d_type)
+{
+       struct linux_dirent64 __user *dirent;
+       struct compat_getdents_callback64 *buf = __buf;
+       int jj = NAME_OFFSET(dirent);
+       int reclen = COMPAT_ROUND_UP64(jj + namlen + 1);
+       u64 off;
+
+       buf->error = -EINVAL;   /* only used if we fail.. */
+       if (reclen > buf->count)
+               return -EINVAL;
+       dirent = buf->previous;
+
+       if (dirent) {
+               if (__put_user(offset, (u32 __user *)&dirent->d_off))
+                       goto efault;
+               if (__put_user(offset >> 32,
+                               ((u32 __user *)&dirent->d_off) + 1))
+                       goto efault;
+       }
+       dirent = buf->current_dir;
+       if ((__put_user(ino, (u32 __user *)&dirent->d_ino))
+        || (__put_user(ino >> 32, ((u32 __user *)&dirent->d_ino) + 1)))
+               goto efault;
+       off = 0;
+       if ((__put_user(off, (u32 __user *)&dirent->d_off))
+        || (__put_user(off >> 32, ((u32 __user *)&dirent->d_off) + 1)))
+               goto efault;
+       if (__put_user(reclen, &dirent->d_reclen))
+               goto efault;
+       if (__put_user(d_type, &dirent->d_type))
+               goto efault;
+       if (copy_to_user(dirent->d_name, name, namlen))
+               goto efault;
+       if (__put_user(0, dirent->d_name + namlen))
+               goto efault;
+       buf->previous = dirent;
+       dirent = (void __user *)dirent + reclen;
+       buf->current_dir = dirent;
+       buf->count -= reclen;
+       return 0;
+efault:
+       buf->error = -EFAULT;
+       return -EFAULT;
+}
+
+asmlinkage long compat_sys_getdents64(unsigned int fd,
+               struct linux_dirent64 __user * dirent, unsigned int count)
+{
+       struct file * file;
+       struct linux_dirent64 __user * lastdirent;
+       struct compat_getdents_callback64 buf;
+       int error;
+
+       error = -EFAULT;
+       if (!access_ok(VERIFY_WRITE, dirent, count))
+               goto out;
+
+       error = -EBADF;
+       file = fget(fd);
+       if (!file)
+               goto out;
+
+       buf.current_dir = dirent;
+       buf.previous = NULL;
+       buf.count = count;
+       buf.error = 0;
+
+       error = vfs_readdir(file, compat_filldir64, &buf);
+       if (error < 0)
+               goto out_putf;
+       error = buf.error;
+       lastdirent = buf.previous;
+       if (lastdirent) {
+               typeof(lastdirent->d_off) d_off = file->f_pos;
+               __put_user(d_off, (u32 __user *)&lastdirent->d_off);
+               __put_user(d_off >> 32, ((u32 __user *)&lastdirent->d_off) + 1);
+               error = count - buf.count;
+       }
+
+out_putf:
+       fput(file);
+out:
+       return error;
+}
+#endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */
+
 static ssize_t compat_do_readv_writev(int type, struct file *file,
                               const struct compat_iovec __user *uvector,
                               unsigned long nr_segs, loff_t *pos)
index c14b9cd..fc3fb9f 100644 (file)
@@ -218,9 +218,14 @@ static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __u
 {
        u32 tmp;
 
-       if(get_user(tmp, &up->base))
+       if (get_user(tmp, &up->base))
                return -EFAULT;
-       kp->base = compat_ptr(tmp);
+
+       /* This is actually a physical address stored
+        * as a void pointer.
+        */
+       kp->base = (void *)(unsigned long) tmp;
+
        __get_user(kp->height, &up->height);
        __get_user(kp->width, &up->width);
        __get_user(kp->depth, &up->depth);
@@ -3107,7 +3112,8 @@ static int do_ncp_getmountuid2(unsigned int fd, unsigned int cmd, unsigned long
        set_fs(old_fs);
 
        if (!err)
-               err = put_user(kuid, (unsigned int *)compat_ptr(arg));
+               err = put_user(kuid,
+                              (unsigned int __user *) compat_ptr(arg));
 
        return err;
 }
@@ -3187,7 +3193,8 @@ static int do_ncp_setobjectname(unsigned int fd, unsigned int cmd, unsigned long
 static int do_ncp_getprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        struct ncp_privatedata_ioctl_32 n32, __user *p32 = compat_ptr(arg);
-       struct ncp_privatedata_ioctl *p = __user compat_alloc_user_space(sizeof(*p));
+       struct ncp_privatedata_ioctl __user *p =
+               compat_alloc_user_space(sizeof(*p));
        u32 len;
        int err;
 
@@ -3209,8 +3216,10 @@ static int do_ncp_getprivatedata(unsigned int fd, unsigned int cmd, unsigned lon
 
 static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct ncp_privatedata_ioctl_32 n32, *p32 = compat_ptr(arg);
-       struct ncp_privatedata_ioctl *p = compat_alloc_user_space(sizeof(*p));
+       struct ncp_privatedata_ioctl_32 n32;
+       struct ncp_privatedata_ioctl_32 __user *p32 = compat_ptr(arg);
+       struct ncp_privatedata_ioctl __user *p =
+               compat_alloc_user_space(sizeof(*p));
 
        if (copy_from_user(&n32, p32, sizeof(n32)) ||
            put_user(n32.len, &p->len) ||
index 20842c5..b0fb348 100644 (file)
@@ -848,13 +848,13 @@ static unsigned int boot_options = OPTION_NONE;
 static devfs_handle_t _devfs_walk_path(struct devfs_entry *dir,
                                       const char *name, int namelen,
                                       int traverse_symlink);
-static ssize_t devfsd_read(struct file *file, char *buf, size_t len,
+static ssize_t devfsd_read(struct file *file, char __user *buf, size_t len,
                           loff_t * ppos);
 static int devfsd_ioctl(struct inode *inode, struct file *file,
                        unsigned int cmd, unsigned long arg);
 static int devfsd_close(struct inode *inode, struct file *file);
 #ifdef CONFIG_DEVFS_DEBUG
-static ssize_t stat_read(struct file *file, char *buf, size_t len,
+static ssize_t stat_read(struct file *file, char __user *buf, size_t len,
                         loff_t * ppos);
 static struct file_operations stat_fops = {
        .read = stat_read,
@@ -2562,7 +2562,7 @@ static struct file_system_type devfs_fs_type = {
 
 /*  File operations for devfsd follow  */
 
-static ssize_t devfsd_read(struct file *file, char *buf, size_t len,
+static ssize_t devfsd_read(struct file *file, char __user *buf, size_t len,
                           loff_t * ppos)
 {
        int done = FALSE;
@@ -2676,7 +2676,7 @@ static int devfsd_ioctl(struct inode *inode, struct file *file,
        switch (cmd) {
        case DEVFSDIOC_GET_PROTO_REV:
                ival = DEVFSD_PROTOCOL_REVISION_KERNEL;
-               if (copy_to_user((void *)arg, &ival, sizeof ival))
+               if (copy_to_user((void __user *)arg, &ival, sizeof ival))
                        return -EFAULT;
                break;
        case DEVFSDIOC_SET_EVENT_MASK:
@@ -2715,7 +2715,7 @@ static int devfsd_ioctl(struct inode *inode, struct file *file,
                /*break; */
 #ifdef CONFIG_DEVFS_DEBUG
        case DEVFSDIOC_SET_DEBUG_MASK:
-               if (copy_from_user(&ival, (void *)arg, sizeof ival))
+               if (copy_from_user(&ival, (void __user *)arg, sizeof ival))
                        return -EFAULT;
                devfs_debug = ival;
                break;
@@ -2755,7 +2755,7 @@ static int devfsd_close(struct inode *inode, struct file *file)
 }                              /*  End Function devfsd_close  */
 
 #ifdef CONFIG_DEVFS_DEBUG
-static ssize_t stat_read(struct file *file, char *buf, size_t len,
+static ssize_t stat_read(struct file *file, char __user *buf, size_t len,
                         loff_t * ppos)
 {
        ssize_t num;
index a2910fb..92443ae 100644 (file)
@@ -1063,24 +1063,29 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
                        kfree(dio);
                }
        } else {
+               ssize_t transferred = 0;
+
                finished_one_bio(dio);
                ret2 = dio_await_completion(dio);
                if (ret == 0)
                        ret = ret2;
                if (ret == 0)
                        ret = dio->page_errors;
-               if (ret == 0 && dio->result) {
+               if (dio->result) {
                        loff_t i_size = i_size_read(inode);
 
-                       ret = dio->result;
+                       transferred = dio->result;
                        /*
                         * Adjust the return value if the read crossed a
                         * non-block-aligned EOF.
                         */
-                       if (rw == READ && (offset + ret > i_size))
-                               ret = i_size - offset;
+                       if (rw == READ && (offset + transferred > i_size))
+                               transferred = i_size - offset;
                }
-               dio_complete(dio, offset, ret);
+               dio_complete(dio, offset, transferred);
+               if (ret == 0)
+                       ret = transferred;
+
                /* We could have also come here on an AIO file extend */
                if (!is_sync_kiocb(iocb) && rw == WRITE &&
                    ret >= 0 && dio->result == dio->size)
index df42800..70280bc 100644 (file)
@@ -306,7 +306,7 @@ EXPORT_SYMBOL(mark_info_dirty);
 
 int dquot_acquire(struct dquot *dquot)
 {
-       int ret = 0;
+       int ret = 0, ret2 = 0;
        struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
 
        down(&dquot->dq_lock);
@@ -319,8 +319,15 @@ int dquot_acquire(struct dquot *dquot)
        /* Instantiate dquot if needed */
        if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) {
                ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
+               /* Write the info if needed */
+               if (info_dirty(&dqopt->info[dquot->dq_type]))
+                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
                if (ret < 0)
                        goto out_iolock;
+               if (ret2 < 0) {
+                       ret = ret2;
+                       goto out_iolock;
+               }
        }
        set_bit(DQ_ACTIVE_B, &dquot->dq_flags);
 out_iolock:
@@ -334,7 +341,7 @@ out_iolock:
  */
 int dquot_commit(struct dquot *dquot)
 {
-       int ret = 0;
+       int ret = 0, ret2 = 0;
        struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
 
        down(&dqopt->dqio_sem);
@@ -346,12 +353,15 @@ int dquot_commit(struct dquot *dquot)
        spin_unlock(&dq_list_lock);
        /* Inactive dquot can be only if there was error during read/init
         * => we have better not writing it */
-       if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
+       if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
                ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
+               if (info_dirty(&dqopt->info[dquot->dq_type]))
+                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
+               if (ret >= 0)
+                       ret = ret2;
+       }
 out_sem:
        up(&dqopt->dqio_sem);
-       if (info_dirty(&dqopt->info[dquot->dq_type]))
-               dquot->dq_sb->dq_op->write_info(dquot->dq_sb, dquot->dq_type);
        return ret;
 }
 
@@ -360,7 +370,7 @@ out_sem:
  */
 int dquot_release(struct dquot *dquot)
 {
-       int ret = 0;
+       int ret = 0, ret2 = 0;
        struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
 
        down(&dquot->dq_lock);
@@ -368,8 +378,14 @@ int dquot_release(struct dquot *dquot)
        if (atomic_read(&dquot->dq_count) > 1)
                goto out_dqlock;
        down(&dqopt->dqio_sem);
-       if (dqopt->ops[dquot->dq_type]->release_dqblk)
+       if (dqopt->ops[dquot->dq_type]->release_dqblk) {
                ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot);
+               /* Write the info */
+               if (info_dirty(&dqopt->info[dquot->dq_type]))
+                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
+               if (ret >= 0)
+                       ret = ret2;
+       }
        clear_bit(DQ_ACTIVE_B, &dquot->dq_flags);
        up(&dqopt->dqio_sem);
 out_dqlock:
index 1c80839..86464ea 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/spinlock.h>
 #include <linux/syscalls.h>
 #include <linux/rwsem.h>
+#include <linux/rbtree.h>
 #include <linux/wait.h>
 #include <linux/eventpoll.h>
 #include <linux/mount.h>
 /* Maximum number of poll wake up nests we are allowing */
 #define EP_MAX_POLLWAKE_NESTS 4
 
-/* Maximum size of the hash in bits ( 2^N ) */
-#define EP_MAX_HASH_BITS 17
-
-/* Minimum size of the hash in bits ( 2^N ) */
-#define EP_MIN_HASH_BITS 9
-
-/* Number of hash entries ( "struct list_head" ) inside a page */
-#define EP_HENTRY_X_PAGE (PAGE_SIZE / sizeof(struct list_head))
-
-/* Maximum size of the hash in pages */
-#define EP_MAX_HPAGES ((1 << EP_MAX_HASH_BITS) / EP_HENTRY_X_PAGE + 1)
-
-/* Number of pages allocated for an "hbits" sized hash table */
-#define EP_HASH_PAGES(hbits) ((int) ((1 << (hbits)) / EP_HENTRY_X_PAGE + \
-                                    ((1 << (hbits)) % EP_HENTRY_X_PAGE ? 1: 0)))
-
 /* Macro to allocate a "struct epitem" from the slab cache */
 #define EPI_MEM_ALLOC()        (struct epitem *) kmem_cache_alloc(epi_cache, SLAB_KERNEL)
 
 /* Fast test to see if the file is an evenpoll file */
 #define IS_FILE_EPOLL(f) ((f)->f_op == &eventpoll_fops)
 
+/* Setup the structure that is used as key for the rb-tree */
+#define EP_SET_FFD(p, f, d) do { (p)->file = (f); (p)->fd = (d); } while (0)
+
+/* Compare rb-tree keys */
+#define EP_CMP_FFD(p1, p2) ((p1)->file > (p2)->file ? +1: \
+                           ((p1)->file < (p2)->file ? -1: (p1)->fd - (p2)->fd))
+
+/* Special initialization for the rb-tree node to detect linkage */
+#define EP_RB_INITNODE(n) (n)->rb_parent = (n)
+
+/* Removes a node from the rb-tree and marks it for a fast is-linked check */
+#define EP_RB_ERASE(n, r) do { rb_erase(n, r); (n)->rb_parent = (n); } while (0)
+
+/* Fast check to verify that the item is linked to the main rb-tree */
+#define EP_RB_LINKED(n) ((n)->rb_parent != (n))
+
 /*
  * Remove the item from the list and perform its initialization.
  * This is useful for us because we can test if the item is linked
 /* Get the "struct epitem" from an epoll queue wrapper */
 #define EP_ITEM_FROM_EPQUEUE(p) (container_of(p, struct ep_pqueue, pt)->epi)
 
+
+struct epoll_filefd {
+       struct file *file;
+       int fd;
+};
+
 /*
  * Node that is linked into the "wake_task_list" member of the "struct poll_safewake".
  * It is used to keep track on all tasks that are currently inside the wake_up() code
@@ -195,11 +202,8 @@ struct eventpoll {
        /* List of ready file descriptors */
        struct list_head rdllist;
 
-       /* Size of the hash */
-       unsigned int hashbits;
-
-       /* Pages for the "struct epitem" hash */
-       char *hpages[EP_MAX_HPAGES];
+       /* RB-Tree root used to store monitored fd structs */
+       struct rb_root rbr;
 };
 
 /* Wait structure used by the poll hooks */
@@ -225,14 +229,14 @@ struct eppoll_entry {
  * have an entry of this type linked to the hash.
  */
 struct epitem {
-       /* List header used to link this structure to the eventpoll hash */
-       struct list_head llink;
+       /* RB-Tree node used to link this structure to the eventpoll rb-tree */
+       struct rb_node rbn;
 
        /* List header used to link this structure to the eventpoll ready list */
        struct list_head rdllink;
 
-       /* The file descriptor this item refers to */
-       int fd;
+       /* The file descriptor information this item refers to */
+       struct epoll_filefd ffd;
 
        /* Number of active wait queue attached to poll operations */
        int nwait;
@@ -243,9 +247,6 @@ struct epitem {
        /* The "container" of this item */
        struct eventpoll *ep;
 
-       /* The file this item refers to */
-       struct file *file;
-
        /* The structure that describe the interested events and the source fd */
        struct epoll_event event;
 
@@ -278,22 +279,15 @@ struct ep_pqueue {
 
 static void ep_poll_safewake_init(struct poll_safewake *psw);
 static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
-static unsigned int ep_get_hash_bits(unsigned int hintsize);
 static int ep_getfd(int *efd, struct inode **einode, struct file **efile);
-static int ep_alloc_pages(char **pages, int numpages);
-static int ep_free_pages(char **pages, int numpages);
-static int ep_file_init(struct file *file, unsigned int hashbits);
-static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file,
-                                 int fd);
-static struct list_head *ep_hash_entry(struct eventpoll *ep,
-                                      unsigned int index);
-static int ep_init(struct eventpoll *ep, unsigned int hashbits);
+static int ep_file_init(struct file *file);
 static void ep_free(struct eventpoll *ep);
 static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
 static void ep_use_epitem(struct epitem *epi);
 static void ep_release_epitem(struct epitem *epi);
 static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
                                 poll_table *pt);
+static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi);
 static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
                     struct file *tfile, int fd);
 static int ep_modify(struct eventpoll *ep, struct epitem *epi,
@@ -424,19 +418,6 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
 }
 
 
-/*
- * Calculate the size of the hash in bits. The returned size will be
- * bounded between EP_MIN_HASH_BITS and EP_MAX_HASH_BITS.
- */
-static unsigned int ep_get_hash_bits(unsigned int hintsize)
-{
-       unsigned int i, val;
-
-       for (i = 0, val = 1; val < hintsize && i < EP_MAX_HASH_BITS; i++, val <<= 1);
-       return i <  EP_MIN_HASH_BITS ?  EP_MIN_HASH_BITS: i;
-}
-
-
 /* Used to initialize the epoll bits inside the "struct file" */
 void eventpoll_init_file(struct file *file)
 {
@@ -492,15 +473,16 @@ void eventpoll_release_file(struct file *file)
 asmlinkage long sys_epoll_create(int size)
 {
        int error, fd;
-       unsigned int hashbits;
        struct inode *inode;
        struct file *file;
 
        DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n",
                     current, size));
 
-       /* Correctly size the hash */
-       hashbits = ep_get_hash_bits((unsigned int) size);
+       /* Sanity check on the size parameter */
+       error = -EINVAL;
+       if (size <= 0)
+               goto eexit_1;
 
        /*
         * Creates all the items needed to setup an eventpoll file. That is,
@@ -511,7 +493,7 @@ asmlinkage long sys_epoll_create(int size)
                goto eexit_1;
 
        /* Setup the file internal data structure ( "struct eventpoll" ) */
-       error = ep_file_init(file, hashbits);
+       error = ep_file_init(file);
        if (error)
                goto eexit_2;
 
@@ -763,114 +745,32 @@ eexit_1:
 }
 
 
-static int ep_alloc_pages(char **pages, int numpages)
+static int ep_file_init(struct file *file)
 {
-       int i;
-
-       for (i = 0; i < numpages; i++) {
-               pages[i] = (char *) __get_free_pages(GFP_KERNEL, 0);
-               if (!pages[i]) {
-                       for (--i; i >= 0; i--) {
-                               ClearPageReserved(virt_to_page(pages[i]));
-                               free_pages((unsigned long) pages[i], 0);
-                       }
-                       return -ENOMEM;
-               }
-               SetPageReserved(virt_to_page(pages[i]));
-       }
-       return 0;
-}
-
-
-static int ep_free_pages(char **pages, int numpages)
-{
-       int i;
-
-       for (i = 0; i < numpages; i++) {
-               ClearPageReserved(virt_to_page(pages[i]));
-               free_pages((unsigned long) pages[i], 0);
-       }
-       return 0;
-}
-
-
-static int ep_file_init(struct file *file, unsigned int hashbits)
-{
-       int error;
        struct eventpoll *ep;
 
        if (!(ep = kmalloc(sizeof(struct eventpoll), GFP_KERNEL)))
                return -ENOMEM;
 
        memset(ep, 0, sizeof(*ep));
-
-       error = ep_init(ep, hashbits);
-       if (error) {
-               kfree(ep);
-               return error;
-       }
-
-       file->private_data = ep;
-
-       DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_file_init() ep=%p\n",
-                    current, ep));
-       return 0;
-}
-
-
-/*
- * Calculate the index of the hash relative to "file".
- */
-static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file, int fd)
-{
-       unsigned long ptr = (unsigned long) file ^ (fd << ep->hashbits);
-
-       return (unsigned int) hash_ptr((void *) ptr, ep->hashbits);
-}
-
-
-/*
- * Returns the hash entry ( struct list_head * ) of the passed index.
- */
-static struct list_head *ep_hash_entry(struct eventpoll *ep, unsigned int index)
-{
-
-       return (struct list_head *) (ep->hpages[index / EP_HENTRY_X_PAGE] +
-                                    (index % EP_HENTRY_X_PAGE) * sizeof(struct list_head));
-}
-
-
-static int ep_init(struct eventpoll *ep, unsigned int hashbits)
-{
-       int error;
-       unsigned int i, hsize;
-
        rwlock_init(&ep->lock);
        init_rwsem(&ep->sem);
        init_waitqueue_head(&ep->wq);
        init_waitqueue_head(&ep->poll_wait);
        INIT_LIST_HEAD(&ep->rdllist);
+       ep->rbr = RB_ROOT;
 
-       /* Hash allocation and setup */
-       ep->hashbits = hashbits;
-       error = ep_alloc_pages(ep->hpages, EP_HASH_PAGES(ep->hashbits));
-       if (error)
-               goto eexit_1;
-
-       /* Initialize hash buckets */
-       for (i = 0, hsize = 1 << hashbits; i < hsize; i++)
-               INIT_LIST_HEAD(ep_hash_entry(ep, i));
+       file->private_data = ep;
 
+       DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_file_init() ep=%p\n",
+                    current, ep));
        return 0;
-eexit_1:
-       return error;
 }
 
 
 static void ep_free(struct eventpoll *ep)
 {
-       unsigned int i, hsize;
-       struct list_head *lsthead, *lnk;
+       struct rb_node *rbp;
        struct epitem *epi;
 
        /* We need to release all tasks waiting for these file */
@@ -888,16 +788,12 @@ static void ep_free(struct eventpoll *ep)
        down(&epsem);
 
        /*
-        * Walks through the whole hash by unregistering poll callbacks.
+        * Walks through the whole tree by unregistering poll callbacks.
         */
-       for (i = 0, hsize = 1 << ep->hashbits; i < hsize; i++) {
-               lsthead = ep_hash_entry(ep, i);
+       for (rbp = rb_first(&ep->rbr); rbp; rbp = rb_next(rbp)) {
+               epi = rb_entry(rbp, struct epitem, rbn);
 
-               list_for_each(lnk, lsthead) {
-                       epi = list_entry(lnk, struct epitem, llink);
-
-                       ep_unregister_pollwait(ep, epi);
-               }
+               ep_unregister_pollwait(ep, epi);
        }
 
        /*
@@ -906,20 +802,12 @@ static void ep_free(struct eventpoll *ep)
         * write-holding "sem" we can be sure that no file cleanup code will hit
         * us during this operation. So we can avoid the lock on "ep->lock".
         */
-       for (i = 0, hsize = 1 << ep->hashbits; i < hsize; i++) {
-               lsthead = ep_hash_entry(ep, i);
-
-               while (!list_empty(lsthead)) {
-                       epi = list_entry(lsthead->next, struct epitem, llink);
-
-                       ep_remove(ep, epi);
-               }
+       while ((rbp = rb_first(&ep->rbr))) {
+               epi = rb_entry(rbp, struct epitem, rbn);
+               ep_remove(ep, epi);
        }
 
        up(&epsem);
-
-       /* Free hash pages */
-       ep_free_pages(ep->hpages, EP_HASH_PAGES(ep->hashbits));
 }
 
 
@@ -930,29 +818,33 @@ static void ep_free(struct eventpoll *ep)
  */
 static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd)
 {
+       int kcmp;
        unsigned long flags;
-       struct list_head *lsthead, *lnk;
-       struct epitem *epi = NULL;
+       struct rb_node *rbp;
+       struct epitem *epi, *epir = NULL;
+       struct epoll_filefd ffd;
 
+       EP_SET_FFD(&ffd, file, fd);
        read_lock_irqsave(&ep->lock, flags);
-
-       lsthead = ep_hash_entry(ep, ep_hash_index(ep, file, fd));
-       list_for_each(lnk, lsthead) {
-               epi = list_entry(lnk, struct epitem, llink);
-
-               if (epi->file == file && epi->fd == fd) {
+       for (rbp = ep->rbr.rb_node; rbp; ) {
+               epi = rb_entry(rbp, struct epitem, rbn);
+               kcmp = EP_CMP_FFD(&ffd, &epi->ffd);
+               if (kcmp > 0)
+                       rbp = rbp->rb_right;
+               else if (kcmp < 0)
+                       rbp = rbp->rb_left;
+               else {
                        ep_use_epitem(epi);
+                       epir = epi;
                        break;
                }
-               epi = NULL;
        }
-
        read_unlock_irqrestore(&ep->lock, flags);
 
        DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_find(%p) -> %p\n",
-                    current, file, epi));
+                    current, file, epir));
 
-       return epi;
+       return epir;
 }
 
 
@@ -1004,6 +896,26 @@ static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
 }
 
 
+static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi)
+{
+       int kcmp;
+       struct rb_node **p = &ep->rbr.rb_node, *parent = NULL;
+       struct epitem *epic;
+
+       while (*p) {
+               parent = *p;
+               epic = rb_entry(parent, struct epitem, rbn);
+               kcmp = EP_CMP_FFD(&epi->ffd, &epic->ffd);
+               if (kcmp > 0)
+                       p = &parent->rb_right;
+               else
+                       p = &parent->rb_left;
+       }
+       rb_link_node(&epi->rbn, parent, p);
+       rb_insert_color(&epi->rbn, &ep->rbr);
+}
+
+
 static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
                     struct file *tfile, int fd)
 {
@@ -1017,14 +929,13 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
                goto eexit_1;
 
        /* Item initialization follow here ... */
-       INIT_LIST_HEAD(&epi->llink);
+       EP_RB_INITNODE(&epi->rbn);
        INIT_LIST_HEAD(&epi->rdllink);
        INIT_LIST_HEAD(&epi->fllink);
        INIT_LIST_HEAD(&epi->txlink);
        INIT_LIST_HEAD(&epi->pwqlist);
        epi->ep = ep;
-       epi->file = tfile;
-       epi->fd = fd;
+       EP_SET_FFD(&epi->ffd, tfile, fd);
        epi->event = *event;
        atomic_set(&epi->usecnt, 1);
        epi->nwait = 0;
@@ -1056,8 +967,8 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
        /* We have to drop the new item inside our item list to keep track of it */
        write_lock_irqsave(&ep->lock, flags);
 
-       /* Add the current item to the hash table */
-       list_add(&epi->llink, ep_hash_entry(ep, ep_hash_index(ep, tfile, fd)));
+       /* Add the current item to the rb-tree */
+       ep_rbtree_insert(ep, epi);
 
        /* If the file is already "ready" we drop it inside the ready list */
        if ((revents & event->events) && !EP_IS_LINKED(&epi->rdllink)) {
@@ -1121,7 +1032,7 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even
         * Get current event bits. We can safely use the file* here because
         * its usage count has been increased by the caller of this function.
         */
-       revents = epi->file->f_op->poll(epi->file, NULL);
+       revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL);
 
        write_lock_irqsave(&ep->lock, flags);
 
@@ -1132,7 +1043,7 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even
         * If the item is not linked to the hash it means that it's on its
         * way toward the removal. Do nothing in this case.
         */
-       if (EP_IS_LINKED(&epi->llink)) {
+       if (EP_RB_LINKED(&epi->rbn)) {
                /*
                 * If the item is "hot" and it is not registered inside the ready
                 * list, push it inside. If the item is not "hot" and it is currently
@@ -1200,7 +1111,7 @@ static int ep_unlink(struct eventpoll *ep, struct epitem *epi)
         * The check protect us from doing a double unlink ( crash ).
         */
        error = -ENOENT;
-       if (!EP_IS_LINKED(&epi->llink))
+       if (!EP_RB_LINKED(&epi->rbn))
                goto eexit_1;
 
        /*
@@ -1211,11 +1122,11 @@ static int ep_unlink(struct eventpoll *ep, struct epitem *epi)
        epi->event.events = 0;
 
        /*
-        * At this point is safe to do the job, unlink the item from our list.
+        * At this point is safe to do the job, unlink the item from our rb-tree.
         * This operation togheter with the above check closes the door to
         * double unlinks.
         */
-       EP_LIST_DEL(&epi->llink);
+       EP_RB_ERASE(&epi->rbn, &ep->rbr);
 
        /*
         * If the item we are going to remove is inside the ready file descriptors
@@ -1242,7 +1153,7 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
 {
        int error;
        unsigned long flags;
-       struct file *file = epi->file;
+       struct file *file = epi->ffd.file;
 
        /*
         * Removes poll wait queue hooks. We _have_ to do this without holding
@@ -1441,7 +1352,7 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
                 * because we are holding the "sem" in read and this will
                 * guarantee that both the file and the item will not vanish.
                 */
-               revents = epi->file->f_op->poll(epi->file, NULL);
+               revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL);
 
                /*
                 * Set the return event set for the current file descriptor.
@@ -1492,7 +1403,7 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
                 * item is set to have an Edge Triggered behaviour, we don't have
                 * to push it back either.
                 */
-               if (EP_IS_LINKED(&epi->llink) && !(epi->event.events & EPOLLET) &&
+               if (EP_RB_LINKED(&epi->rbn) && !(epi->event.events & EPOLLET) &&
                    (epi->revents & epi->event.events) && !EP_IS_LINKED(&epi->rdllink)) {
                        list_add_tail(&epi->rdllink, &ep->rdllist);
                        ricnt++;
index 3ba35b6..2b14054 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -48,7 +48,6 @@
 #include <linux/rmap.h>
 
 #include <asm/uaccess.h>
-#include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
 
 #ifdef CONFIG_KMOD
@@ -845,7 +844,8 @@ int flush_old_exec(struct linux_binprm * bprm)
        flush_thread();
 
        if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 
-           permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL))
+           permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) ||
+           (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP))
                current->mm->dumpable = 0;
 
        /* An exec changes our domain. We are no longer part of the thread
@@ -1090,20 +1090,21 @@ int do_execve(char * filename,
        int retval;
        int i;
 
-       sched_balance_exec();
-
        file = open_exec(filename);
 
        retval = PTR_ERR(file);
        if (IS_ERR(file))
                return retval;
 
+       sched_balance_exec();
+
        bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
        memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
 
        bprm.file = file;
        bprm.filename = filename;
        bprm.interp = filename;
+       bprm.interp_flags = 0;
        bprm.sh_bang = 0;
        bprm.loader = 0;
        bprm.exec = 0;
index 704cd44..92deb0d 100644 (file)
@@ -5,7 +5,7 @@
 obj-$(CONFIG_EXT3_FS) += ext3.o
 
 ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
-          ioctl.o namei.o super.o symlink.o hash.o resize.o
+          ioctl.o namei.o super.o symlink.o hash.o
 
 ext3-$(CONFIG_EXT3_FS_XATTR)    += xattr.o xattr_user.o xattr_trusted.o
 ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
index 75369a9..4ebdcf4 100644 (file)
@@ -96,87 +96,9 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group)
 error_out:
        return bh;
 }
-/*
- * The reservation window structure operations
- * --------------------------------------------
- * Operations include:
- * dump, find, add, remove, is_empty, find_next_reservable_window, etc.
- *
- * We use sorted double linked list for the per-filesystem reservation
- * window list. (like in vm_region).
- *
- * Initially, we keep those small operations in the abstract functions,
- * so later if we need a better searching tree than double linked-list,
- * we could easily switch to that without changing too much
- * code.
- */
-static inline void rsv_window_dump(struct reserve_window *head, char *fn)
-{
-       struct reserve_window *rsv;
-
-       printk("Block Allocation Reservation Windows Map (%s):\n", fn);
-       list_for_each_entry(rsv, &head->rsv_list, rsv_list) {
-               printk("reservation window 0x%p start:  %d, end:  %d\n",
-                        rsv, rsv->rsv_start, rsv->rsv_end);
-       }
-}
-
-static int
-goal_in_my_reservation(struct reserve_window *rsv, int goal,
-                       unsigned int group, struct super_block * sb)
-{
-       unsigned long group_first_block, group_last_block;
-
-       group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
-                               group * EXT3_BLOCKS_PER_GROUP(sb);
-       group_last_block = group_first_block + EXT3_BLOCKS_PER_GROUP(sb) - 1;
-
-       if ((rsv->rsv_start > group_last_block) ||
-           (rsv->rsv_end < group_first_block))
-               return 0;
-       if ((goal >= 0) && ((goal + group_first_block < rsv->rsv_start)
-               || (goal + group_first_block > rsv->rsv_end)))
-               return 0;
-       return 1;
-}
-
-static inline void rsv_window_add(struct reserve_window *rsv,
-                                       struct reserve_window *prev)
-{
-       /* insert the new reservation window after the head */
-       list_add(&rsv->rsv_list, &prev->rsv_list);
-}
-
-static inline void rsv_window_remove(struct reserve_window *rsv)
-{
-       rsv->rsv_start = 0;
-       rsv->rsv_end = 0;
-               rsv->rsv_alloc_hit = 0;
-       list_del(&rsv->rsv_list);
-       INIT_LIST_HEAD(&rsv->rsv_list);
-}
-
-static inline int rsv_is_empty(struct reserve_window *rsv)
-{
-       /* a valid reservation end block could not be 0 */
-       return (rsv->rsv_end == 0);
-}
-
-void ext3_discard_reservation(struct inode *inode)
-{
-       struct ext3_inode_info *ei = EXT3_I(inode);
-       struct reserve_window *rsv = &ei->i_rsv_window;
-       spinlock_t *rsv_lock = &EXT3_SB(inode->i_sb)->s_rsv_window_lock;
-
-       if (!rsv_is_empty(rsv)) {
-               spin_lock(rsv_lock);
-               rsv_window_remove(rsv);
-               spin_unlock(rsv_lock);
-       }
-}
 
 /* Free given blocks, update quota and i_blocks field */
-void ext3_free_blocks(handle_t *handle, struct inode *inode,
+void ext3_free_blocks (handle_t *handle, struct inode * inode,
                        unsigned long block, unsigned long count)
 {
        struct buffer_head *bitmap_bh = NULL;
@@ -353,7 +275,7 @@ do_more:
 error_return:
        brelse(bitmap_bh);
        ext3_std_error(sb, err);
-       if (dquot_freed_blocks && !(EXT3_I(inode)->i_state & EXT3_STATE_RESIZE))
+       if (dquot_freed_blocks)
                DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
        return;
 }
@@ -374,7 +296,7 @@ error_return:
  * data-writes at some point, and disable it for metadata allocations or
  * sync-data inodes.
  */
-static int ext3_test_allocatable(int nr, struct buffer_head *bh)
+static inline int ext3_test_allocatable(int nr, struct buffer_head *bh)
 {
        int ret;
        struct journal_head *jh = bh2jh(bh);
@@ -391,33 +313,6 @@ static int ext3_test_allocatable(int nr, struct buffer_head *bh)
        return ret;
 }
 
-static int
-bitmap_search_next_usable_block(int start, struct buffer_head *bh,
-                                       int maxblocks)
-{
-       int next;
-       struct journal_head *jh = bh2jh(bh);
-
-       /*
-        * The bitmap search --- search forward alternately through the actual
-        * bitmap and the last-committed copy until we find a bit free in
-        * both
-        */
-       while (start < maxblocks) {
-               next = ext3_find_next_zero_bit(bh->b_data, maxblocks, start);
-               if (next >= maxblocks)
-                       return -1;
-               if (ext3_test_allocatable(next, bh))
-                       return next;
-               jbd_lock_bh_state(bh);
-               if (jh->b_committed_data)
-                       start = ext3_find_next_zero_bit(jh->b_committed_data,
-                                                       maxblocks, next);
-               jbd_unlock_bh_state(bh);
-       }
-       return -1;
-}
-
 /*
  * Find an allocatable block in a bitmap.  We honour both the bitmap and
  * its last-committed copy (if that exists), and perform the "most
@@ -430,6 +325,7 @@ find_next_usable_block(int start, struct buffer_head *bh, int maxblocks)
 {
        int here, next;
        char *p, *r;
+       struct journal_head *jh = bh2jh(bh);
 
        if (start > 0) {
                /*
@@ -441,8 +337,6 @@ find_next_usable_block(int start, struct buffer_head *bh, int maxblocks)
                 * next 64-bit boundary is simple..
                 */
                int end_goal = (start + 63) & ~63;
-               if (end_goal > maxblocks)
-                       end_goal = maxblocks;
                here = ext3_find_next_zero_bit(bh->b_data, end_goal, start);
                if (here < end_goal && ext3_test_allocatable(here, bh))
                        return here;
@@ -457,7 +351,7 @@ find_next_usable_block(int start, struct buffer_head *bh, int maxblocks)
        r = memscan(p, 0, (maxblocks - here + 7) >> 3);
        next = (r - ((char *)bh->b_data)) << 3;
 
-       if (next < maxblocks && next >= start && ext3_test_allocatable(next, bh))
+       if (next < maxblocks && ext3_test_allocatable(next, bh))
                return next;
 
        /*
@@ -465,8 +359,19 @@ find_next_usable_block(int start, struct buffer_head *bh, int maxblocks)
         * bitmap and the last-committed copy until we find a bit free in
         * both
         */
-       here = bitmap_search_next_usable_block(here, bh, maxblocks);
-       return here;
+       while (here < maxblocks) {
+               next = ext3_find_next_zero_bit(bh->b_data, maxblocks, here);
+               if (next >= maxblocks)
+                       return -1;
+               if (ext3_test_allocatable(next, bh))
+                       return next;
+               jbd_lock_bh_state(bh);
+               if (jh->b_committed_data)
+                       here = ext3_find_next_zero_bit(jh->b_committed_data,
+                                                       maxblocks, next);
+               jbd_unlock_bh_state(bh);
+       }
+       return -1;
 }
 
 /*
@@ -502,464 +407,62 @@ claim_block(spinlock_t *lock, int block, struct buffer_head *bh)
  */
 static int
 ext3_try_to_allocate(struct super_block *sb, handle_t *handle, int group,
-       struct buffer_head *bitmap_bh, int goal, struct reserve_window *my_rsv)
+               struct buffer_head *bitmap_bh, int goal, int *errp)
 {
-       int group_first_block, start, end;
-
-       /* we do allocation within the reservation window if we have a window */
-       if (my_rsv) {
-               group_first_block =
-                       le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
-                       group * EXT3_BLOCKS_PER_GROUP(sb);
-               if (my_rsv->rsv_start >= group_first_block)
-                       start = my_rsv->rsv_start - group_first_block;
-               else
-                       /* reservation window cross group boundary */
-                       start = 0;
-               end = my_rsv->rsv_end - group_first_block + 1;
-               if (end > EXT3_BLOCKS_PER_GROUP(sb))
-                       /* reservation window crosses group boundary */
-                       end = EXT3_BLOCKS_PER_GROUP(sb);
-               if ((start <= goal) && (goal < end))
-                       start = goal;
-               else
-                       goal = -1;
-       } else {
-               if (goal > 0)
-                       start = goal;
-               else
-                       start = 0;
-               end = EXT3_BLOCKS_PER_GROUP(sb);
-       }
+       int i;
+       int fatal;
+       int credits = 0;
 
-       BUG_ON(start > EXT3_BLOCKS_PER_GROUP(sb));
+       *errp = 0;
+
+       /*
+        * Make sure we use undo access for the bitmap, because it is critical
+        * that we do the frozen_data COW on bitmap buffers in all cases even
+        * if the buffer is in BJ_Forget state in the committing transaction.
+        */
+       BUFFER_TRACE(bitmap_bh, "get undo access for new block");
+       fatal = ext3_journal_get_undo_access(handle, bitmap_bh, &credits);
+       if (fatal) {
+               *errp = fatal;
+               goto fail;
+       }
 
 repeat:
        if (goal < 0 || !ext3_test_allocatable(goal, bitmap_bh)) {
-               goal = find_next_usable_block(start, bitmap_bh, end);
+               goal = find_next_usable_block(goal, bitmap_bh,
+                                       EXT3_BLOCKS_PER_GROUP(sb));
                if (goal < 0)
                        goto fail_access;
-               if (!my_rsv) {
-                       int i;
-
-                       for (i = 0; i < 7 && goal > start &&
-                                       ext3_test_allocatable(goal - 1,
-                                                               bitmap_bh);
-                                       i++, goal--)
-                               ;
-               }
+
+               for (i = 0; i < 7 && goal > 0 &&
+                               ext3_test_allocatable(goal - 1, bitmap_bh);
+                       i++, goal--);
        }
-       start = goal;
 
        if (!claim_block(sb_bgl_lock(EXT3_SB(sb), group), goal, bitmap_bh)) {
                /*
                 * The block was allocated by another thread, or it was
                 * allocated and then freed by another thread
                 */
-               start++;
                goal++;
-               if (start >= end)
+               if (goal >= EXT3_BLOCKS_PER_GROUP(sb))
                        goto fail_access;
                goto repeat;
        }
-       if (my_rsv)
-               my_rsv->rsv_alloc_hit++;
-       return goal;
-fail_access:
-       return -1;
-}
 
-/**
- *     find_next_reservable_window():
- *             find a reservable space within the given range
- *             It does not allocate the reservation window for now
- *             alloc_new_reservation() will do the work later.
- *
- *     @search_head: the head of the searching list;
- *             This is not necessary the list head of the whole filesystem
- *
- *             we have both head and start_block to assist the search
- *             for the reservable space. The list start from head,
- *             but we will shift to the place where start_block is,
- *             then start from there, we looking for a resevable space.
- *
- *     @fs_rsv_head: per-filesystem reervation list head.
- *
- *     @size: the target new reservation window size
- *     @group_first_block: the first block we consider to start
- *                     the real search from
- *
- *     @last_block:
- *             the maxium block number that our goal reservable space
- *             could start from. This is normally the last block in this
- *             group. The search will end when we found the start of next
- *             possiblereservable space is out of this boundary.
- *             This could handle the cross bounday reservation window request.
- *
- *     basically we search from the given range, rather than the whole
- *     reservation double linked list, (start_block, last_block)
- *     to find a free region that of of my size and has not
- *     been reserved.
- *
- *     on succeed, it returns the reservation window to be append to.
- *     failed, return NULL.
- */
-static inline
-struct reserve_window *find_next_reservable_window(
-                               struct reserve_window *search_head,
-                               struct reserve_window *fs_rsv_head,
-                               unsigned long size, int *start_block,
-                               int last_block)
-{
-       struct reserve_window *rsv;
-       int cur;
-
-       /* TODO:make the start of the reservation window byte alligned */
-       /*cur = *start_block & 8;*/
-       cur = *start_block;
-       rsv = list_entry(search_head->rsv_list.next,
-                               struct reserve_window, rsv_list);
-       while (rsv != fs_rsv_head) {
-               if (cur + size <= rsv->rsv_start) {
-                       /*
-                        * Found a reserveable space big enough.  We could
-                        * have a reservation across the group boundary here
-                        */
-                       break;
-               }
-               if (cur <= rsv->rsv_end)
-                       cur = rsv->rsv_end + 1;
-
-               /* TODO?
-                * in the case we could not find a reservable space
-                * that is what is expected, during the re-search, we could
-                * remember what's the largest reservable space we could have
-                * and return that one.
-                *
-                * For now it will fail if we could not find the reservable
-                * space with expected-size (or more)...
-                */
-               rsv = list_entry(rsv->rsv_list.next,
-                               struct reserve_window, rsv_list);
-               if (cur > last_block)
-                       return NULL;            /* fail */
-       }
-       /*
-        * we come here either :
-        * when we rearch to the end of the whole list,
-        * and there is empty reservable space after last entry in the list.
-        * append it to the end of the list.
-        *
-        * or we found one reservable space in the middle of the list,
-        * return the reservation window that we could append to.
-        * succeed.
-        */
-       *start_block = cur;
-       return list_entry(rsv->rsv_list.prev, struct reserve_window, rsv_list);
-}
-
-/**
- *     alloc_new_reservation()--allocate a new reservation window
- *             if there is an existing reservation, discard it first
- *             then allocate the new one from there
- *             otherwise allocate the new reservation from the given
- *             start block, or the beginning of the group, if a goal
- *             is not given.
- *
- *             To make a new reservation, we search part of the filesystem
- *             reservation list(the list that inside the group).
- *
- *             If we have a old reservation, the search goal is the end of
- *             last reservation. If we do not have a old reservatio, then we
- *             start from a given goal, or the first block of the group, if
- *             the goal is not given.
- *
- *             We first find a reservable space after the goal, then from
- *             there,we check the bitmap for the first free block after
- *             it. If there is no free block until the end of group, then the
- *             whole group is full, we failed. Otherwise, check if the free
- *             block is inside the expected reservable space, if so, we
- *             succeed.
- *             If the first free block is outside the reseravle space, then
- *             start from the first free block, we search for next avalibale
- *             space, and go on.
- *
- *     on succeed, a new reservation will be found and inserted into the list
- *     It contains at least one free block, and it is not overlap with other
- *     reservation window.
- *
- *     failed: we failed to found a reservation window in this group
- *
- *     @rsv: the reservation
- *
- *     @goal: The goal.  It is where the search for a
- *             free reservable space should start from.
- *             if we have a old reservation, start_block is the end of
- *             old reservation. Otherwise,
- *             if we have a goal(goal >0 ), then start from there,
- *             no goal(goal = -1), we start from the first block
- *             of the group.
- *
- *     @sb: the super block
- *     @group: the group we are trying to do allocate in
- *     @bitmap_bh: the block group block bitmap
- */
-static int alloc_new_reservation(struct reserve_window *my_rsv,
-               int goal, struct super_block *sb,
-               unsigned int group, struct buffer_head *bitmap_bh)
-{
-       struct reserve_window *search_head;
-       int group_first_block, group_end_block, start_block;
-       int first_free_block;
-       int reservable_space_start;
-       struct reserve_window *prev_rsv;
-       struct reserve_window *fs_rsv_head = &EXT3_SB(sb)->s_rsv_window_head;
-       unsigned long size;
-
-       group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
-                               group * EXT3_BLOCKS_PER_GROUP(sb);
-       group_end_block = group_first_block + EXT3_BLOCKS_PER_GROUP(sb) - 1;
-
-       if (goal < 0)
-               start_block = group_first_block;
-       else
-               start_block = goal + group_first_block;
-
-       size = atomic_read(&my_rsv->rsv_goal_size);
-       /* if we have a old reservation, start the search from the old rsv */
-       if (!rsv_is_empty(my_rsv)) {
-               /*
-                * if the old reservation is cross group boundary
-                * we will come here when we just failed to allocate from
-                * the first part of the window. We still have another part
-                * that belongs to the next group. In this case, there is no
-                * point to discard our window and try to allocate a new one
-                * in this group(which will fail). we should
-                * keep the reservation window, just simply move on.
-                *
-                * Maybe we could shift the start block of the reservation
-                * window to the first block of next group.
-                */
-
-               if ((my_rsv->rsv_start <= group_end_block) &&
-                               (my_rsv->rsv_end > group_end_block))
-                       return -1;
-
-               /* remember where we are before we discard the old one */
-               if (my_rsv->rsv_end + 1 > start_block)
-                       start_block = my_rsv->rsv_end + 1;
-               search_head = my_rsv;
-               if ((my_rsv->rsv_alloc_hit > (my_rsv->rsv_end - my_rsv->rsv_start + 1) / 2)) {
-                       /*
-                        * if we previously allocation hit ration is greater than half
-                        * we double the size of reservation window next time
-                        * otherwise keep the same
-                        */
-                       size = size * 2;
-                       if (size > EXT3_MAX_RESERVE_BLOCKS)
-                               size = EXT3_MAX_RESERVE_BLOCKS;
-                       atomic_set(&my_rsv->rsv_goal_size, size);
-               }
-       }
-       else {
-               /*
-                * we don't have a reservation,
-                * we set our goal(start_block) and
-                * the list head for the search
-                */
-               search_head = fs_rsv_head;
-       }
-
-       /*
-        * find_next_reservable_window() simply find a reservable window
-        * inside the given range(start_block, group_end_block).
-        *
-        * To make sure the reservation window has a free bit inside it, we
-        * need to check the bitmap after we found a reservable window.
-        */
-retry:
-       prev_rsv = find_next_reservable_window(search_head, fs_rsv_head, size,
-                                               &start_block, group_end_block);
-       if (prev_rsv == NULL)
-               goto failed;
-       reservable_space_start = start_block;
-       /*
-        * On success, find_next_reservable_window() returns the
-        * reservation window where there is a reservable space after it.
-        * Before we reserve this reservable space, we need
-        * to make sure there is at least a free block inside this region.
-        *
-        * searching the first free bit on the block bitmap and copy of
-        * last committed bitmap alternatively, until we found a allocatable
-        * block. Search start from the start block of the reservable space
-        * we just found.
-        */
-       first_free_block = bitmap_search_next_usable_block(
-                       reservable_space_start - group_first_block,
-                       bitmap_bh, group_end_block - group_first_block + 1);
-
-       if (first_free_block < 0) {
-               /*
-                * no free block left on the bitmap, no point
-                * to reserve the space. return failed.
-                */
-               goto failed;
-       }
-       start_block = first_free_block + group_first_block;
-       /*
-        * check if the first free block is within the
-        * free space we just found
-        */
-       if ((start_block >= reservable_space_start) &&
-         (start_block < reservable_space_start + size))
-               goto found_rsv_window;
-       /*
-        * if the first free bit we found is out of the reservable space
-        * this means there is no free block on the reservable space
-        * we should continue search for next reservable space,
-        * start from where the free block is,
-        * we also shift the list head to where we stopped last time
-        */
-       search_head = prev_rsv;
-       goto retry;
-
-found_rsv_window:
-       /*
-        * great! the reservable space contains some free blocks.
-        * if the search returns that we should add the new
-        * window just next to where the old window, we don't
-        * need to remove the old window first then add it to the
-        * same place, just update the new start and new end.
-        */
-       if (my_rsv != prev_rsv)  {
-               if (!rsv_is_empty(my_rsv))
-                       rsv_window_remove(my_rsv);
-               rsv_window_add(my_rsv, prev_rsv);
-       }
-       my_rsv->rsv_start = reservable_space_start;
-       my_rsv->rsv_end = my_rsv->rsv_start + size - 1;
-       return 0;               /* succeed */
-failed:
-       return -1;              /* failed */
-}
-
-/*
- * This is the main function used to allocate a new block and its reservation
- * window.
- *
- * Each time when a new block allocation is need, first try to allocate from
- * its own reservation.  If it does not have a reservation window, instead of
- * looking for a free bit on bitmap first, then look up the reservation list to
- * see if it is inside somebody else's reservation window, we try to allocate a
- * reservation window for it start from the goal first. Then do the block
- * allocation within the reservation window.
- *
- * This will aviod keep searching the reservation list again and again when
- * someboday is looking for a free block(without reservation), and there are
- * lots of free blocks, but they are all being reserved
- *
- * We use a sorted double linked list for the per-filesystem reservation list.
- * The insert, remove and find a free space(non-reserved) operations for the
- * sorted double linked list should be fast.
- *
- */
-static int
-ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
-                       unsigned int group, struct buffer_head *bitmap_bh,
-                       int goal, struct reserve_window * my_rsv,
-                       int *errp)
-{
-       spinlock_t *rsv_lock;
-       unsigned long group_first_block;
-       int ret = 0;
-       int fatal;
-       int credits = 0;
-
-       *errp = 0;
-
-       /*
-        * Make sure we use undo access for the bitmap, because it is critical
-        * that we do the frozen_data COW on bitmap buffers in all cases even
-        * if the buffer is in BJ_Forget state in the committing transaction.
-        */
-       BUFFER_TRACE(bitmap_bh, "get undo access for new block");
-       fatal = ext3_journal_get_undo_access(handle, bitmap_bh, &credits);
+       BUFFER_TRACE(bitmap_bh, "journal_dirty_metadata for bitmap block");
+       fatal = ext3_journal_dirty_metadata(handle, bitmap_bh);
        if (fatal) {
                *errp = fatal;
-               return -1;
-       }
-
-       /*
-        * we don't deal with reservation when
-        * filesystem is mounted without reservation
-        * or the file is not a regular file
-        * of last attemp of allocating a block with reservation turn on failed
-        */
-       if (my_rsv == NULL ) {
-               ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, NULL);
-               goto out;
-       }
-       rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock;
-       /*
-        * goal is a group relative block number (if there is a goal)
-        * 0 < goal < EXT3_BLOCKS_PER_GROUP(sb)
-        * first block is a filesystem wide block number
-        * first block is the block number of the first block in this group
-        */
-       group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
-                       group * EXT3_BLOCKS_PER_GROUP(sb);
-
-       /*
-        * Basically we will allocate a new block from inode's reservation
-        * window.
-        *
-        * We need to allocate a new reservation window, if:
-        * a) inode does not have a reservation window; or
-        * b) last attemp of allocating a block from existing reservation
-        *    failed; or
-        * c) we come here with a goal and with a reservation window
-        *
-        * We do not need to allocate a new reservation window if we come here
-        * at the beginning with a goal and the goal is inside the window, or
-        * or we don't have a goal but already have a reservation window.
-        * then we could go to allocate from the reservation window directly.
-        */
-       while (1) {
-               if (rsv_is_empty(my_rsv) || (ret < 0) ||
-                       !goal_in_my_reservation(my_rsv, goal, group, sb)) {
-                       spin_lock(rsv_lock);
-                       ret = alloc_new_reservation(my_rsv, goal, sb,
-                                                       group, bitmap_bh);
-                       spin_unlock(rsv_lock);
-                       if (ret < 0)
-                               break;                  /* failed */
-
-                       if (!goal_in_my_reservation(my_rsv, goal, group, sb))
-                               goal = -1;
-               }
-               if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb))
-                       || (my_rsv->rsv_end < group_first_block))
-                       BUG();
-               ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal,
-                                       my_rsv);
-               if (ret >= 0)
-                       break;                          /* succeed */
-       }
-out:
-       if (ret >= 0) {
-               BUFFER_TRACE(bitmap_bh, "journal_dirty_metadata for "
-                                       "bitmap block");
-               fatal = ext3_journal_dirty_metadata(handle, bitmap_bh);
-               if (fatal) {
-                       *errp = fatal;
-                       return -1;
-               }
-               return ret;
+               goto fail;
        }
+       return goal;
 
+fail_access:
        BUFFER_TRACE(bitmap_bh, "journal_release_buffer");
        ext3_journal_release_buffer(handle, bitmap_bh, credits);
-       return ret;
+fail:
+       return -1;
 }
 
 static int ext3_has_free_blocks(struct ext3_sb_info *sbi)
@@ -1000,16 +503,16 @@ int ext3_should_retry_alloc(struct super_block *sb, int *retries)
  * bitmap, and then for any free bit if that fails.
  * This function also updates quota and i_blocks field.
  */
-int ext3_new_block(handle_t *handle, struct inode *inode,
-                       unsigned long goal, int *errp)
+int
+ext3_new_block(handle_t *handle, struct inode *inode, unsigned long goal,
+               u32 *prealloc_count, u32 *prealloc_block, int *errp)
 {
-       struct buffer_head *bitmap_bh = NULL;
-       struct buffer_head *gdp_bh;
-       int group_no;
-       int goal_group;
-       int ret_block;
-       int bgi;                        /* blockgroup iteration index */
-       int target_block;
+       struct buffer_head *bitmap_bh = NULL;   /* bh */
+       struct buffer_head *gdp_bh;             /* bh2 */
+       int group_no;                           /* i */
+       int ret_block;                          /* j */
+       int bgi;                                /* blockgroup iteration index */
+       int target_block;                       /* tmp */
        int fatal = 0, err;
        int performed_allocation = 0;
        int free_blocks;
@@ -1017,7 +520,6 @@ int ext3_new_block(handle_t *handle, struct inode *inode,
        struct ext3_group_desc *gdp;
        struct ext3_super_block *es;
        struct ext3_sb_info *sbi;
-       struct reserve_window *my_rsv = NULL;
 #ifdef EXT3FS_DEBUG
        static int goal_hits, goal_attempts;
 #endif
@@ -1039,8 +541,7 @@ int ext3_new_block(handle_t *handle, struct inode *inode,
        sbi = EXT3_SB(sb);
        es = EXT3_SB(sb)->s_es;
        ext3_debug("goal=%lu.\n", goal);
-       if (test_opt(sb, RESERVATION) && S_ISREG(inode->i_mode))
-               my_rsv = &EXT3_I(inode)->i_rsv_window;
+
        if (!ext3_has_free_blocks(sbi)) {
                *errp = -ENOSPC;
                goto out;
@@ -1058,8 +559,6 @@ int ext3_new_block(handle_t *handle, struct inode *inode,
        if (!gdp)
                goto io_error;
 
-       goal_group = group_no;
-retry:
        free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
        if (free_blocks > 0) {
                ret_block = ((goal - le32_to_cpu(es->s_first_data_block)) %
@@ -1067,8 +566,8 @@ retry:
                bitmap_bh = read_block_bitmap(sb, group_no);
                if (!bitmap_bh)
                        goto io_error;
-               ret_block = ext3_try_to_allocate_with_rsv(sb, handle, group_no,
-                                       bitmap_bh, ret_block, my_rsv, &fatal);
+               ret_block = ext3_try_to_allocate(sb, handle, group_no,
+                                       bitmap_bh, ret_block, &fatal);
                if (fatal)
                        goto out;
                if (ret_block >= 0)
@@ -1096,25 +595,14 @@ retry:
                bitmap_bh = read_block_bitmap(sb, group_no);
                if (!bitmap_bh)
                        goto io_error;
-               ret_block = ext3_try_to_allocate_with_rsv(sb, handle, group_no,
-                                       bitmap_bh, -1, my_rsv, &fatal);
+               ret_block = ext3_try_to_allocate(sb, handle, group_no,
+                                               bitmap_bh, -1, &fatal);
                if (fatal)
                        goto out;
                if (ret_block >= 0) 
                        goto allocated;
        }
-       /*
-        * We may end up a bogus ealier ENOSPC error due to
-        * filesystem is "full" of reservations, but
-        * there maybe indeed free blocks avaliable on disk
-        * In this case, we just forget about the reservations
-        * just do block allocation as without reservations.
-        */
-       if (my_rsv) {
-               my_rsv = NULL;
-               group_no = goal_group;
-               goto retry;
-       }
+
        /* No space left on the device */
        *errp = -ENOSPC;
        goto out;
index cb02116..50ba686 100644 (file)
  */
 static int ext3_release_file (struct inode * inode, struct file * filp)
 {
-       /* if we are the last writer on the inode, drop the block reservation */
-       if ((filp->f_mode & FMODE_WRITE) &&
-                       (atomic_read(&inode->i_writecount) == 1))
-               ext3_discard_reservation(inode);
+       if (filp->f_mode & FMODE_WRITE)
+               ext3_discard_prealloc (inode);
        if (is_dx(inode) && filp->private_data)
                ext3_htree_free_dir_info(filp->private_data);
 
index 11ac3c2..ac238b2 100644 (file)
@@ -581,11 +581,10 @@ got:
        ei->i_file_acl = 0;
        ei->i_dir_acl = 0;
        ei->i_dtime = 0;
-       ei->i_rsv_window.rsv_start = 0;
-       ei->i_rsv_window.rsv_end = 0;
-       atomic_set(&ei->i_rsv_window.rsv_goal_size, EXT3_DEFAULT_RESERVE_BLOCKS);
-       ei->i_rsv_window.rsv_alloc_hit = 0;
-       INIT_LIST_HEAD(&ei->i_rsv_window.rsv_list);
+#ifdef EXT3_PREALLOCATE
+       ei->i_prealloc_block = 0;
+       ei->i_prealloc_count = 0;
+#endif
        ei->i_block_group = group;
 
        ext3_set_inode_flags(inode);
index f6f61f7..e359ba3 100644 (file)
@@ -176,6 +176,19 @@ static int ext3_journal_test_restart(handle_t *handle, struct inode *inode)
        return ext3_journal_restart(handle, blocks_for_truncate(inode));
 }
 
+/*
+ * Called at each iput()
+ *
+ * The inode may be "bad" if ext3_read_inode() saw an error from
+ * ext3_get_inode(), so we need to check that to avoid freeing random disk
+ * blocks.
+ */
+void ext3_put_inode(struct inode *inode)
+{
+       if (!is_bad_inode(inode))
+               ext3_discard_prealloc(inode);
+}
+
 /*
  * Called at the last iput() if i_nlink is zero.
  */
@@ -229,12 +242,62 @@ no_delete:
        clear_inode(inode);     /* We must guarantee clearing of inode... */
 }
 
+void ext3_discard_prealloc (struct inode * inode)
+{
+#ifdef EXT3_PREALLOCATE
+       struct ext3_inode_info *ei = EXT3_I(inode);
+       /* Writer: ->i_prealloc* */
+       if (ei->i_prealloc_count) {
+               unsigned short total = ei->i_prealloc_count;
+               unsigned long block = ei->i_prealloc_block;
+               ei->i_prealloc_count = 0;
+               ei->i_prealloc_block = 0;
+               /* Writer: end */
+               ext3_free_blocks (inode, block, total);
+       }
+#endif
+}
+
 static int ext3_alloc_block (handle_t *handle,
                        struct inode * inode, unsigned long goal, int *err)
 {
        unsigned long result;
 
-       result = ext3_new_block (handle, inode, goal, err);
+#ifdef EXT3_PREALLOCATE
+#ifdef EXT3FS_DEBUG
+       static unsigned long alloc_hits, alloc_attempts;
+#endif
+       struct ext3_inode_info *ei = EXT3_I(inode);
+       /* Writer: ->i_prealloc* */
+       if (ei->i_prealloc_count &&
+           (goal == ei->i_prealloc_block ||
+            goal + 1 == ei->i_prealloc_block))
+       {
+               result = ei->i_prealloc_block++;
+               ei->i_prealloc_count--;
+               /* Writer: end */
+               ext3_debug ("preallocation hit (%lu/%lu).\n",
+                           ++alloc_hits, ++alloc_attempts);
+       } else {
+               ext3_discard_prealloc (inode);
+               ext3_debug ("preallocation miss (%lu/%lu).\n",
+                           alloc_hits, ++alloc_attempts);
+               if (S_ISREG(inode->i_mode))
+                       result = ext3_new_block (inode, goal, 
+                                &ei->i_prealloc_count,
+                                &ei->i_prealloc_block, err);
+               else
+                       result = ext3_new_block (inode, goal, 0, 0, err);
+               /*
+                * AKPM: this is somewhat sticky.  I'm not surprised it was
+                * disabled in 2.2's ext3.  Need to integrate b_committed_data
+                * guarding with preallocation, if indeed preallocation is
+                * effective.
+                */
+       }
+#else
+       result = ext3_new_block (handle, inode, goal, 0, 0, err);
+#endif
        return result;
 }
 
@@ -902,6 +965,38 @@ struct buffer_head *ext3_bread(handle_t *handle, struct inode * inode,
        bh = ext3_getblk (handle, inode, block, create, err);
        if (!bh)
                return bh;
+#ifdef EXT3_PREALLOCATE
+       /*
+        * If the inode has grown, and this is a directory, then use a few
+        * more of the preallocated blocks to keep directory fragmentation
+        * down.  The preallocated blocks are guaranteed to be contiguous.
+        */
+       if (create &&
+           S_ISDIR(inode->i_mode) &&
+           inode->i_blocks > prev_blocks &&
+           EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
+                                   EXT3_FEATURE_COMPAT_DIR_PREALLOC)) {
+               int i;
+               struct buffer_head *tmp_bh;
+
+               for (i = 1;
+                    EXT3_I(inode)->i_prealloc_count &&
+                    i < EXT3_SB(inode->i_sb)->s_es->s_prealloc_dir_blocks;
+                    i++) {
+                       /*
+                        * ext3_getblk will zero out the contents of the
+                        * directory for us
+                        */
+                       tmp_bh = ext3_getblk(handle, inode,
+                                               block+i, create, err);
+                       if (!tmp_bh) {
+                               brelse (bh);
+                               return 0;
+                       }
+                       brelse (tmp_bh);
+               }
+       }
+#endif
        if (buffer_uptodate(bh))
                return bh;
        ll_rw_block (READ, 1, &bh);
@@ -2044,7 +2139,7 @@ void ext3_truncate(struct inode * inode)
        if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
                return;
 
-       ext3_discard_reservation(inode);
+       ext3_discard_prealloc(inode);
 
        /*
         * We have to lock the EOF page here, because lock_page() nests
@@ -2199,11 +2294,9 @@ static unsigned long ext3_get_inode_block(struct super_block *sb,
        unsigned long offset, block;
        struct buffer_head *bh;
        struct ext3_group_desc * gdp;
-       
 
        if ((ino != EXT3_ROOT_INO &&
                ino != EXT3_JOURNAL_INO &&
-               ino != EXT3_RESIZE_INO &&
                ino < EXT3_FIRST_INO(sb)) ||
                ino > le32_to_cpu(
                        EXT3_SB(sb)->s_es->s_inodes_count)) {
@@ -2439,11 +2532,11 @@ void ext3_read_inode(struct inode * inode)
        }
        ei->i_disksize = inode->i_size;
        inode->i_generation = le32_to_cpu(raw_inode->i_generation);
+#ifdef EXT3_PREALLOCATE
+       ei->i_prealloc_count = 0;
+#endif
        ei->i_block_group = iloc.block_group;
-       ei->i_rsv_window.rsv_start = 0;
-       ei->i_rsv_window.rsv_end= 0;
-       atomic_set(&ei->i_rsv_window.rsv_goal_size, EXT3_DEFAULT_RESERVE_BLOCKS);
-       INIT_LIST_HEAD(&ei->i_rsv_window.rsv_list);
+
        /*
         * NOTE! The in-memory inode i_data array is in little-endian order
         * even on big-endian machines: we do NOT byteswap the block numbers!
index e2ea75c..0d50039 100644 (file)
@@ -20,14 +20,13 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
 {
        struct ext3_inode_info *ei = EXT3_I(inode);
        unsigned int flags;
-       unsigned short rsv_window_size;
 
        ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg);
 
        switch (cmd) {
        case EXT3_IOC_GETFLAGS:
                flags = ei->i_flags & EXT3_FL_USER_VISIBLE;
-               return put_user(flags, (int *) arg);
+               return put_user(flags, (int __user *) arg);
        case EXT3_IOC_SETFLAGS: {
                handle_t *handle = NULL;
                int err;
@@ -41,7 +40,7 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
                if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
                        return -EACCES;
 
-               if (get_user(flags, (int *) arg))
+               if (get_user(flags, (int __user *) arg))
                        return -EFAULT;
 
                if (!S_ISDIR(inode->i_mode))
@@ -101,7 +100,7 @@ flags_err:
        }
        case EXT3_IOC_GETVERSION:
        case EXT3_IOC_GETVERSION_OLD:
-               return put_user(inode->i_generation, (int *) arg);
+               return put_user(inode->i_generation, (int __user *) arg);
        case EXT3_IOC_SETVERSION:
        case EXT3_IOC_SETVERSION_OLD: {
                handle_t *handle;
@@ -113,7 +112,7 @@ flags_err:
                        return -EPERM;
                if (IS_RDONLY(inode))
                        return -EROFS;
-               if (get_user(generation, (int *) arg))
+               if (get_user(generation, (int __user *) arg))
                        return -EFAULT;
 
                handle = ext3_journal_start(inode, 1);
@@ -152,74 +151,6 @@ flags_err:
                        return ret;
                }
 #endif
-       case EXT3_IOC_GETRSVSZ:
-               if (test_opt(inode->i_sb, RESERVATION) && S_ISREG(inode->i_mode)) {
-                       rsv_window_size = atomic_read(&ei->i_rsv_window.rsv_goal_size);
-                       return put_user(rsv_window_size, (int *)arg);
-               }
-               return -ENOTTY;
-       case EXT3_IOC_SETRSVSZ:
-               if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
-                       return -ENOTTY;
-
-               if (IS_RDONLY(inode))
-                       return -EROFS;
-
-               if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
-                       return -EACCES;
-
-               if (get_user(rsv_window_size, (int *)arg))
-                       return -EFAULT;
-
-               if (rsv_window_size > EXT3_MAX_RESERVE_BLOCKS)
-                       rsv_window_size = EXT3_MAX_RESERVE_BLOCKS;
-               atomic_set(&ei->i_rsv_window.rsv_goal_size, rsv_window_size);
-               return 0;
-       case EXT3_IOC_GROUP_EXTEND: {
-               unsigned long n_blocks_count;
-               struct super_block *sb = inode->i_sb;
-               int err;
-
-               if (!capable(CAP_SYS_RESOURCE))
-                       return -EACCES;
-
-               if (sb->s_flags & MS_RDONLY)
-                       return -EROFS;
-
-               if (get_user(n_blocks_count, (__u32 *)arg))
-                       return -EFAULT;
-
-               err = ext3_group_extend(sb, EXT3_SB(sb)->s_es, n_blocks_count);
-               journal_lock_updates(EXT3_SB(sb)->s_journal);
-               journal_flush(EXT3_SB(sb)->s_journal);
-               journal_unlock_updates(EXT3_SB(sb)->s_journal);
-
-               return err;
-       }
-       case EXT3_IOC_GROUP_ADD: {
-               struct ext3_new_group_data input;
-               struct super_block *sb = inode->i_sb;
-               int err;
-
-               if (!capable(CAP_SYS_RESOURCE))
-                       return -EACCES;
-
-               if (inode->i_sb->s_flags & MS_RDONLY)
-                       return -EROFS;
-
-               if (copy_from_user(&input, (struct ext3_new_group_input *)arg,
-                               sizeof(input)))
-                       return -EFAULT;
-
-               err = ext3_group_add(sb, &input);
-               journal_lock_updates(EXT3_SB(sb)->s_journal);
-               journal_flush(EXT3_SB(sb)->s_journal);
-               journal_unlock_updates(EXT3_SB(sb)->s_journal);
-
-               return err;
-       }
-
-
        default:
                return -ENOTTY;
        }
index a93119c..4ee524b 100644 (file)
@@ -557,6 +557,8 @@ static int htree_dirblock_to_tree(struct file *dir_file,
                    ((hinfo->hash == start_hash) &&
                     (hinfo->minor_hash < start_minor_hash)))
                        continue;
+               if (de->inode == 0)
+                       continue;
                if ((err = ext3_htree_store_dirent(dir_file,
                                   hinfo->hash, hinfo->minor_hash, de)) != 0) {
                        brelse(bh);
@@ -1971,8 +1973,6 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode)
                goto out_brelse;
        NEXT_ORPHAN(inode) = 0;
        err = ext3_mark_iloc_dirty(handle, inode, &iloc);
-       if (err)
-               goto out_brelse;
 
 out_err:
        ext3_std_error(inode->i_sb, err);
index 9c59011..ad0977b 100644 (file)
@@ -493,9 +493,10 @@ static void destroy_inodecache(void)
                printk(KERN_INFO "ext3_inode_cache: not all structures were freed\n");
 }
 
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+
 static void ext3_clear_inode(struct inode *inode)
 {
-#ifdef CONFIG_EXT3_FS_POSIX_ACL
        if (EXT3_I(inode)->i_acl &&
            EXT3_I(inode)->i_acl != EXT3_ACL_NOT_CACHED) {
                posix_acl_release(EXT3_I(inode)->i_acl);
@@ -506,11 +507,12 @@ static void ext3_clear_inode(struct inode *inode)
                posix_acl_release(EXT3_I(inode)->i_default_acl);
                EXT3_I(inode)->i_default_acl = EXT3_ACL_NOT_CACHED;
        }
-#endif
-       if (!is_bad_inode(inode))
-               ext3_discard_reservation(inode);
 }
 
+#else
+# define ext3_clear_inode NULL
+#endif
+
 #ifdef CONFIG_QUOTA
 
 #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
@@ -559,6 +561,7 @@ static struct super_operations ext3_sops = {
        .read_inode     = ext3_read_inode,
        .write_inode    = ext3_write_inode,
        .dirty_inode    = ext3_dirty_inode,
+       .put_inode      = ext3_put_inode,
        .delete_inode   = ext3_delete_inode,
        .put_super      = ext3_put_super,
        .write_super    = ext3_write_super,
@@ -579,13 +582,12 @@ enum {
        Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
        Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
        Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
-       Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
-       Opt_reservation, Opt_noreservation, Opt_noload,
+       Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_noload,
        Opt_commit, Opt_journal_update, Opt_journal_inum,
        Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
        Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
        Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0,
-       Opt_ignore, Opt_err, Opt_resize,
+       Opt_ignore, Opt_err,
 };
 
 static match_table_t tokens = {
@@ -612,8 +614,6 @@ static match_table_t tokens = {
        {Opt_nouser_xattr, "nouser_xattr"},
        {Opt_acl, "acl"},
        {Opt_noacl, "noacl"},
-       {Opt_reservation, "reservation"},
-       {Opt_noreservation, "noreservation"},
        {Opt_noload, "noload"},
        {Opt_commit, "commit=%u"},
        {Opt_journal_update, "journal=update"},
@@ -632,9 +632,7 @@ static match_table_t tokens = {
        {Opt_ignore, "noquota"},
        {Opt_ignore, "quota"},
        {Opt_ignore, "usrquota"},
-       {Opt_err, NULL},
-       {Opt_resize, "resize"}
-               
+       {Opt_err, NULL}
 };
 
 static unsigned long get_sb_block(void **data)
@@ -658,7 +656,7 @@ static unsigned long get_sb_block(void **data)
 }
 
 static int parse_options (char * options, struct super_block *sb,
-                         unsigned long * inum, unsigned long *n_blocks_count, int is_remount)
+                         unsigned long * inum, int is_remount)
 {
        struct ext3_sb_info *sbi = EXT3_SB(sb);
        char * p;
@@ -769,12 +767,6 @@ static int parse_options (char * options, struct super_block *sb,
                        printk("EXT3 (no)acl options not supported\n");
                        break;
 #endif
-               case Opt_reservation:
-                       set_opt(sbi->s_mount_opt, RESERVATION);
-                       break;
-               case Opt_noreservation:
-                       clear_opt(sbi->s_mount_opt, RESERVATION);
-                       break;
                case Opt_journal_update:
                        /* @@@ FIXME */
                        /* Eventually we will want to be able to create
@@ -907,15 +899,6 @@ clear_qf_name:
                        break;
                case Opt_ignore:
                        break;
-               case Opt_resize:
-                       if (!n_blocks_count) {
-                               printk("EXT3-fs: resize option only available "
-                                       "for remount\n");
-                               return 0;
-                       }
-                       match_int(&args[0], &option);
-                       *n_blocks_count = option;
-                       break;
                default:
                        printk (KERN_ERR
                                "EXT3-fs: Unrecognized mount option \"%s\" "
@@ -1305,9 +1288,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
        sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
 
-       set_opt(sbi->s_mount_opt, RESERVATION);
-
-       if (!parse_options ((char *) data, sb, &journal_inum, NULL, 0))
+       if (!parse_options ((char *) data, sb, &journal_inum, 0))
                goto failed_mount;
 
        sb->s_flags |= MS_ONE_SECOND;
@@ -1481,14 +1462,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        sbi->s_gdb_count = db_count;
        get_random_bytes(&sbi->s_next_generation, sizeof(u32));
        spin_lock_init(&sbi->s_next_gen_lock);
-       /* per fileystem reservation list head & lock */
-       spin_lock_init(&sbi->s_rsv_window_lock);
-       INIT_LIST_HEAD(&sbi->s_rsv_window_head.rsv_list);
-       sbi->s_rsv_window_head.rsv_start = 0;
-       sbi->s_rsv_window_head.rsv_end = 0;
-       sbi->s_rsv_window_head.rsv_alloc_hit = 0;
-       atomic_set(&sbi->s_rsv_window_head.rsv_goal_size, 0);
-
        /*
         * set up enough so that it can read an inode
         */
@@ -1670,6 +1643,7 @@ static journal_t *ext3_get_journal(struct super_block *sb, int journal_inum)
        if (!journal) {
                printk(KERN_ERR "EXT3-fs: Could not load journal inode\n");
                iput(journal_inode);
+               return NULL;
        }
        journal->j_private = sb;
        ext3_init_journal_params(EXT3_SB(sb), journal);
@@ -1901,13 +1875,17 @@ static void ext3_commit_super (struct super_block * sb,
 static void ext3_mark_recovery_complete(struct super_block * sb,
                                        struct ext3_super_block * es)
 {
-       journal_flush(EXT3_SB(sb)->s_journal);
+       journal_t *journal = EXT3_SB(sb)->s_journal;
+
+       journal_lock_updates(journal);
+       journal_flush(journal);
        if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) &&
            sb->s_flags & MS_RDONLY) {
                EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
                sb->s_dirt = 0;
                ext3_commit_super(sb, es, 1);
        }
+       journal_unlock_updates(journal);
 }
 
 /*
@@ -2035,12 +2013,11 @@ int ext3_remount (struct super_block * sb, int * flags, char * data)
        struct ext3_super_block * es;
        struct ext3_sb_info *sbi = EXT3_SB(sb);
        unsigned long tmp;
-       unsigned long n_blocks_count = 0;
 
        /*
         * Allow the "check" option to be passed as a remount option.
         */
-       if (!parse_options(data, sb, &tmp, &n_blocks_count, 1))
+       if (!parse_options(data, sb, &tmp, 1))
                return -EINVAL;
 
        if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
@@ -2053,8 +2030,7 @@ int ext3_remount (struct super_block * sb, int * flags, char * data)
 
        ext3_init_journal_params(sbi, sbi->s_journal);
 
-       if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
-               n_blocks_count > le32_to_cpu(es->s_blocks_count)) {
+       if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
                if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
                        return -EROFS;
 
@@ -2093,8 +2069,6 @@ int ext3_remount (struct super_block * sb, int * flags, char * data)
                         */
                        ext3_clear_journal_err(sb, es);
                        sbi->s_mount_state = le16_to_cpu(es->s_state);
-                       if ((ret = ext3_group_extend(sb, es, n_blocks_count)))
-                               return ret;
                        if (!ext3_setup_super (sb, es, 0))
                                sb->s_flags &= ~MS_RDONLY;
                }
index b766908..e818bee 100644 (file)
@@ -787,7 +787,7 @@ ext3_xattr_set_handle2(handle_t *handle, struct inode *inode,
                                EXT3_I(inode)->i_block_group *
                                EXT3_BLOCKS_PER_GROUP(sb);
                        int block = ext3_new_block(handle,
-                               inode, goal, &error);
+                               inode, goal, 0, 0, &error);
                        if (error)
                                goto cleanup;
                        ea_idebug(inode, "creating block %d", block);
index 0e73e30..5f3ccf9 100644 (file)
@@ -396,9 +396,19 @@ restart:
        sb = sb_entry(super_blocks.prev);
        for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.prev)) {
                if (!list_empty(&sb->s_dirty) || !list_empty(&sb->s_io)) {
+                       /* we're making our own get_super here */
                        sb->s_count++;
                        spin_unlock(&sb_lock);
-                       sync_sb_inodes(sb, wbc);
+                       /*
+                        * If we can't get the readlock, there's no sense in
+                        * waiting around, most of the time the FS is going to
+                        * be unmounted by the time it is released.
+                        */
+                       if (down_read_trylock(&sb->s_umount)) {
+                               if (sb->s_root)
+                                       sync_sb_inodes(sb, wbc);
+                               up_read(&sb->s_umount);
+                       }
                        spin_lock(&sb_lock);
                        if (__put_super(sb))
                                goto restart;
@@ -423,18 +433,15 @@ restart:
  */
 void sync_inodes_sb(struct super_block *sb, int wait)
 {
-       struct page_state ps;
        struct writeback_control wbc = {
-               .bdi            = NULL,
                .sync_mode      = wait ? WB_SYNC_ALL : WB_SYNC_HOLD,
-               .older_than_this = NULL,
-               .nr_to_write    = 0,
        };
+       unsigned long nr_dirty = read_page_state(nr_dirty);
+       unsigned long nr_unstable = read_page_state(nr_unstable);
 
-       get_page_state(&ps);
-       wbc.nr_to_write = ps.nr_dirty + ps.nr_unstable +
+       wbc.nr_to_write = nr_dirty + nr_unstable +
                        (inodes_stat.nr_inodes - inodes_stat.nr_unused) +
-                       ps.nr_dirty + ps.nr_unstable;
+                       nr_dirty + nr_unstable;
        wbc.nr_to_write += wbc.nr_to_write / 2;         /* Bit more for luck */
        spin_lock(&inode_lock);
        sync_sb_inodes(sb, &wbc);
index 440e0da..bd05477 100644 (file)
@@ -31,7 +31,7 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
                        flags |= EXT2_FLAG_APPEND; /* EXT2_APPEND_FL */
                if (HFSPLUS_I(inode).userflags & HFSPLUS_FLG_NODUMP)
                        flags |= EXT2_FLAG_NODUMP; /* EXT2_NODUMP_FL */
-               return put_user(flags, (int *)arg);
+               return put_user(flags, (int __user *)arg);
        case HFSPLUS_IOC_EXT2_SETFLAGS: {
                if (IS_RDONLY(inode))
                        return -EROFS;
@@ -39,7 +39,7 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
                if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
                        return -EACCES;
 
-               if (get_user(flags, (int *)arg))
+               if (get_user(flags, (int __user *)arg))
                        return -EFAULT;
 
                if (flags & (EXT2_FLAG_IMMUTABLE|EXT2_FLAG_APPEND) ||
index abfd24a..db1c175 100644 (file)
@@ -725,7 +725,7 @@ struct file *hugetlb_zero_setup(size_t size)
        struct qstr quick_string;
        char buf[16];
 
-       if (!can_do_mlock())
+       if (!capable(CAP_IPC_LOCK))
                return ERR_PTR(-EPERM);
 
        if (!is_hugepage_mem_enough(size))
index 35049c1..bf162f0 100644 (file)
@@ -4,7 +4,7 @@
 
 obj-$(CONFIG_ISO9660_FS) += isofs.o
 
-isofs-objs-y                   := namei.o inode.o dir.o util.o rock.o
+isofs-objs-y                   := namei.o inode.o dir.o util.o rock.o export.o
 isofs-objs-$(CONFIG_JOLIET)    += joliet.o
 isofs-objs-$(CONFIG_ZISOFS)    += compress.o
 isofs-objs                     := $(isofs-objs-y)
index 1f2f92a..14d86de 100644 (file)
@@ -64,7 +64,8 @@ int isofs_name_translate(struct iso_directory_record *de, char *new, struct inod
                        break;
 
                /* Convert remaining ';' to '.' */
-               if (c == ';')
+               /* Also '/' to '.' (broken Acorn-generated ISO9660 images) */
+               if (c == ';' || c == '/')
                        c = '.';
 
                new[i] = c;
@@ -106,8 +107,8 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
 {
        unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
        unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
-       unsigned int block, offset;
-       int inode_number = 0;   /* Quiet GCC */
+       unsigned long block, offset, block_saved, offset_saved;
+       unsigned long inode_number = 0; /* Quiet GCC */
        struct buffer_head *bh = NULL;
        int len;
        int map;
@@ -129,8 +130,6 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
                }
 
                de = (struct iso_directory_record *) (bh->b_data + offset);
-               if (first_de)
-                       inode_number = (bh->b_blocknr << bufbits) + offset;
 
                de_len = *(unsigned char *) de;
 
@@ -147,6 +146,8 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
                        continue;
                }
 
+               block_saved = block;
+               offset_saved = offset;
                offset += de_len;
 
                /* Make sure we have a full directory entry */
@@ -166,6 +167,15 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
                        de = tmpde;
                }
 
+               if (first_de) {
+                       isofs_normalize_block_and_offset(de,
+                                                        &block_saved,
+                                                        &offset_saved);
+                       inode_number = isofs_get_ino(block_saved,
+                                                    offset_saved,
+                                                    bufbits);
+               }
+
                if (de->flags[-sbi->s_high_sierra] & 0x80) {
                        first_de = 0;
                        filp->f_pos += de_len;
index 768367e..9d498e2 100644 (file)
@@ -7,6 +7,8 @@
  *      1995  Mark Dobie - allow mounting of some weird VideoCDs and PhotoCDs.
  *     1997  Gordon Chaffee - Joliet CDs
  *     1998  Eric Lammerts - ISO 9660 Level 3
+ *     2004  Paul Serice - Inode Support pushed out from 4GB to 128GB
+ *     2004  Paul Serice - NFS Export Operations
  */
 
 #include <linux/config.h>
@@ -135,20 +137,6 @@ static struct super_operations isofs_sops = {
        .remount_fs     = isofs_remount,
 };
 
-/* the export_operations structure for describing
- * how to export (e.g. via kNFSd) is deliberately
- * empty.
- * This means that the filesystem want to use iget
- * to map an inode number into an inode.
- * The lack of a get_parent operation means that 
- * if something isn't in the cache, then you cannot
- * access it.
- * It should be possible to write a get_parent,
- * but it would be a bit hairy...
- */
-static struct export_operations isofs_export_ops = {
-};
-
 
 static struct dentry_operations isofs_dentry_ops[] = {
        {
@@ -738,19 +726,14 @@ root_found:
        /* Set this for reference. Its not currently used except on write
           which we don't have .. */
           
-       /* RDE: data zone now byte offset! */
-
-       first_data_zone = ((isonum_733 (rootp->extent) +
-                         isonum_711 (rootp->ext_attr_length))
-                        << sbi->s_log_zone_size);
+       first_data_zone = isonum_733 (rootp->extent) +
+                         isonum_711 (rootp->ext_attr_length);
        sbi->s_firstdatazone = first_data_zone;
 #ifndef BEQUIET
        printk(KERN_DEBUG "Max size:%ld   Log zone size:%ld\n",
               sbi->s_max_size,
               1UL << sbi->s_log_zone_size);
-       printk(KERN_DEBUG "First datazone:%ld   Root inode number:%ld\n",
-              sbi->s_firstdatazone >> sbi->s_log_zone_size,
-              sbi->s_firstdatazone);
+       printk(KERN_DEBUG "First datazone:%ld\n", sbi->s_firstdatazone);
        if(sbi->s_high_sierra)
                printk(KERN_DEBUG "Disc in High Sierra format.\n");
 #endif
@@ -767,9 +750,8 @@ root_found:
                pri = (struct iso_primary_descriptor *) sec;
                rootp = (struct iso_directory_record *)
                        pri->root_directory_record;
-               first_data_zone = ((isonum_733 (rootp->extent) +
-                               isonum_711 (rootp->ext_attr_length))
-                                << sbi->s_log_zone_size);
+               first_data_zone = isonum_733 (rootp->extent) +
+                               isonum_711 (rootp->ext_attr_length);
        }
 
        /*
@@ -835,7 +817,7 @@ root_found:
         * the s_rock flag. Once we have the final s_rock value,
         * we then decide whether to use the Joliet descriptor.
         */
-       inode = iget(s, sbi->s_firstdatazone);
+       inode = isofs_iget(s, sbi->s_firstdatazone, 0);
 
        /*
         * If this disk has both Rock Ridge and Joliet on it, then we
@@ -854,7 +836,7 @@ root_found:
                        printk(KERN_DEBUG 
                                "ISOFS: changing to secondary root\n");
                        iput(inode);
-                       inode = iget(s, sbi->s_firstdatazone);
+                       inode = isofs_iget(s, sbi->s_firstdatazone, 0);
                }
        }
 
@@ -952,7 +934,7 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
        unsigned long b_off;
        unsigned offset, sect_size;
        unsigned int firstext;
-       unsigned long nextino;
+       unsigned long nextblk, nextoff;
        long iblock = (long)iblock_s;
        int section, rv;
        struct iso_inode_info *ei = ISOFS_I(inode);
@@ -970,7 +952,8 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
        offset    = 0;
        firstext  = ei->i_first_extent;
        sect_size = ei->i_section_size >> ISOFS_BUFFER_BITS(inode);
-       nextino   = ei->i_next_section_ino;
+       nextblk   = ei->i_next_section_block;
+       nextoff   = ei->i_next_section_offset;
        section   = 0;
 
        while ( nblocks ) {
@@ -987,25 +970,28 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
                        goto abort;
                }
                
-               if (nextino) {
+               if (nextblk) {
                        while (b_off >= (offset + sect_size)) {
                                struct inode *ninode;
                                
                                offset += sect_size;
-                               if (nextino == 0)
+                               if (nextblk == 0)
                                        goto abort;
-                               ninode = iget(inode->i_sb, nextino);
+                               ninode = isofs_iget(inode->i_sb, nextblk, nextoff);
                                if (!ninode)
                                        goto abort;
                                firstext  = ISOFS_I(ninode)->i_first_extent;
-                               sect_size = ISOFS_I(ninode)->i_section_size;
-                               nextino   = ISOFS_I(ninode)->i_next_section_ino;
+                               sect_size = ISOFS_I(ninode)->i_section_size >> ISOFS_BUFFER_BITS(ninode);
+                               nextblk   = ISOFS_I(ninode)->i_next_section_block;
+                               nextoff   = ISOFS_I(ninode)->i_next_section_offset;
                                iput(ninode);
                                
                                if (++section > 100) {
                                        printk("isofs_get_blocks: More than 100 file sections ?!?, aborting...\n");
-                                       printk("isofs_get_blocks: ino=%lu block=%ld firstext=%u sect_size=%u nextino=%lu\n",
-                                              inode->i_ino, iblock, firstext, (unsigned) sect_size, nextino);
+                                       printk("isofs_get_blocks: block=%ld firstext=%u sect_size=%u "
+                                              "nextblk=%lu nextoff=%lu\n",
+                                              iblock, firstext, (unsigned) sect_size,
+                                              nextblk, nextoff);
                                        goto abort;
                                }
                        }
@@ -1044,7 +1030,7 @@ static int isofs_get_block(struct inode *inode, sector_t iblock,
        return isofs_get_blocks(inode, iblock, &bh_result, 1) ? 0 : -EIO;
 }
 
-static int isofs_bmap(struct inode *inode, int block)
+static int isofs_bmap(struct inode *inode, sector_t block)
 {
        struct buffer_head dummy;
        int error;
@@ -1097,21 +1083,25 @@ static inline void test_and_set_gid(gid_t *p, gid_t value)
 
 static int isofs_read_level3_size(struct inode * inode)
 {
-       unsigned long f_pos = inode->i_ino;
        unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
        int high_sierra = ISOFS_SB(inode->i_sb)->s_high_sierra;
        struct buffer_head * bh = NULL;
-       unsigned long block, offset;
+       unsigned long block, offset, block_saved, offset_saved;
        int i = 0;
        int more_entries = 0;
        struct iso_directory_record * tmpde = NULL;
        struct iso_inode_info *ei = ISOFS_I(inode);
 
        inode->i_size = 0;
-       ei->i_next_section_ino = 0;
 
-       block = f_pos >> ISOFS_BUFFER_BITS(inode);
-       offset = f_pos & (bufsize-1);
+       /* The first 16 blocks are reserved as the System Area.  Thus,
+        * no inodes can appear in block 0.  We use this to flag that
+        * this is the last section. */
+       ei->i_next_section_block = 0;
+       ei->i_next_section_offset = 0;
+
+       block = ei->i_iget5_block;
+       offset = ei->i_iget5_offset;
 
        do {
                struct iso_directory_record * de;
@@ -1128,12 +1118,13 @@ static int isofs_read_level3_size(struct inode * inode)
                if (de_len == 0) {
                        brelse(bh);
                        bh = NULL;
-                       f_pos = (f_pos + ISOFS_BLOCK_SIZE) & ~(ISOFS_BLOCK_SIZE - 1);
-                       block = f_pos >> ISOFS_BUFFER_BITS(inode);
+                       ++block;
                        offset = 0;
                        continue;
                }
 
+               block_saved = block;
+               offset_saved = offset;
                offset += de_len;
 
                /* Make sure we have a full directory entry */
@@ -1159,12 +1150,13 @@ static int isofs_read_level3_size(struct inode * inode)
                }
 
                inode->i_size += isonum_733(de->size);
-               if (i == 1)
-                       ei->i_next_section_ino = f_pos;
+               if (i == 1) {
+                       ei->i_next_section_block = block_saved;
+                       ei->i_next_section_offset = offset_saved;
+               }
 
                more_entries = de->flags[-high_sierra] & 0x80;
 
-               f_pos += de_len;
                i++;
                if(i > 100)
                        goto out_toomany;
@@ -1190,8 +1182,8 @@ out_noread:
 out_toomany:
        printk(KERN_INFO "isofs_read_level3_size: "
                "More than 100 file sections ?!?, aborting...\n"
-               "isofs_read_level3_size: inode=%lu ino=%lu\n",
-               inode->i_ino, f_pos);
+               "isofs_read_level3_size: inode=%lu\n",
+               inode->i_ino);
        goto out;
 }
 
@@ -1200,21 +1192,22 @@ static void isofs_read_inode(struct inode * inode)
        struct super_block *sb = inode->i_sb;
        struct isofs_sb_info *sbi = ISOFS_SB(sb);
        unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
-       int block = inode->i_ino >> ISOFS_BUFFER_BITS(inode);
+       unsigned long block;
        int high_sierra = sbi->s_high_sierra;
        struct buffer_head * bh = NULL;
        struct iso_directory_record * de;
        struct iso_directory_record * tmpde = NULL;
        unsigned int de_len;
        unsigned long offset;
-       int i;
        struct iso_inode_info *ei = ISOFS_I(inode);
 
+       block = ei->i_iget5_block;
        bh = sb_bread(inode->i_sb, block);
        if (!bh)
                goto out_badread;
 
-       offset = (inode->i_ino & (bufsize - 1));
+       offset = ei->i_iget5_offset;
+
        de = (struct iso_directory_record *) (bh->b_data + offset);
        de_len = *(unsigned char *) de;
 
@@ -1235,6 +1228,10 @@ static void isofs_read_inode(struct inode * inode)
                de = tmpde;
        }
 
+       inode->i_ino = isofs_get_ino(ei->i_iget5_block,
+                                    ei->i_iget5_offset,
+                                    ISOFS_BUFFER_BITS(inode));
+
        /* Assume it is a normal-format file unless told otherwise */
        ei->i_file_format = isofs_file_normal;
 
@@ -1250,14 +1247,6 @@ static void isofs_read_inode(struct inode * inode)
                inode->i_mode = sbi->s_mode;
                inode->i_nlink = 1;
                inode->i_mode |= S_IFREG;
-               /* If there are no periods in the name,
-                * then set the execute permission bit
-                */
-               for(i=0; i< de->name_len[0]; i++)
-                       if(de->name[i]=='.' || de->name[i]==';')
-                               break;
-               if(i == de->name_len[0] || de->name[i] == ';')
-                       inode->i_mode |= S_IXUGO; /* execute permission */
        }
        inode->i_uid = sbi->s_uid;
        inode->i_gid = sbi->s_gid;
@@ -1271,7 +1260,8 @@ static void isofs_read_inode(struct inode * inode)
        if(de->flags[-high_sierra] & 0x80) {
                if(isofs_read_level3_size(inode)) goto fail;
        } else {
-               ei->i_next_section_ino = 0;
+               ei->i_next_section_block = 0;
+               ei->i_next_section_offset = 0;
                inode->i_size = isonum_733 (de->size);
        }
 
@@ -1385,6 +1375,61 @@ static void isofs_read_inode(struct inode * inode)
        goto out;
 }
 
+struct isofs_iget5_callback_data {
+       unsigned long block;
+       unsigned long offset;
+};
+
+static int isofs_iget5_test(struct inode *ino, void *data)
+{
+       struct iso_inode_info *i = ISOFS_I(ino);
+       struct isofs_iget5_callback_data *d =
+               (struct isofs_iget5_callback_data*)data;
+       return (i->i_iget5_block == d->block)
+              && (i->i_iget5_offset == d->offset);
+}
+
+static int isofs_iget5_set(struct inode *ino, void *data)
+{
+       struct iso_inode_info *i = ISOFS_I(ino);
+       struct isofs_iget5_callback_data *d =
+               (struct isofs_iget5_callback_data*)data;
+       i->i_iget5_block = d->block;
+       i->i_iget5_offset = d->offset;
+       return 0;
+}
+
+/* Store, in the inode's containing structure, the block and block
+ * offset that point to the underlying meta-data for the inode.  The
+ * code below is otherwise similar to the iget() code in
+ * include/linux/fs.h */
+struct inode *isofs_iget(struct super_block *sb,
+                        unsigned long block,
+                        unsigned long offset)
+{
+       unsigned long hashval;
+       struct inode *inode;
+       struct isofs_iget5_callback_data data;
+
+       data.block = block;
+       data.offset = offset;
+
+       hashval = (block << sb->s_blocksize_bits) | offset;
+
+       inode = iget5_locked(sb,
+                            hashval,
+                            &isofs_iget5_test,
+                            &isofs_iget5_set,
+                            &data);
+
+       if (inode && (inode->i_state & I_NEW)) {
+               sb->s_op->read_inode(inode);
+               unlock_new_inode(inode);
+       }
+
+       return inode;
+}
+
 #ifdef LEAK_CHECK
 #undef malloc
 #undef free_s
index 8d525f6..9569fc4 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/config.h>      /* Joliet? */
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
+#include <linux/dcache.h>
 
 #include <asm/uaccess.h>
 
@@ -59,12 +60,12 @@ isofs_cmp(struct dentry * dentry, const char * compare, int dlen)
  */
 static unsigned long
 isofs_find_entry(struct inode *dir, struct dentry *dentry,
+       unsigned long *block_rv, unsigned long* offset_rv,
        char * tmpname, struct iso_directory_record * tmpde)
 {
-       unsigned long inode_number;
        unsigned long bufsize = ISOFS_BUFFER_SIZE(dir);
        unsigned char bufbits = ISOFS_BUFFER_BITS(dir);
-       unsigned int block, f_pos, offset;
+       unsigned long block, f_pos, offset, block_saved, offset_saved;
        struct buffer_head * bh = NULL;
        struct isofs_sb_info *sbi = ISOFS_SB(dir->i_sb);
 
@@ -87,7 +88,6 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry,
                }
 
                de = (struct iso_directory_record *) (bh->b_data + offset);
-               inode_number = (bh->b_blocknr << bufbits) + offset;
 
                de_len = *(unsigned char *) de;
                if (!de_len) {
@@ -99,6 +99,8 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry,
                        continue;
                }
 
+               block_saved = bh->b_blocknr;
+               offset_saved = offset;
                offset += de_len;
                f_pos += de_len;
 
@@ -150,8 +152,13 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry,
                        match = (isofs_cmp(dentry,dpnt,dlen) == 0);
                }
                if (match) {
+                       isofs_normalize_block_and_offset(de,
+                                                        &block_saved,
+                                                        &offset_saved);
+                        *block_rv = block_saved;
+                        *offset_rv = offset_saved;
                        if (bh) brelse(bh);
-                       return inode_number;
+                       return 1;
                }
        }
        if (bh) brelse(bh);
@@ -160,7 +167,8 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry,
 
 struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
 {
-       unsigned long ino;
+       int found;
+       unsigned long block, offset;
        struct inode *inode;
        struct page *page;
 
@@ -171,19 +179,23 @@ struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry, struct n
                return ERR_PTR(-ENOMEM);
 
        lock_kernel();
-       ino = isofs_find_entry(dir, dentry, page_address(page),
-                              1024 + page_address(page));
+       found = isofs_find_entry(dir, dentry,
+                                &block, &offset,
+                                page_address(page),
+                                1024 + page_address(page));
        __free_page(page);
 
        inode = NULL;
-       if (ino) {
-               inode = iget(dir->i_sb, ino);
+       if (found) {
+               inode = isofs_iget(dir->i_sb, block, offset);
                if (!inode) {
                        unlock_kernel();
                        return ERR_PTR(-EACCES);
                }
        }
        unlock_kernel();
+       if (inode)
+               return d_splice_alias(inode, dentry);
        d_add(dentry, inode);
        return NULL;
 }
index 088acdc..df78cec 100644 (file)
@@ -306,9 +306,7 @@ int parse_rock_ridge_inode_internal(struct iso_directory_record * de,
        goto out;
       case SIG('C','L'):
        ISOFS_I(inode)->i_first_extent = isonum_733(rr->u.CL.location);
-       reloc = iget(inode->i_sb,
-                    (ISOFS_I(inode)->i_first_extent <<
-                     ISOFS_SB(inode->i_sb)->s_log_zone_size));
+       reloc = isofs_iget(inode->i_sb, ISOFS_I(inode)->i_first_extent, 0);
        if (!reloc)
                goto out;
        inode->i_mode = reloc->i_mode;
@@ -447,15 +445,15 @@ int parse_rock_ridge_inode(struct iso_directory_record * de,
 static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
 {
        struct inode *inode = page->mapping->host;
+        struct iso_inode_info *ei = ISOFS_I(inode);
        char *link = kmap(page);
        unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
-       unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
        struct buffer_head *bh;
        char *rpnt = link;
        unsigned char *pnt;
        struct iso_directory_record *raw_inode;
        CONTINUE_DECLS;
-       int block;
+       unsigned long block, offset;
        int sig;
        int len;
        unsigned char *chr;
@@ -464,20 +462,21 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
        if (!ISOFS_SB(inode->i_sb)->s_rock)
                panic ("Cannot have symlink with high sierra variant of iso filesystem\n");
 
-       block = inode->i_ino >> bufbits;
+       block = ei->i_iget5_block;
        lock_kernel();
        bh = sb_bread(inode->i_sb, block);
        if (!bh)
                goto out_noread;
 
-       pnt = (unsigned char *) bh->b_data + (inode->i_ino & (bufsize - 1));
+        offset = ei->i_iget5_offset;
+       pnt = (unsigned char *) bh->b_data + offset;
 
        raw_inode = (struct iso_directory_record *) pnt;
 
        /*
         * If we go past the end of the buffer, there is some sort of error.
         */
-       if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize)
+       if (offset + *pnt > bufsize)
                goto out_bad_span;
 
        /* Now test for possible Rock Ridge extensions which will override
index 1c029b2..c1eb3c5 100644 (file)
@@ -412,7 +412,8 @@ write_out_data:
                        tagp = &bh->b_data[sizeof(journal_header_t)];
                        space_left = bh->b_size - sizeof(journal_header_t);
                        first_tag = 1;
-                       set_bit(BH_JWrite, &bh->b_state);
+                       set_buffer_jwrite(bh);
+                       set_buffer_dirty(bh);
                        wbuf[bufs++] = bh;
 
                        /* Record it so that we can wait for IO
@@ -638,7 +639,8 @@ wait_for_iobuf:
        JBUFFER_TRACE(descriptor, "write commit block");
        {
                struct buffer_head *bh = jh2bh(descriptor);
-               set_buffer_uptodate(bh);
+
+               set_buffer_dirty(bh);
                sync_dirty_buffer(bh);
                if (unlikely(!buffer_uptodate(bh)))
                        err = -EIO;
index 4197d47..946eec5 100644 (file)
@@ -619,9 +619,13 @@ int journal_bmap(journal_t *journal, unsigned long blocknr,
  * We play buffer_head aliasing tricks to write data/metadata blocks to
  * the journal without copying their contents, but for journal
  * descriptor blocks we do need to generate bona fide buffers.
+ *
+ * After the caller of journal_get_descriptor_buffer() has finished modifying
+ * the buffer's contents they really should run flush_dcache_page(bh->b_page).
+ * But we don't bother doing that, so there will be coherency problems with
+ * mmaps of blockdevs which hold live JBD-controlled filesystems.
  */
-
-struct journal_head * journal_get_descriptor_buffer(journal_t *journal)
+struct journal_head *journal_get_descriptor_buffer(journal_t *journal)
 {
        struct buffer_head *bh;
        unsigned long blocknr;
@@ -633,8 +637,10 @@ struct journal_head * journal_get_descriptor_buffer(journal_t *journal)
                return NULL;
 
        bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
+       lock_buffer(bh);
        memset(bh->b_data, 0, journal->j_blocksize);
-       bh->b_state |= (1 << BH_Dirty);
+       set_buffer_uptodate(bh);
+       unlock_buffer(bh);
        BUFFER_TRACE(bh, "return this buffer");
        return journal_add_journal_head(bh);
 }
index 1564a48..6bbd736 100644 (file)
@@ -522,7 +522,7 @@ void journal_write_revoke_records(journal_t *journal,
                        kmem_cache_free(revoke_record_cache, record);
                }
        }
-       if (descriptor) 
+       if (descriptor)
                flush_descriptor(journal, descriptor, offset);
        jbd_debug(1, "Wrote %d revoke records\n", count);
 }
@@ -606,7 +606,7 @@ static void flush_descriptor(journal_t *journal,
        header->r_count = htonl(offset);
        set_buffer_jwrite(bh);
        BUFFER_TRACE(bh, "write");
-       set_buffer_uptodate(bh);
+       set_buffer_dirty(bh);
        ll_rw_block(WRITE, 1, &bh);
 }
 #endif
index fe30a98..4d34ba6 100644 (file)
@@ -1582,7 +1582,7 @@ jffs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
                        struct jffs_fmcontrol *fmc = c->fmc;
                        printk("Flash status -- ");
                        if (!access_ok(VERIFY_WRITE,
-                                      (struct jffs_flash_status *)arg,
+                                      (struct jffs_flash_status __user *)arg,
                                       sizeof(struct jffs_flash_status))) {
                                D(printk("jffs_ioctl(): Bad arg in "
                                         "JFFS_GET_STATUS ioctl!\n"));
@@ -1598,7 +1598,7 @@ jffs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
                               "begin: %d, end: %d\n",
                               fst.size, fst.used, fst.dirty,
                               fst.begin, fst.end);
-                       if (copy_to_user((struct jffs_flash_status *)arg,
+                       if (copy_to_user((struct jffs_flash_status __user *)arg,
                                         &fst,
                                         sizeof(struct jffs_flash_status))) {
                                ret = -EFAULT;
index 53c0a6e..ba4fb09 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2001
+ *   Copyright (C) International Business Machines Corp., 2000-2004
  *
  *   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
@@ -108,13 +108,12 @@ struct btpage {
  * record the path traversed during the search;
  * top frame record the leaf page/entry selected.
  */
-#define        MAXTREEHEIGHT           8
 struct btframe {       /* stack frame */
        s64 bn;                 /* 8: */
        s16 index;              /* 2: */
-       s16 lastindex;          /* 2: */
-       struct metapage *mp;    /* 4: */
-};                             /* (16) */
+       s16 lastindex;          /* 2: unused */
+       struct metapage *mp;    /* 4/8: */
+};                             /* (16/24) */
 
 struct btstack {
        struct btframe *top;
@@ -125,12 +124,15 @@ struct btstack {
 #define BT_CLR(btstack)\
        (btstack)->top = (btstack)->stack
 
+#define BT_STACK_FULL(btstack)\
+       ( (btstack)->top == &((btstack)->stack[MAXTREEHEIGHT-1]))
+
 #define BT_PUSH(BTSTACK, BN, INDEX)\
 {\
+       assert(!BT_STACK_FULL(BTSTACK));\
        (BTSTACK)->top->bn = BN;\
        (BTSTACK)->top->index = INDEX;\
        ++(BTSTACK)->top;\
-       assert((BTSTACK)->top != &((BTSTACK)->stack[MAXTREEHEIGHT]));\
 }
 
 #define BT_POP(btstack)\
@@ -139,6 +141,16 @@ struct btstack {
 #define BT_STACK(btstack)\
        ( (btstack)->top == (btstack)->stack ? NULL : (btstack)->top )
 
+static inline void BT_STACK_DUMP(struct btstack *btstack)
+{
+       int i;
+       printk("btstack dump:\n");
+       for (i = 0; i < MAXTREEHEIGHT; i++)
+               printk(KERN_ERR "bn = %Lx, index = %d\n",
+                      btstack->stack[i].bn,
+                      btstack->stack[i].index);
+}
+
 /* retrieve search results */
 #define BT_GETSEARCH(IP, LEAF, BN, MP, TYPE, P, INDEX, ROOT)\
 {\
index 3e9e629..1b55df3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *   Copyright (C) International Business Machines Corp., 2000-2003
+ *   Copyright (C) International Business Machines Corp., 2000-2004
  *
  *   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
@@ -382,7 +382,7 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
        IREAD_LOCK(ipbmap);
 
        /* block to be freed better be within the mapsize. */
-       if (blkno + nblocks > bmp->db_mapsize) {
+       if (unlikely((blkno == 0) || (blkno + nblocks > bmp->db_mapsize))) {
                IREAD_UNLOCK(ipbmap);
                printk(KERN_ERR "blkno = %Lx, nblocks = %Lx\n",
                       (unsigned long long) blkno,
index 1b49bbc..3c3140d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *   Copyright (C) International Business Machines Corp., 2000-2003
+ *   Copyright (C) International Business Machines Corp., 2000-2004
  *
  *   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
@@ -378,6 +378,8 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
                 * It's time to move the inline table to an external
                 * page and begin to build the xtree
                 */
+               if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr))
+                       goto clean_up;  /* No space */
 
                /*
                 * Save the table, we're going to overwrite it with the
@@ -394,8 +396,8 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
                /*
                 * Allocate the first block & add it to the xtree
                 */
-               xaddr = 0;
                if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) {
+                       /* This really shouldn't fail */
                        jfs_warn("add_index: xtInsert failed!");
                        memcpy(&jfs_ip->i_dirtable, temp_table,
                               sizeof (temp_table));
@@ -764,11 +766,12 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
                 */
              getChild:
                /* update max. number of pages to split */
-               if (btstack->nsplit >= 8) {
+               if (BT_STACK_FULL(btstack)) {
                        /* Something's corrupted, mark filesytem dirty so
                         * chkdsk will fix it.
                         */
                        jfs_error(sb, "stack overrun in dtSearch!");
+                       BT_STACK_DUMP(btstack);
                        rc = -EIO;
                        goto out;
                }
@@ -975,8 +978,10 @@ static int dtSplitUp(tid_t tid,
                n -= DTROOTMAXSLOT - sp->header.freecnt; /* header + entries */
                if (n <= split->nslot)
                        xlen++;
-               if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr)))
+               if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr))) {
+                       DT_PUTPAGE(smp);
                        goto freeKeyName;
+               }
 
                pxdlist.maxnpxd = 1;
                pxdlist.npxd = 0;
@@ -3342,6 +3347,12 @@ static int dtReadFirst(struct inode *ip, struct btstack * btstack)
                /*
                 * descend down to leftmost child page
                 */
+               if (BT_STACK_FULL(btstack)) {
+                       DT_PUTPAGE(mp);
+                       jfs_error(ip->i_sb, "dtReadFirst: btstack overrun");
+                       BT_STACK_DUMP(btstack);
+                       return -EIO;
+               }
                /* push (bn, index) of the parent page/entry */
                BT_PUSH(btstack, bn, 0);
 
index 1f3dfbc..8c94bb0 100644 (file)
@@ -239,6 +239,7 @@ again:
                spin_unlock(&meta_lock);
                if (test_bit(META_stale, &mp->flag)) {
                        release_metapage(mp);
+                       yield();        /* Let other waiters release it, too */
                        goto again;
                }
                if (test_bit(META_discard, &mp->flag)) {
index 34b9b80..f48fdea 100644 (file)
@@ -1747,7 +1747,10 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
 
                if (lwm == next)
                        goto out;
-               assert(lwm < next);
+               if (lwm > next) {
+                       jfs_err("xtLog: lwm > next\n");
+                       goto out;
+               }
                tlck->flag |= tlckUPDATEMAP;
                xadlock->flag = mlckALLOCXADLIST;
                xadlock->count = next - lwm;
@@ -1913,25 +1916,18 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                /*
                 *      write log records
                 */
-               /*
-                * allocate entries XAD[lwm:next]:
+               /* log after-image for logredo():
+                *
+                * logredo() will update bmap for alloc of new/extended
+                * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from
+                * after-image of XADlist;
+                * logredo() resets (XAD_NEW|XAD_EXTEND) flag when
+                * applying the after-image to the meta-data page.
                 */
-               if (lwm < next) {
-                       /* log after-image for logredo():
-                        * logredo() will update bmap for alloc of new/extended
-                        * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from
-                        * after-image of XADlist;
-                        * logredo() resets (XAD_NEW|XAD_EXTEND) flag when
-                        * applying the after-image to the meta-data page.
-                        */
-                       lrd->type = cpu_to_le16(LOG_REDOPAGE);
-                       PXDaddress(pxd, mp->index);
-                       PXDlength(pxd,
-                                 mp->logical_size >> tblk->sb->
-                                 s_blocksize_bits);
-                       lrd->backchain =
-                           cpu_to_le32(lmLog(log, tblk, lrd, tlck));
-               }
+               lrd->type = cpu_to_le16(LOG_REDOPAGE);
+               PXDaddress(pxd, mp->index);
+               PXDlength(pxd, mp->logical_size >> tblk->sb->s_blocksize_bits);
+               lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
 
                /*
                 * truncate entry XAD[twm == next - 1]:
@@ -2624,6 +2620,7 @@ void txAbort(tid_t tid, int dirty)
        lid_t lid, next;
        struct metapage *mp;
        struct tblock *tblk = tid_to_tblock(tid);
+       struct tlock *tlck;
 
        jfs_warn("txAbort: tid:%d dirty:0x%x", tid, dirty);
 
@@ -2631,9 +2628,10 @@ void txAbort(tid_t tid, int dirty)
         * free tlocks of the transaction
         */
        for (lid = tblk->next; lid; lid = next) {
-               next = lid_to_tlock(lid)->next;
-
-               mp = lid_to_tlock(lid)->mp;
+               tlck = lid_to_tlock(lid);
+               next = tlck->next;
+               mp = tlck->mp;
+               JFS_IP(tlck->ip)->xtlid = 0;
 
                if (mp) {
                        mp->lid = 0;
index 87ecbab..3fefbf0 100644 (file)
@@ -113,11 +113,12 @@ typedef struct {
 #define        addressPXD(pxd)\
        ( ((s64)((pxd)->addr1)) << 32 | __le32_to_cpu((pxd)->addr2))
 
+#define MAXTREEHEIGHT 8
 /* pxd list */
 struct pxdlist {
        s16 maxnpxd;
        s16 npxd;
-       pxd_t pxd[8];
+       pxd_t pxd[MAXTREEHEIGHT];
 };
 
 
index c5b789e..998410c 100644 (file)
@@ -858,7 +858,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
        unchar *i_fastsymlink;
        s64 xlen = 0;
        int bmask = 0, xsize;
-       s64 xaddr;
+       s64 extent = 0, xaddr;
        struct metapage *mp;
        struct super_block *sb;
        struct tblock *tblk;
@@ -892,29 +892,11 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
        down(&JFS_IP(dip)->commit_sem);
        down(&JFS_IP(ip)->commit_sem);
 
-       if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE)))
-               goto out3;
-
        tblk = tid_to_tblock(tid);
        tblk->xflag |= COMMIT_CREATE;
        tblk->ino = ip->i_ino;
        tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
 
-       /*
-        * create entry for symbolic link in parent directory
-        */
-
-       ino = ip->i_ino;
-
-
-
-       if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
-               jfs_err("jfs_symlink: dtInsert returned %d", rc);
-               /* discard ne inode */
-               goto out3;
-
-       }
-
        /* fix symlink access permission
         * (dir_create() ANDs in the u.u_cmask, 
         * but symlinks really need to be 777 access)
@@ -922,7 +904,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
        ip->i_mode |= 0777;
 
        /*
-          *       write symbolic link target path name
+        * write symbolic link target path name
         */
        xtInitRoot(tid, ip);
 
@@ -966,37 +948,48 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
                xsize = (ssize + bmask) & ~bmask;
                xaddr = 0;
                xlen = xsize >> JFS_SBI(sb)->l2bsize;
-               if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0)) == 0) {
-                       ip->i_size = ssize - 1;
-                       while (ssize) {
-                               int copy_size = min(ssize, PSIZE);
-
-                               mp = get_metapage(ip, xaddr, PSIZE, 1);
-
-                               if (mp == NULL) {
-                                       dtDelete(tid, dip, &dname, &ino,
-                                                JFS_REMOVE);
-                                       rc = -EIO;
-                                       goto out3;
-                               }
-                               memcpy(mp->data, name, copy_size);
-                               flush_metapage(mp);
-#if 0
-                               set_buffer_uptodate(bp);
-                               mark_buffer_dirty(bp, 1);
-                               if (IS_SYNC(dip))
-                                       sync_dirty_buffer(bp);
-                               brelse(bp);
-#endif                         /* 0 */
-                               ssize -= copy_size;
-                               xaddr += JFS_SBI(sb)->nbperpage;
-                       }
-                       ip->i_blocks = LBLK2PBLK(sb, xlen);
-               } else {
-                       dtDelete(tid, dip, &dname, &ino, JFS_REMOVE);
+               if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0))) {
+                       txAbort(tid, 0);
                        rc = -ENOSPC;
                        goto out3;
                }
+               extent = xaddr;
+               ip->i_size = ssize - 1;
+               while (ssize) {
+                       /* This is kind of silly since PATH_MAX == 4K */
+                       int copy_size = min(ssize, PSIZE);
+
+                       mp = get_metapage(ip, xaddr, PSIZE, 1);
+
+                       if (mp == NULL) {
+                               dbFree(ip, extent, xlen);
+                               rc = -EIO;
+                               txAbort(tid, 0);
+                               goto out3;
+                       }
+                       memcpy(mp->data, name, copy_size);
+                       flush_metapage(mp);
+                       ssize -= copy_size;
+                       name += copy_size;
+                       xaddr += JFS_SBI(sb)->nbperpage;
+               }
+               ip->i_blocks = LBLK2PBLK(sb, xlen);
+       }
+
+       /*
+        * create entry for symbolic link in parent directory
+        */
+       rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE);
+       if (rc == 0) {
+               ino = ip->i_ino;
+               rc = dtInsert(tid, dip, &dname, &ino, &btstack);
+       }
+       if (rc) {
+               if (xlen)
+                       dbFree(ip, extent, xlen);
+               txAbort(tid, 0);
+               /* discard new inode */
+               goto out3;
        }
 
        insert_inode_hash(ip);
@@ -1004,23 +997,11 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
 
        /*
         * commit update of parent directory and link object
-        *
-        * if extent allocation failed (ENOSPC),
-        * the parent inode is committed regardless to avoid
-        * backing out parent directory update (by dtInsert())
-        * and subsequent dtDelete() which is harmless wrt 
-        * integrity concern.  
-        * the symlink inode will be freed by iput() at exit
-        * as it has a zero link count (by dtDelete()) and 
-        * no permanant resources. 
         */
 
        iplist[0] = dip;
-       if (rc == 0) {
-               iplist[1] = ip;
-               rc = txCommit(tid, 2, &iplist[0], 0);
-       } else
-               rc = txCommit(tid, 1, &iplist[0], 0);
+       iplist[1] = ip;
+       rc = txCommit(tid, 2, &iplist[0], 0);
 
       out3:
        txEnd(tid);
@@ -1223,7 +1204,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                        /* Linelock header of dtree */
                        tlck = txLock(tid, old_ip,
                                    (struct metapage *) &JFS_IP(old_ip)->bxflag,
-                                     tlckDTREE | tlckBTROOT);
+                                     tlckDTREE | tlckBTROOT | tlckRELINK);
                        dtlck = (struct dt_lock *) & tlck->lock;
                        ASSERT(dtlck->index == 0);
                        lv = & dtlck->lv[0];
index ad74981..c786348 100644 (file)
@@ -688,17 +688,26 @@ static int can_set_system_xattr(struct inode *inode, const char *name,
                        }
                        inode->i_mode = mode;
                        mark_inode_dirty(inode);
-                       if (rc == 0)
-                               value = NULL;
                }
                /*
                 * We're changing the ACL.  Get rid of the cached one
                 */
                acl =JFS_IP(inode)->i_acl;
-               if (acl && (acl != JFS_ACL_NOT_CACHED))
+               if (acl != JFS_ACL_NOT_CACHED)
                        posix_acl_release(acl);
                JFS_IP(inode)->i_acl = JFS_ACL_NOT_CACHED;
+
+               return 0;
        } else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) {
+               acl = posix_acl_from_xattr(value, value_len);
+               if (IS_ERR(acl)) {
+                       rc = PTR_ERR(acl);
+                       printk(KERN_ERR "posix_acl_from_xattr returned %d\n",
+                              rc);
+                       return rc;
+               }
+               posix_acl_release(acl);
+
                /*
                 * We're changing the default ACL.  Get rid of the cached one
                 */
@@ -706,13 +715,11 @@ static int can_set_system_xattr(struct inode *inode, const char *name,
                if (acl && (acl != JFS_ACL_NOT_CACHED))
                        posix_acl_release(acl);
                JFS_IP(inode)->i_default_acl = JFS_ACL_NOT_CACHED;
-       } else
-               /* Invalid xattr name */
-               return -EINVAL;
-       return 0;
-#else                  /* CONFIG_JFS_POSIX_ACL */
-       return -EOPNOTSUPP;
+
+               return 0;
+       }
 #endif                 /* CONFIG_JFS_POSIX_ACL */
+       return -EOPNOTSUPP;
 }
 
 static int can_set_xattr(struct inode *inode, const char *name,
index 9184fbb..cfb6c29 100644 (file)
@@ -762,12 +762,12 @@ ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir,
 int ncp_conn_logged_in(struct super_block *sb)
 {
        struct ncp_server* server = NCP_SBP(sb);
-       struct nw_info_struct i;
        int result;
 
        if (ncp_single_volume(server)) {
                int len;
                struct dentry* dent;
+               __u32 volNumber, dirEntNum, DosDirNum;
                __u8 __name[NCP_MAXPATHLEN + 1];
 
                len = sizeof(__name);
@@ -776,7 +776,7 @@ int ncp_conn_logged_in(struct super_block *sb)
                if (result)
                        goto out;
                result = -ENOENT;
-               if (ncp_lookup_volume(server, __name, &i)) {
+               if (ncp_get_volume_root(server, __name, &volNumber, &dirEntNum, &DosDirNum)) {
                        PPRINTK("ncp_conn_logged_in: %s not found\n",
                                server->m.mounted_vol);
                        goto out;
@@ -785,9 +785,9 @@ int ncp_conn_logged_in(struct super_block *sb)
                if (dent) {
                        struct inode* ino = dent->d_inode;
                        if (ino) {
-                               NCP_FINFO(ino)->volNumber = i.volNumber;
-                               NCP_FINFO(ino)->dirEntNum = i.dirEntNum;
-                               NCP_FINFO(ino)->DosDirNum = i.DosDirNum;
+                               NCP_FINFO(ino)->volNumber = volNumber;
+                               NCP_FINFO(ino)->dirEntNum = dirEntNum;
+                               NCP_FINFO(ino)->DosDirNum = DosDirNum;
                        } else {
                                DPRINTK("ncpfs: sb->s_root->d_inode == NULL!\n");
                        }
index e4406a5..c1745b6 100644 (file)
@@ -99,7 +99,7 @@ out:
 }
 
 static ssize_t
-ncp_file_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+ncp_file_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
        struct dentry *dentry = file->f_dentry;
        struct inode *inode = dentry->d_inode;
@@ -187,7 +187,7 @@ outrel:
 }
 
 static ssize_t
-ncp_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
        struct dentry *dentry = file->f_dentry;
        struct inode *inode = dentry->d_inode;
index a25f957..6a35315 100644 (file)
 /* maximum negotiable packet size */
 #define NCP_PACKET_SIZE_INTERNAL 65536
 
+static int
+ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_info* arg)
+{
+       struct ncp_fs_info info;
+
+       if ((permission(inode, MAY_WRITE, NULL) != 0)
+           && (current->uid != server->m.mounted_uid)) {
+               return -EACCES;
+       }
+       if (copy_from_user(&info, arg, sizeof(info)))
+               return -EFAULT;
+
+       if (info.version != NCP_GET_FS_INFO_VERSION) {
+               DPRINTK("info.version invalid: %d\n", info.version);
+               return -EINVAL;
+       }
+       /* TODO: info.addr = server->m.serv_addr; */
+       SET_UID(info.mounted_uid, server->m.mounted_uid);
+       info.connection         = server->connection;
+       info.buffer_size        = server->buffer_size;
+       info.volume_number      = NCP_FINFO(inode)->volNumber;
+       info.directory_id       = NCP_FINFO(inode)->DosDirNum;
+
+       if (copy_to_user(arg, &info, sizeof(info)))
+               return -EFAULT;
+       return 0;
+}
+
+static int
+ncp_get_fs_info_v2(struct ncp_server* server, struct inode* inode, struct ncp_fs_info_v2* arg)
+{
+       struct ncp_fs_info_v2 info2;
+
+       if ((permission(inode, MAY_WRITE, NULL) != 0)
+           && (current->uid != server->m.mounted_uid)) {
+               return -EACCES;
+       }
+       if (copy_from_user(&info2, arg, sizeof(info2)))
+               return -EFAULT;
+
+       if (info2.version != NCP_GET_FS_INFO_VERSION_V2) {
+               DPRINTK("info.version invalid: %d\n", info2.version);
+               return -EINVAL;
+       }
+       info2.mounted_uid   = server->m.mounted_uid;
+       info2.connection    = server->connection;
+       info2.buffer_size   = server->buffer_size;
+       info2.volume_number = NCP_FINFO(inode)->volNumber;
+       info2.directory_id  = NCP_FINFO(inode)->DosDirNum;
+       info2.dummy1 = info2.dummy2 = info2.dummy3 = 0;
+
+       if (copy_to_user(arg, &info2, sizeof(info2)))
+               return -EFAULT;
+       return 0;
+}
+
+#ifdef CONFIG_NCPFS_NLS
+/* Here we are select the iocharset and the codepage for NLS.
+ * Thanks Petr Vandrovec for idea and many hints.
+ */
+static int
+ncp_set_charsets(struct ncp_server* server, struct ncp_nls_ioctl* arg)
+{
+       struct ncp_nls_ioctl user;
+       struct nls_table *codepage;
+       struct nls_table *iocharset;
+       struct nls_table *oldset_io;
+       struct nls_table *oldset_cp;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EACCES;
+       if (server->root_setuped)
+               return -EBUSY;
+
+       if (copy_from_user(&user, arg, sizeof(user)))
+               return -EFAULT;
+
+       codepage = NULL;
+       user.codepage[NCP_IOCSNAME_LEN] = 0;
+       if (!user.codepage[0] || !strcmp(user.codepage, "default"))
+               codepage = load_nls_default();
+       else {
+               codepage = load_nls(user.codepage);
+               if (!codepage) {
+                       return -EBADRQC;
+               }
+       }
+
+       iocharset = NULL;
+       user.iocharset[NCP_IOCSNAME_LEN] = 0;
+       if (!user.iocharset[0] || !strcmp(user.iocharset, "default")) {
+               iocharset = load_nls_default();
+               NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
+       } else if (!strcmp(user.iocharset, "utf8")) {
+               iocharset = load_nls_default();
+               NCP_SET_FLAG(server, NCP_FLAG_UTF8);
+       } else {
+               iocharset = load_nls(user.iocharset);
+               if (!iocharset) {
+                       unload_nls(codepage);
+                       return -EBADRQC;
+               }
+               NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
+       }
+
+       oldset_cp = server->nls_vol;
+       server->nls_vol = codepage;
+       oldset_io = server->nls_io;
+       server->nls_io = iocharset;
+
+       if (oldset_cp)
+               unload_nls(oldset_cp);
+       if (oldset_io)
+               unload_nls(oldset_io);
+
+       return 0;
+}
+
+static int
+ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl* arg)
+{
+       struct ncp_nls_ioctl user;
+       int len;
+
+       memset(&user, 0, sizeof(user));
+       if (server->nls_vol && server->nls_vol->charset) {
+               len = strlen(server->nls_vol->charset);
+               if (len > NCP_IOCSNAME_LEN)
+                       len = NCP_IOCSNAME_LEN;
+               strncpy(user.codepage, server->nls_vol->charset, len);
+               user.codepage[len] = 0;
+       }
+
+       if (NCP_IS_FLAG(server, NCP_FLAG_UTF8))
+               strcpy(user.iocharset, "utf8");
+       else if (server->nls_io && server->nls_io->charset) {
+               len = strlen(server->nls_io->charset);
+               if (len > NCP_IOCSNAME_LEN)
+                       len = NCP_IOCSNAME_LEN;
+               strncpy(user.iocharset, server->nls_io->charset, len);
+               user.iocharset[len] = 0;
+       }
+
+       if (copy_to_user(arg, &user, sizeof(user)))
+               return -EFAULT;
+       return 0;
+}
+#endif /* CONFIG_NCPFS_NLS */
+
 int ncp_ioctl(struct inode *inode, struct file *filp,
              unsigned int cmd, unsigned long arg)
 {
@@ -96,60 +245,10 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
                return ncp_conn_logged_in(inode->i_sb);
 
        case NCP_IOC_GET_FS_INFO:
-               {
-                       struct ncp_fs_info info;
-
-                       if ((permission(inode, MAY_WRITE, NULL) != 0)
-                           && (current->uid != server->m.mounted_uid)) {
-                               return -EACCES;
-                       }
-                       if (copy_from_user(&info, (struct ncp_fs_info *) arg, 
-                               sizeof(info)))
-                               return -EFAULT;
-
-                       if (info.version != NCP_GET_FS_INFO_VERSION) {
-                               DPRINTK("info.version invalid: %d\n", info.version);
-                               return -EINVAL;
-                       }
-                       /* TODO: info.addr = server->m.serv_addr; */
-                       SET_UID(info.mounted_uid, server->m.mounted_uid);
-                       info.connection         = server->connection;
-                       info.buffer_size        = server->buffer_size;
-                       info.volume_number      = NCP_FINFO(inode)->volNumber;
-                       info.directory_id       = NCP_FINFO(inode)->DosDirNum;
-
-                       if (copy_to_user((struct ncp_fs_info *) arg, &info, 
-                               sizeof(info))) return -EFAULT;
-                       return 0;
-               }
+               return ncp_get_fs_info(server, inode, (struct ncp_fs_info *)arg);
 
        case NCP_IOC_GET_FS_INFO_V2:
-               {
-                       struct ncp_fs_info_v2 info2;
-
-                       if ((permission(inode, MAY_WRITE, NULL) != 0)
-                           && (current->uid != server->m.mounted_uid)) {
-                               return -EACCES;
-                       }
-                       if (copy_from_user(&info2, (struct ncp_fs_info_v2 *) arg, 
-                               sizeof(info2)))
-                               return -EFAULT;
-
-                       if (info2.version != NCP_GET_FS_INFO_VERSION_V2) {
-                               DPRINTK("info.version invalid: %d\n", info2.version);
-                               return -EINVAL;
-                       }
-                       info2.mounted_uid   = server->m.mounted_uid;
-                       info2.connection    = server->connection;
-                       info2.buffer_size   = server->buffer_size;
-                       info2.volume_number = NCP_FINFO(inode)->volNumber;
-                       info2.directory_id  = NCP_FINFO(inode)->DosDirNum;
-                       info2.dummy1 = info2.dummy2 = info2.dummy3 = 0;
-
-                       if (copy_to_user((struct ncp_fs_info_v2 *) arg, &info2, 
-                               sizeof(info2))) return -EFAULT;
-                       return 0;
-               }
+               return ncp_get_fs_info_v2(server, inode, (struct ncp_fs_info_v2 *)arg);
 
        case NCP_IOC_GETMOUNTUID2:
                {
@@ -201,7 +300,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
        case NCP_IOC_SETROOT:
                {
                        struct ncp_setroot_ioctl sr;
-                       unsigned int vnum, de, dosde;
+                       __u32 vnum, de, dosde;
                        struct dentry* dentry;
 
                        if (!capable(CAP_SYS_ADMIN))
@@ -219,15 +318,10 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
                                dosde = 0;
                        } else if (sr.volNumber >= NCP_NUMBER_OF_VOLUMES) {
                                return -EINVAL;
-                       } else {
-                               struct nw_info_struct ni;
-                               
-                               if (ncp_mount_subdir(server, &ni, sr.volNumber,
-                                               sr.namespace, sr.dirEntNum))
-                                       return -ENOENT;
-                               vnum = ni.volNumber;
-                               de = ni.dirEntNum;
-                               dosde = ni.DosDirNum;
+                       } else if (ncp_mount_subdir(server, sr.volNumber,
+                                               sr.namespace, sr.dirEntNum,
+                                               &vnum, &de, &dosde)) {
+                               return -ENOENT;
                        }
                        
                        dentry = inode->i_sb->s_root;
@@ -508,105 +602,14 @@ outrel:
                }
 
 #ifdef CONFIG_NCPFS_NLS
-/* Here we are select the iocharset and the codepage for NLS.
- * Thanks Petr Vandrovec for idea and many hints.
- */
        case NCP_IOC_SETCHARSETS:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EACCES;
-               if (server->root_setuped)
-                       return -EBUSY;
-
-               {
-                       struct ncp_nls_ioctl user;
-                       struct nls_table *codepage;
-                       struct nls_table *iocharset;
-                       struct nls_table *oldset_io;
-                       struct nls_table *oldset_cp;
-                       
-                       if (copy_from_user(&user, (struct ncp_nls_ioctl*)arg,
-                                       sizeof(user)))
-                               return -EFAULT;
-
-                       codepage = NULL;
-                       user.codepage[NCP_IOCSNAME_LEN] = 0;
-                       if (!user.codepage[0] ||
-                                       !strcmp(user.codepage, "default"))
-                               codepage = load_nls_default();
-                       else {
-                               codepage = load_nls(user.codepage);
-                               if (!codepage) {
-                                       return -EBADRQC;
-                               }
-                       }
-
-                       iocharset = NULL;
-                       user.iocharset[NCP_IOCSNAME_LEN] = 0;
-                       if (!user.iocharset[0] ||
-                                       !strcmp(user.iocharset, "default")) {
-                               iocharset = load_nls_default();
-                               NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
-                       } else {
-                               if (!strcmp(user.iocharset, "utf8")) {
-                                       iocharset = load_nls_default();
-                                       NCP_SET_FLAG(server, NCP_FLAG_UTF8);
-                               } else {
-                                       iocharset = load_nls(user.iocharset);
-                                       if (!iocharset) {
-                                               unload_nls(codepage);
-                                               return -EBADRQC;
-                                       }
-                                       NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
-                               }
-                       }
-
-                       oldset_cp = server->nls_vol;
-                       server->nls_vol = codepage;
-                       oldset_io = server->nls_io;
-                       server->nls_io = iocharset;
-
-                       if (oldset_cp)
-                               unload_nls(oldset_cp);
-                       if (oldset_io)
-                               unload_nls(oldset_io);
-
-                       return 0;
-               }
+               return ncp_set_charsets(server, (struct ncp_nls_ioctl *)arg);
                
-       case NCP_IOC_GETCHARSETS: /* not tested */
-               {
-                       struct ncp_nls_ioctl user;
-                       int len;
-
-                       memset(&user, 0, sizeof(user));
-                       if (server->nls_vol && server->nls_vol->charset) {
-                               len = strlen(server->nls_vol->charset);
-                               if (len > NCP_IOCSNAME_LEN)
-                                       len = NCP_IOCSNAME_LEN;
-                               strncpy(user.codepage,
-                                               server->nls_vol->charset, len);
-                               user.codepage[len] = 0;
-                       }
-
-                       if (NCP_IS_FLAG(server, NCP_FLAG_UTF8))
-                               strcpy(user.iocharset, "utf8");
-                       else
-                               if (server->nls_io && server->nls_io->charset) {
-                                       len = strlen(server->nls_io->charset);
-                                       if (len > NCP_IOCSNAME_LEN)
-                                               len = NCP_IOCSNAME_LEN;
-                                       strncpy(user.iocharset,
-                                               server->nls_io->charset, len);
-                                       user.iocharset[len] = 0;
-                               }
+       case NCP_IOC_GETCHARSETS:
+               return ncp_get_charsets(server, (struct ncp_nls_ioctl *)arg);
 
-                       if (copy_to_user((struct ncp_nls_ioctl*)arg, &user,
-                                       sizeof(user)))
-                               return -EFAULT;
-
-                       return 0;
-               }
 #endif /* CONFIG_NCPFS_NLS */
+
        case NCP_IOC_SETDENTRYTTL:
                if ((permission(inode, MAY_WRITE, NULL) != 0) &&
                                 (current->uid != server->m.mounted_uid))
index 3452706..ad99ac0 100644 (file)
@@ -536,37 +536,34 @@ ncp_ObtainSpecificDirBase(struct ncp_server *server,
 }
 
 int
-ncp_mount_subdir(struct ncp_server *server, struct nw_info_struct *i,
-                       __u8 volNumber, __u8 srcNS, __u32 dirEntNum)
+ncp_mount_subdir(struct ncp_server *server,
+                __u8 volNumber, __u8 srcNS, __u32 dirEntNum,
+                __u32* volume, __u32* newDirEnt, __u32* newDosEnt)
 {
        int dstNS;
        int result;
-       __u32 newDirEnt;
-       __u32 newDosEnt;
        
        dstNS = ncp_get_known_namespace(server, volNumber);
        if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber, 
-                                     dirEntNum, NULL, &newDirEnt, &newDosEnt)) != 0)
+                                     dirEntNum, NULL, newDirEnt, newDosEnt)) != 0)
        {
                return result;
        }
        server->name_space[volNumber] = dstNS;
-       i->volNumber = volNumber;
-       i->dirEntNum = newDirEnt;
-       i->DosDirNum = newDosEnt;
+       *volume = volNumber;
        server->m.mounted_vol[1] = 0;
        server->m.mounted_vol[0] = 'X';
        return 0;
 }
 
 int 
-ncp_lookup_volume(struct ncp_server *server, char *volname,
-                     struct nw_info_struct *target)
+ncp_get_volume_root(struct ncp_server *server, const char *volname,
+                   __u32* volume, __u32* dirent, __u32* dosdirent)
 {
        int result;
-       int volnum;
+       __u8 volnum;
 
-       DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
+       DPRINTK("ncp_get_volume_root: looking up vol %s\n", volname);
 
        ncp_init_request(server);
        ncp_add_byte(server, 22);       /* Subfunction: Generate dir handle */
@@ -585,16 +582,31 @@ ncp_lookup_volume(struct ncp_server *server, char *volname,
                ncp_unlock_server(server);
                return result;
        }
-       memset(target, 0, sizeof(*target));
-       target->DosDirNum = target->dirEntNum = ncp_reply_dword(server, 4);
-       target->volNumber = volnum = ncp_reply_byte(server, 8);
+       *dirent = *dosdirent = ncp_reply_dword(server, 4);
+       volnum = ncp_reply_byte(server, 8);
        ncp_unlock_server(server);
+       *volume = volnum;
 
        server->name_space[volnum] = ncp_get_known_namespace(server, volnum);
 
        DPRINTK("lookup_vol: namespace[%d] = %d\n",
                volnum, server->name_space[volnum]);
 
+       return 0;
+}
+
+int
+ncp_lookup_volume(struct ncp_server *server, const char *volname,
+                 struct nw_info_struct *target)
+{
+       int result;
+
+       memset(target, 0, sizeof(*target));
+       result = ncp_get_volume_root(server, volname,
+                       &target->volNumber, &target->dirEntNum, &target->DosDirNum);
+       if (result) {
+               return result;
+       }
        target->nameLen = strlen(volname);
        memcpy(target->entryName, volname, target->nameLen+1);
        target->attributes = aDIR;
@@ -1002,7 +1014,7 @@ out:
  */
 int
 ncp_read_bounce(struct ncp_server *server, const char *file_id,
-        __u32 offset, __u16 to_read, char *target, int *bytes_read,
+        __u32 offset, __u16 to_read, char __user *target, int *bytes_read,
         void* bounce, __u32 bufsize)
 {
        int result;
index c702f3b..7edb9e1 100644 (file)
@@ -56,7 +56,7 @@ static inline int ncp_read_bounce_size(__u32 size) {
        return sizeof(struct ncp_reply_header) + 2 + 2 + size + 8;
 };
 int ncp_read_bounce(struct ncp_server *, const char *, __u32, __u16, 
-               char *, int *, void* bounce, __u32 bouncelen);
+               char __user *, int *, void* bounce, __u32 bouncelen);
 int ncp_read_kernel(struct ncp_server *, const char *, __u32, __u16, 
                char *, int *);
 int ncp_write_kernel(struct ncp_server *, const char *, __u32, __u16,
@@ -70,7 +70,9 @@ void ncp_extract_file_info(void* src, struct nw_info_struct* target);
 int ncp_obtain_info(struct ncp_server *server, struct inode *, char *,
                struct nw_info_struct *target);
 int ncp_obtain_nfs_info(struct ncp_server *server, struct nw_info_struct *target);
-int ncp_lookup_volume(struct ncp_server *, char *, struct nw_info_struct *);
+int ncp_get_volume_root(struct ncp_server *server, const char *volname,
+                       __u32 *volume, __u32 *dirent, __u32 *dosdirent);
+int ncp_lookup_volume(struct ncp_server *, const char *, struct nw_info_struct *);
 int ncp_modify_file_or_subdir_dos_info(struct ncp_server *, struct inode *,
         __u32, const struct nw_modify_dos_info *info);
 int ncp_modify_file_or_subdir_dos_info_path(struct ncp_server *, struct inode *,
@@ -111,8 +113,8 @@ ncp_ClearPhysicalRecord(struct ncp_server *server,
 #endif /* CONFIG_NCPFS_IOCTL_LOCKING */
 
 int
-ncp_mount_subdir(struct ncp_server *, struct nw_info_struct *,
-                       __u8, __u8, __u32);
+ncp_mount_subdir(struct ncp_server *, __u8, __u8, __u32,
+                __u32* volume, __u32* dirent, __u32* dosdirent);
 int ncp_dirhandle_alloc(struct ncp_server *, __u8 vol, __u32 dirent, __u8 *dirhandle);
 int ncp_dirhandle_free(struct ncp_server *, __u8 dirhandle);
 
index b8018d5..e4e228e 100644 (file)
@@ -466,7 +466,7 @@ nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
  * cache.
  */
 ssize_t
-nfs_file_direct_read(struct kiocb *iocb, char *buf, size_t count, loff_t pos)
+nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
 {
        ssize_t retval = -EINVAL;
        loff_t *ppos = &iocb->ki_pos;
@@ -546,7 +546,7 @@ nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count,
        struct address_space *mapping = file->f_mapping;
        struct inode *inode = mapping->host;
        struct iovec iov = {
-               .iov_base = buf,
+               .iov_base = (char __user *)buf,
                .iov_len = count,
        };
 
index 1d5d8a9..b74c4e3 100644 (file)
@@ -75,9 +75,10 @@ struct idmap {
        struct idmap_hashtable idmap_group_hash;
 };
 
-static ssize_t   idmap_pipe_upcall(struct file *, struct rpc_pipe_msg *, char *,
-                     size_t);
-static ssize_t   idmap_pipe_downcall(struct file *, const char *, size_t);
+static ssize_t   idmap_pipe_upcall(struct file *, struct rpc_pipe_msg *,
+                    char __user *, size_t);
+static ssize_t   idmap_pipe_downcall(struct file *, const char __user *,
+                    size_t);
 void             idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
 
 static unsigned int fnvhash32(const void *, size_t);
@@ -332,7 +333,7 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h,
 /* RPC pipefs upcall/downcall routines */
 static ssize_t
 idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
-    char *dst, size_t buflen)
+    char __user *dst, size_t buflen)
 {
         char *data = (char *)msg->data + msg->copied;
         ssize_t mlen = msg->len - msg->copied;
@@ -353,7 +354,7 @@ idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
 }
 
 static ssize_t
-idmap_pipe_downcall(struct file *filp, const char *src, size_t mlen)
+idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
 {
         struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode);
        struct idmap *idmap = (struct idmap *)rpci->private;
index 483e831..a01a2fa 100644 (file)
@@ -314,7 +314,7 @@ do_it:
                if (err >= 0) {
                        err = 0;
                        if (wbc->for_reclaim)
-                               err = WRITEPAGE_ACTIVATE;
+                               nfs_flush_inode(inode, 0, 0, FLUSH_STABLE);
                }
        } else {
                err = nfs_writepage_sync(NULL, inode, page, 0,
@@ -327,8 +327,7 @@ do_it:
        }
        unlock_kernel();
 out:
-       if (err != WRITEPAGE_ACTIVATE)
-               unlock_page(page);
+       unlock_page(page);
        if (inode_referenced)
                iput(inode);
        return err; 
index 1541cbb..941ceae 100644 (file)
@@ -436,7 +436,6 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
        resp->buflen = count;
        resp->common.err = nfs_ok;
        resp->buffer = argp->buffer;
-       resp->offset = NULL;
        resp->rqstp = rqstp;
        nfserr = nfsd_readdir(rqstp, &resp->fh, (loff_t*) &argp->cookie, 
                                        &resp->common, nfs3svc_encode_entry);
index 1e3af06..f5df830 100644 (file)
@@ -847,8 +847,18 @@ encode_entry(struct readdir_cd *ccd, const char *name,
        int             elen;           /* estimated entry length in words */
        int             num_entry_words = 0;    /* actual number of words */
 
-       if (cd->offset)
-               xdr_encode_hyper(cd->offset, (u64) offset);
+       if (cd->offset) {
+               u64 offset64 = offset;
+
+               if (unlikely(cd->offset1)) {
+                       /* we ended up with offset on a page boundary */
+                       *cd->offset = htonl(offset64 >> 32);
+                       *cd->offset1 = htonl(offset64 & 0xffffffff);
+                       cd->offset1 = NULL;
+               } else {
+                       xdr_encode_hyper(cd->offset, (u64) offset);
+               }
+       }
 
        /*
        dprintk("encode_entry(%.*s @%ld%s)\n",
@@ -929,17 +939,32 @@ encode_entry(struct readdir_cd *ccd, const char *name,
                        /* update offset */
                        cd->offset = cd->buffer + (cd->offset - tmp);
                } else {
+                       unsigned int offset_r = (cd->offset - tmp) << 2;
+
+                       /* update pointer to offset location.
+                        * This is a 64bit quantity, so we need to
+                        * deal with 3 cases:
+                        *  -   entirely in first page
+                        *  -   entirely in second page
+                        *  -   4 bytes in each page
+                        */
+                       if (offset_r + 8 <= len1) {
+                               cd->offset = p + (cd->offset - tmp);
+                       } else if (offset_r >= len1) {
+                               cd->offset -= len1 >> 2;
+                       } else {
+                               /* sitting on the fence */
+                               BUG_ON(offset_r != len1 - 4);
+                               cd->offset = p + (cd->offset - tmp);
+                               cd->offset1 = tmp;
+                       }
+
                        len2 = (num_entry_words << 2) - len1;
 
                        /* move from temp page to current and next pages */
                        memmove(p, tmp, len1);
                        memmove(tmp, (caddr_t)tmp+len1, len2);
 
-                       /* update offset */
-                       if (((cd->offset - tmp) << 2) < len1)
-                               cd->offset = p + (cd->offset - tmp);
-                       else
-                               cd->offset -= len1 >> 2;
                        p = tmp + (len2 >> 2);
                }
        }
index d8765a0..d54c85a 100644 (file)
@@ -389,7 +389,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre
                break;
 
        default:
-               BUG();
+               status = nfserr_badtype;
        }
 
        if (!status) {
index 73a8944..848c485 100644 (file)
@@ -495,15 +495,13 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
                gen_clid(new);
                gen_confirm(new);
                add_to_unconfirmed(new, strhashval);
-       } else if (!cmp_clid(&conf->cl_clientid, &unconf->cl_clientid) &&
-             !cmp_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
+       } else if (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
                /*      
                 * CASE3:
                 * confirmed found (name, principal match)
                 * confirmed verifier does not match input clverifier
                 *
                 * unconfirmed found (name match)
-                * confirmed->cl_clientid != unconfirmed->cl_clientid and
                 * confirmed->cl_confirm != unconfirmed->cl_confirm
                 *
                 * remove unconfirmed.
@@ -2334,28 +2332,27 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *
 
        /* find the lockowner */
         status = nfs_ok;
-       for (i=0; i < LOCK_HASH_SIZE; i++) {
-               list_for_each_entry(local, &lock_ownerstr_hashtbl[i], so_strhash) {
-                       if(cmp_owner_str(local, owner, clid))
-                               break;
-               }
-       }
-       if (local) {
-               struct nfs4_stateid *stp;
-
-               /* check for any locks held by any stateid associated with the
-                * (lock) stateowner */
-               status = nfserr_locks_held;
-               list_for_each_entry(stp, &local->so_perfilestate, st_perfilestate) {
-                       if(stp->st_vfs_set) {
-                               if (check_for_locks(&stp->st_vfs_file, local))
-                                       goto out;
+       for (i=0; i < LOCK_HASH_SIZE; i++)
+               list_for_each_entry(local, &lock_ownerstr_hashtbl[i], so_strhash)
+                       if(cmp_owner_str(local, owner, clid)) {
+                               struct nfs4_stateid *stp;
+
+                               /* check for any locks held by any stateid
+                                * associated with the (lock) stateowner */
+                               status = nfserr_locks_held;
+                               list_for_each_entry(stp, &local->so_perfilestate,
+                                                   st_perfilestate) {
+                                       if(stp->st_vfs_set) {
+                                               if (check_for_locks(&stp->st_vfs_file,
+                                                                   local))
+                                                       goto out;
+                                       }
+                               }
+                               /* no locks held by (lock) stateowner */
+                               status = nfs_ok;
+                               release_stateowner(local);
+                               goto out;
                        }
-               }
-               /* no locks held by (lock) stateowner */
-               status = nfs_ok;
-               release_stateowner(local);
-       }
 out:
        nfs4_unlock_state();
        return status;
index bb0c72f..2fc81bc 100644 (file)
@@ -538,9 +538,8 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
        case NF4SOCK:
        case NF4FIFO:
        case NF4DIR:
-               break;
        default:
-               goto xdr_error;
+               break;
        }
 
        READ_BUF(4);
@@ -1289,6 +1288,49 @@ static u32 nfs4_ftypes[16] = {
         NF4SOCK, NF4BAD,  NF4LNK, NF4BAD,
 };
 
+static inline int
+xdr_padding(int l)
+{
+       return 3 - ((l - 1) & 3); /* smallest i>=0 such that (l+i)%4 = 0 */
+}
+
+static int
+nfsd4_encode_name(struct svc_rqst *rqstp, int group, uid_t id,
+                       u32 **p, int *buflen)
+{
+       int status;
+       u32 len;
+
+       if (*buflen < (XDR_QUADLEN(IDMAP_NAMESZ) << 2) + 4)
+               return nfserr_resource;
+       if (group)
+               status = nfsd_map_gid_to_name(rqstp, id, (u8 *)(*p + 1));
+       else
+               status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1));
+       if (status < 0)
+               return nfserrno(status);
+       len = (unsigned)status;
+       *(*p)++ = htonl(len);
+       memset((u8 *)*p + len, 0, xdr_padding(len));
+       *p += XDR_QUADLEN(len);
+       *buflen -= (XDR_QUADLEN(len) << 2) + 4;
+       BUG_ON(*buflen < 0);
+       return 0;
+}
+
+static inline int
+nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, u32 **p, int *buflen)
+{
+       return nfsd4_encode_name(rqstp, uid, 0, p, buflen);
+}
+
+static inline int
+nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, u32 **p, int *buflen)
+{
+       return nfsd4_encode_name(rqstp, gid, 1, p, buflen);
+}
+
+
 /*
  * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
  * ourselves.
@@ -1304,10 +1346,6 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
        u32 bmval0 = bmval[0];
        u32 bmval1 = bmval[1];
        struct kstat stat;
-       char owner[IDMAP_NAMESZ];
-       u32 ownerlen = 0;
-       char group[IDMAP_NAMESZ];
-       u32 grouplen = 0;
        struct svc_fh tempfh;
        struct kstatfs statfs;
        int buflen = *countp << 2;
@@ -1338,23 +1376,6 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
                        goto out;
                fhp = &tempfh;
        }
-       if (bmval1 & FATTR4_WORD1_OWNER) {
-               int temp = nfsd_map_uid_to_name(rqstp, stat.uid, owner);
-               if (temp < 0) {
-                       status = temp;
-                       goto out_nfserr;
-               }
-               ownerlen = (unsigned) temp;
-       }
-       if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
-               int temp = nfsd_map_gid_to_name(rqstp, stat.gid, group);
-               if (temp < 0) {
-                       status = temp;
-                       goto out_nfserr;
-               }
-               grouplen = (unsigned) temp;
-       }
-
        if ((buflen -= 16) < 0)
                goto out_resource;
 
@@ -1536,18 +1557,18 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
                WRITE32(stat.nlink);
        }
        if (bmval1 & FATTR4_WORD1_OWNER) {
-               buflen -= (XDR_QUADLEN(ownerlen) << 2) + 4;
-               if (buflen < 0)
+               status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
+               if (status == nfserr_resource)
                        goto out_resource;
-               WRITE32(ownerlen);
-               WRITEMEM(owner, ownerlen);
+               if (status)
+                       goto out;
        }
        if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
-               buflen -= (XDR_QUADLEN(grouplen) << 2) + 4;
-               if (buflen < 0)
+               status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
+               if (status == nfserr_resource)
                        goto out_resource;
-               WRITE32(grouplen);
-               WRITEMEM(group, grouplen);
+               if (status)
+                       goto out;
        }
        if (bmval1 & FATTR4_WORD1_RAWDEV) {
                if ((buflen -= 8) < 0)
index aaa367f..8e8c234 100644 (file)
@@ -56,7 +56,7 @@ int nfsd_acceptable(void *expv, struct dentry *dentry)
                /* make sure parents give x permission to user */
                int err;
                parent = dget_parent(tdentry);
-               err = permission(parent->d_inode, S_IXOTH, NULL);
+               err = permission(parent->d_inode, MAY_EXEC, NULL);
                if (err < 0) {
                        dput(parent);
                        break;
index 097555b..57e8c7e 100644 (file)
@@ -1,4 +1,4 @@
-ToDo:
+ToDo/Notes:
        - Find and fix bugs.
        - Either invalidate quotas or update the quota charges on NTFS 3.x
          volumes with quota tracking enabled ($Quota).
@@ -11,8 +11,10 @@ ToDo:
          pages as nothing can dirty a page other than ourselves. Should this
          change, we will really need to roll our own ->set_page_dirty().
        - Implement sops->dirty_inode() to implement {a,m,c}time updates and
-         such things.
-       - Implement sops->write_inode().
+         such things.  This should probably just flag the ntfs inode such that
+         sops->write_inode(), i.e. ntfs_write_inode(), will copy the times
+         when it is invoked rather than having to update the mft record
+         every time.
        - In between ntfs_prepare/commit_write, need exclusion between
          simultaneous file extensions. Need perhaps an NInoResizeUnderway()
          flag which we can set in ntfs_prepare_write() and clear again in
@@ -24,6 +26,71 @@ ToDo:
          OTOH, perhaps i_sem, which is held accross generic_file_write is
          sufficient for synchronisation here. We then just need to make sure
          ntfs_readpage/writepage/truncate interoperate properly with us.
+       - Implement mft.c::sync_mft_mirror_umount().  We currently will just
+         leave the volume dirty on umount if the final iput(vol->mft_ino)
+         causes a write of any mirrored mft records due to the mft mirror
+         inode having been discarded already.  Whether this can actually ever
+         happen is unclear however so it is worth waiting until someone hits
+         the problem.
+       - Enable the code for setting the NT4 compatibility flag when we start
+         making NTFS 1.2 specific modifications.
+
+2.1.14 - Fix an NFSd caused deadlock reported by several users.
+
+       - Modify fs/ntfs/ntfs_readdir() to copy the index root attribute value
+         to a buffer so that we can put the search context and unmap the mft
+         record before calling the filldir() callback.  We need to do this
+         because of NFSd which calls ->lookup() from its filldir callback()
+         and this causes NTFS to deadlock as ntfs_lookup() maps the mft record
+         of the directory and since ntfs_readdir() has got it mapped already
+         ntfs_lookup() deadlocks.
+
+2.1.13 - Enable overwriting of resident files and housekeeping of system files.
+
+       - Implement writing of mft records (fs/ntfs/mft.[hc]), which includes
+         keeping the mft mirror in sync with the mft when mirrored mft records
+         are written.  The functions are write_mft_record{,_nolock}().  The
+         implementation is quite rudimentary for now with lots of things not
+         implemented yet but I am not sure any of them can actually occur so
+         I will wait for people to hit each one and only then implement it.
+       - Commit open system inodes at umount time.  This should make it
+         virtually impossible for sync_mft_mirror_umount() to ever be needed.
+       - Implement ->write_inode (fs/ntfs/inode.c::ntfs_write_inode()) for the
+         ntfs super operations.  This gives us inode writing via the VFS inode
+         dirty code paths.  Note:  Access time updates are not implemented yet.
+       - Implement fs/ntfs/mft.[hc]::{,__}mark_mft_record_dirty() and make
+         fs/ntfs/aops.c::ntfs_writepage() and ntfs_commit_write() use it, thus
+         finally enabling resident file overwrite!  (-8  This also includes a
+         placeholder for ->writepage (ntfs_mft_writepage()), which for now
+         just redirties the page and returns.  Also, at umount time, we for
+         now throw away all mft data page cache pages after the last call to
+         ntfs_commit_inode() in the hope that all inodes will have been
+         written out by then and hence no dirty (meta)data will be lost.  We
+         also check for this case and emit an error message telling the user
+         to run chkdsk.
+       - Use set_page_writeback() and end_page_writeback() in the resident
+         attribute code path of fs/ntfs/aops.c::ntfs_writepage() otherwise
+         the radix-tree tag PAGECACHE_TAG_DIRTY remains set even though the
+         page is clean.
+       - Implement ntfs_mft_writepage() so it now checks if any of the mft
+         records in the page are dirty and if so redirties the page and
+         returns.  Otherwise it just returns (after doing set_page_writeback(),
+         unlock_page(), end_page_writeback() or the radix-tree tag
+         PAGECACHE_TAG_DIRTY remains set even though the page is clean), thus
+         alowing the VM to do with the page as it pleases.  Also, at umount
+         time, now only throw away dirty mft (meta)data pages if dirty inodes
+         are present and ask the user to email us if they see this happening.
+       - Add functions ntfs_{clear,set}_volume_flags(), to modify the volume
+         information flags (fs/ntfs/super.c).
+       - Mark the volume dirty when (re)mounting read-write and mark it clean
+         when unmounting or remounting read-only.  If any volume errors are
+         found, the volume is left marked dirty to force chkdsk to run.
+       - Add code to set the NT4 compatibility flag when (re)mounting
+         read-write for newer NTFS versions but leave it commented out for now
+         since we do not make any modifications that are NTFS 1.2 specific yet
+         and since setting this flag breaks Captive-NTFS which is not nice.
+         This code must be enabled once we start writing NTFS 1.2 specific
+         changes otherwise Windows NTFS driver might crash / cause corruption.
 
 2.1.12 - Fix the second fix to the decompression engine and some cleanups.
 
index 715dc2c..3665464 100644 (file)
@@ -5,7 +5,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs.o
 ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \
             mst.o namei.o super.o sysctl.o unistr.o upcase.o
 
-EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.12\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.14\"
 
 ifeq ($(CONFIG_NTFS_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
index f7f561a..08aa85b 100644 (file)
@@ -478,8 +478,8 @@ static int ntfs_write_block(struct writeback_control *wbc, struct page *page)
        ni = NTFS_I(vi);
        vol = ni->vol;
 
-       ntfs_debug("Entering for inode %li, attribute type 0x%x, page index "
-                       "0x%lx.\n", vi->i_ino, ni->type, page->index);
+       ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
+                       "0x%lx.", vi->i_ino, ni->type, page->index);
 
        BUG_ON(!NInoNonResident(ni));
        BUG_ON(NInoMstProtected(ni));
@@ -778,9 +778,8 @@ lock_retry_remap:
  *
  * For resident attributes, OTOH, ntfs_writepage() writes the @page by copying
  * the data to the mft record (which at this stage is most likely in memory).
- * Thus, in this case, I/O is synchronous, as even if the mft record is not
- * cached at this point in time, we need to wait for it to be read in before we
- * can do the copy.
+ * The mft record is then marked dirty and written out asynchronously via the
+ * vfs inode dirty code path.
  *
  * Note the caller clears the page dirty flag before calling ntfs_writepage().
  *
@@ -875,16 +874,6 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
        BUG_ON(page_has_buffers(page));
        BUG_ON(!PageUptodate(page));
 
-       // TODO: Consider using PageWriteback() + unlock_page() in 2.5 once the
-       // "VM fiddling has ended". Note, don't forget to replace all the
-       // unlock_page() calls further below with end_page_writeback() ones.
-       // FIXME: Make sure it is ok to SetPageError() on unlocked page under
-       // writeback before doing the change!
-#if 0
-       set_page_writeback(page);
-       unlock_page(page);
-#endif
-
        if (!NInoAttr(ni))
                base_ni = ni;
        else
@@ -934,6 +923,14 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
        if (unlikely(bytes > PAGE_CACHE_SIZE))
                bytes = PAGE_CACHE_SIZE;
 
+       /*
+        * Keep the VM happy.  This must be done otherwise the radix-tree tag
+        * PAGECACHE_TAG_DIRTY remains set even though the page is clean.
+        */
+       BUG_ON(PageWriteback(page));
+       set_page_writeback(page);
+       unlock_page(page);
+
        /*
         * Here, we don't need to zero the out of bounds area everytime because
         * the below memcpy() already takes care of the mmap-at-end-of-file
@@ -948,7 +945,10 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
         * expose data to userspace/disk which should never have been exposed.
         *
         * FIXME: Ensure that i_size increases do the zeroing/overwriting and
-        * if we cannot guarantee that, then enable the zeroing below.
+        * if we cannot guarantee that, then enable the zeroing below.  If the
+        * zeroing below is enabled, we MUST move the unlock_page() from above
+        * to after the kunmap_atomic(), i.e. just before the
+        * end_page_writeback().
         */
 
        kaddr = kmap_atomic(page, KM_USER0);
@@ -966,11 +966,10 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
 #endif
        kunmap_atomic(kaddr, KM_USER0);
 
-       unlock_page(page);
+       end_page_writeback(page);
 
-       // TODO: Mark mft record dirty so it gets written back.
-       ntfs_error(vi->i_sb, "Writing to resident files is not supported yet. "
-                       "Wrote to memory only...");
+       /* Mark the mft record dirty, so it gets written back. */
+       mark_mft_record_dirty(ctx->ntfs_ino);
 
        put_attr_search_ctx(ctx);
        unmap_mft_record(base_ni);
@@ -1022,7 +1021,7 @@ static int ntfs_prepare_nonresident_write(struct page *page,
        ni = NTFS_I(vi);
        vol = ni->vol;
 
-       ntfs_debug("Entering for inode %li, attribute type 0x%x, page index "
+       ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
                        "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
                        page->index, from, to);
 
@@ -1379,7 +1378,7 @@ static int ntfs_prepare_write(struct file *file, struct page *page,
        struct inode *vi = page->mapping->host;
        ntfs_inode   *ni = NTFS_I(vi);
 
-       ntfs_debug("Entering for inode %li, attribute type 0x%x, page index "
+       ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
                        "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
                        page->index, from, to);
 
@@ -1487,7 +1486,7 @@ static int ntfs_commit_nonresident_write(struct page *page,
 
        vi = page->mapping->host;
 
-       ntfs_debug("Entering for inode %li, attribute type 0x%x, page index "
+       ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
                        "0x%lx, from = %u, to = %u.", vi->i_ino,
                        NTFS_I(vi)->type, page->index, from, to);
 
@@ -1583,7 +1582,7 @@ static int ntfs_commit_write(struct file *file, struct page *page,
        vi = page->mapping->host;
        ni = NTFS_I(vi);
 
-       ntfs_debug("Entering for inode %li, attribute type 0x%x, page index "
+       ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
                        "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
                        page->index, from, to);
 
@@ -1734,9 +1733,8 @@ static int ntfs_commit_write(struct file *file, struct page *page,
        }
        kunmap_atomic(kaddr, KM_USER0);
 
-       // TODO: Mark mft record dirty so it gets written back.
-       ntfs_error(vi->i_sb, "Writing to resident files is not supported yet. "
-                       "Wrote to memory only...");
+       /* Mark the mft record dirty, so it gets written back. */
+       mark_mft_record_dirty(ctx->ntfs_ino);
 
        put_attr_search_ctx(ctx);
        unmap_mft_record(base_ni);
index 2231c21..6c7fb2a 100644 (file)
@@ -624,7 +624,7 @@ run_list_element *ntfs_merge_run_lists(run_list_element *drl,
 
                        if (drl[ds].vcn == marker_vcn) {
                                ntfs_debug("Old marker = 0x%llx, replacing "
-                                               "with LCN_ENOENT.\n",
+                                               "with LCN_ENOENT.",
                                                (unsigned long long)
                                                drl[ds].lcn);
                                drl[ds].lcn = (LCN)LCN_ENOENT;
@@ -1565,7 +1565,7 @@ do_next_attr:
                goto do_next_attr_loop;
        }
        ntfs_error(base_ni->vol->sb, "Inode contains corrupt attribute list "
-                       "attribute.\n");
+                       "attribute.");
        if (ni != base_ni) {
                unmap_extent_mft_record(ni);
                ctx->ntfs_ino = base_ni;
index 5836232..f9aca53 100644 (file)
@@ -433,7 +433,7 @@ do_next_tag:
        goto do_next_tag;
 
 return_overflow:
-       ntfs_error(NULL, "Failed. Returning -EOVERFLOW.\n");
+       ntfs_error(NULL, "Failed. Returning -EOVERFLOW.");
        goto return_error;
 }
 
@@ -851,7 +851,7 @@ lock_retry_remap:
                if (err) {
                        ntfs_error(vol->sb, "ntfs_decompress() failed in inode "
                                        "0x%lx with error code %i. Skipping "
-                                       "this compression block.\n",
+                                       "this compression block.",
                                        ni->mft_no, -err);
                        /* Release the unfinished pages. */
                        for (; prev_cur_page < cur_page; prev_cur_page++) {
index 470a1e9..153100b 100644 (file)
@@ -1067,7 +1067,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        ntfs_inode *ndir = NTFS_I(vdir);
        ntfs_volume *vol = NTFS_SB(sb);
        MFT_RECORD *m;
-       INDEX_ROOT *ir;
+       INDEX_ROOT *ir = NULL;
        INDEX_ENTRY *ie;
        INDEX_ALLOCATION *ia;
        u8 *name = NULL;
@@ -1139,9 +1139,29 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                                "inode 0x%lx.", vdir->i_ino);
                goto err_out;
        }
-       /* Get to the index root value (it's been verified in read_inode). */
-       ir = (INDEX_ROOT*)((u8*)ctx->attr +
-                       le16_to_cpu(ctx->attr->data.resident.value_offset));
+       /*
+        * Copy the index root attribute value to a buffer so that we can put
+        * the search context and unmap the mft record before calling the
+        * filldir() callback.  We need to do this because of NFSd which calls
+        * ->lookup() from its filldir callback() and this causes NTFS to
+        * deadlock as ntfs_lookup() maps the mft record of the directory and
+        * we have got it mapped here already.  The only solution is for us to
+        * unmap the mft record here so that a call to ntfs_lookup() is able to
+        * map the mft record without deadlocking.
+        */
+       rc = le32_to_cpu(ctx->attr->data.resident.value_length);
+       ir = (INDEX_ROOT*)kmalloc(rc, GFP_NOFS);
+       if (unlikely(!ir)) {
+               err = -ENOMEM;
+               goto err_out;
+       }
+       /* Copy the index root value (it has been verified in read_inode). */
+       memcpy(ir, (u8*)ctx->attr +
+                       le16_to_cpu(ctx->attr->data.resident.value_offset), rc);
+       put_attr_search_ctx(ctx);
+       unmap_mft_record(ndir);
+       ctx = NULL;
+       m = NULL;
        index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
        /* The first index entry. */
        ie = (INDEX_ENTRY*)((u8*)&ir->index +
@@ -1154,7 +1174,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
                ntfs_debug("In index root, offset 0x%x.", (u8*)ie - (u8*)ir);
                /* Bounds checks. */
-               if (unlikely((u8*)ie < (u8*)ctx->mrec || (u8*)ie +
+               if (unlikely((u8*)ie < (u8*)ir || (u8*)ie +
                                sizeof(INDEX_ENTRY_HEADER) > index_end ||
                                (u8*)ie + le16_to_cpu(ie->key_length) >
                                index_end))
@@ -1169,20 +1189,13 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                rc = ntfs_filldir(vol, &fpos, ndir, INDEX_TYPE_ROOT, ir, ie,
                                name, dirent, filldir);
                if (rc) {
-                       put_attr_search_ctx(ctx);
-                       unmap_mft_record(ndir);
+                       kfree(ir);
                        goto abort;
                }
        }
-       /*
-        * We are done with the index root and the mft record for that matter.
-        * We need to release it, otherwise we deadlock on ntfs_attr_iget()
-        * and/or ntfs_read_page().
-        */
-       put_attr_search_ctx(ctx);
-       unmap_mft_record(ndir);
-       m = NULL;
-       ctx = NULL;
+       /* We are done with the index root and can free the buffer. */
+       kfree(ir);
+       ir = NULL;
        /* If there is no index allocation attribute we are finished. */
        if (!NInoIndexAllocPresent(ndir))
                goto EOD;
@@ -1379,6 +1392,8 @@ err_out:
                ntfs_unmap_page(bmp_page);
        if (ia_page)
                ntfs_unmap_page(ia_page);
+       if (ir)
+               kfree(ir);
        if (name)
                kfree(name);
        if (ctx)
index 0bb39d8..1abe1b3 100644 (file)
@@ -1960,49 +1960,134 @@ trunc_err:
        return err;
 }
 
+/**
+ * ntfs_write_inode - write out a dirty inode
+ * @vi:                inode to write out
+ * @sync:      if true, write out synchronously
+ *
+ * Write out a dirty inode to disk including any extent inodes if present.
+ *
+ * If @sync is true, commit the inode to disk and wait for io completion.  This
+ * is done using write_mft_record().
+ *
+ * If @sync is false, just schedule the write to happen but do not wait for i/o
+ * completion.  In 2.6 kernels, scheduling usually happens just by virtue of
+ * marking the page (and in this case mft record) dirty but we do not implement
+ * this yet as write_mft_record() largely ignores the @sync parameter and
+ * always performs synchronous writes.
+ */
 void ntfs_write_inode(struct inode *vi, int sync)
 {
        ntfs_inode *ni = NTFS_I(vi);
+#if 0
+       attr_search_context *ctx;
+#endif
+       MFT_RECORD *m;
+       int err = 0;
 
        ntfs_debug("Entering for %sinode 0x%lx.", NInoAttr(ni) ? "attr " : "",
                        vi->i_ino);
-
        /*
         * Dirty attribute inodes are written via their real inodes so just
-        * clean them here.
+        * clean them here.  TODO:  Take care of access time updates.
         */
        if (NInoAttr(ni)) {
                NInoClearDirty(ni);
                return;
        }
-
-       /* Write this base mft record. */
-       if (NInoDirty(ni)) {
-               ntfs_warning(vi->i_sb, "Cleaning dirty inode 0x%lx without "
-                               "writing to disk as this is not yet "
-                               "implemented.", vi->i_ino);
-               NInoClearDirty(ni);
+       /* Map, pin, and lock the mft record belonging to the inode. */
+       m = map_mft_record(ni);
+       if (unlikely(IS_ERR(m))) {
+               err = PTR_ERR(m);
+               goto err_out;
        }
-
+#if 0
+       /* Obtain the standard information attribute. */
+       ctx = get_attr_search_ctx(ni, m);
+       if (unlikely(!ctx)) {
+               err = -ENOMEM;
+               goto unm_err_out;
+       }
+       if (unlikely(!lookup_attr(AT_STANDARD_INFORMATION, NULL, 0,
+                       IGNORE_CASE, 0, NULL, 0, ctx))) {
+               put_attr_search_ctx(ctx);
+               err = -ENOENT;
+               goto unm_err_out;
+       }
+       // TODO:  Update the access times in the standard information attribute
+       // which is now in ctx->attr.
+       // - Probably want to have use sops->dirty_inode() to set a flag that
+       //   we need to update the times here rather than having to blindly do
+       //   it every time.  Or even don't do it here at all and do it in
+       //   sops->dirty_inode() instead.  Problem with this would be that
+       //   sops->dirty_inode() must be atomic under certain circumstances
+       //   and mapping mft records and such like is not atomic.
+       // - For atime updates also need to check whether they are enabled in
+       //   the superblock flags.
+       ntfs_warning(vi->i_sb, "Access time updates not implement yet.");
+       /*
+        * We just modified the mft record containing the standard information
+        * attribute.  So need to mark the mft record dirty, too, but we do it
+        * manually so that mark_inode_dirty() is not called again.
+        * TODO:  Only do this if there was a change in any of the times!
+        */
+       if (!NInoTestSetDirty(ctx->ntfs_ino))
+               __set_page_dirty_nobuffers(ctx->ntfs_ino->page);
+       put_attr_search_ctx(ctx);
+#endif
+       /* Write this base mft record. */
+       if (NInoDirty(ni))
+               err = write_mft_record(ni, m, sync);
        /* Write all attached extent mft records. */
        down(&ni->extent_lock);
        if (ni->nr_extents > 0) {
-               int i;
                ntfs_inode **extent_nis = ni->ext.extent_ntfs_inos;
+               int i;
 
+               ntfs_debug("Writing %i extent inodes.", ni->nr_extents);
                for (i = 0; i < ni->nr_extents; i++) {
                        ntfs_inode *tni = extent_nis[i];
 
                        if (NInoDirty(tni)) {
-                               ntfs_warning(vi->i_sb, "Cleaning dirty extent "
-                                               "inode 0x%lx without writing "
-                                               "to disk as this is not yet "
-                                               "implemented.", tni->mft_no);
-                               NInoClearDirty(tni);
+                               MFT_RECORD *tm = map_mft_record(tni);
+                               int ret;
+
+                               if (unlikely(IS_ERR(tm))) {
+                                       if (!err || err == -ENOMEM)
+                                               err = PTR_ERR(tm);
+                                       continue;
+                               }
+                               ret = write_mft_record(tni, tm, sync);
+                               unmap_mft_record(tni);
+                               if (unlikely(ret)) {
+                                       if (!err || err == -ENOMEM)
+                                               err = ret;
+                               }
                        }
                }
        }
        up(&ni->extent_lock);
+       unmap_mft_record(ni);
+       if (unlikely(err))
+               goto err_out;
+       ntfs_debug("Done.");
+       return;
+#if 0
+unm_err_out:
+       unmap_mft_record(ni);
+#endif
+err_out:
+       if (err == -ENOMEM) {
+               ntfs_warning(vi->i_sb, "Not enough memory to write inode.  "
+                               "Marking the inode dirty again, so the VFS "
+                               "retries later.");
+               mark_inode_dirty(vi);
+       } else {
+               ntfs_error(vi->i_sb, "Failed (error code %i):  Marking inode "
+                               "as bad.  You should run chkdsk.", -err);
+               make_bad_inode(vi);
+       }
+       return;
 }
 
 #endif /* NTFS_RW */
index 92cdcb8..8875af9 100644 (file)
@@ -102,6 +102,13 @@ int format_mft_record(ntfs_inode *ni, MFT_RECORD *mft_rec)
  */
 extern int ntfs_readpage(struct file *, struct page *);
 
+#ifdef NTFS_RW
+/**
+ * ntfs_mft_writepage - forward declaration, function is further below
+ */
+static int ntfs_mft_writepage(struct page *page, struct writeback_control *wbc);
+#endif /* NTFS_RW */
+
 /**
  * ntfs_mft_aops - address space operations for access to $MFT
  *
@@ -112,6 +119,10 @@ struct address_space_operations ntfs_mft_aops = {
        .readpage       = ntfs_readpage,        /* Fill page with data. */
        .sync_page      = block_sync_page,      /* Currently, just unplugs the
                                                   disk request queue. */
+#ifdef NTFS_RW
+       .writepage      = ntfs_mft_writepage,   /* Write out the dirty mft
+                                                  records in a page. */
+#endif /* NTFS_RW */
 };
 
 /**
@@ -429,3 +440,654 @@ unm_err_out:
                ntfs_clear_extent_inode(ni);
        return m;
 }
+
+#ifdef NTFS_RW
+
+/**
+ * __mark_mft_record_dirty - set the mft record and the page containing it dirty
+ * @ni:                ntfs inode describing the mapped mft record
+ *
+ * Internal function.  Users should call mark_mft_record_dirty() instead.
+ *
+ * Set the mapped (extent) mft record of the (base or extent) ntfs inode @ni,
+ * as well as the page containing the mft record, dirty.  Also, mark the base
+ * vfs inode dirty.  This ensures that any changes to the mft record are
+ * written out to disk.
+ *
+ * NOTE:  We only set I_DIRTY_SYNC and I_DIRTY_DATASYNC (and not I_DIRTY_PAGES)
+ * on the base vfs inode, because even though file data may have been modified,
+ * it is dirty in the inode meta data rather than the data page cache of the
+ * inode, and thus there are no data pages that need writing out.  Therefore, a
+ * full mark_inode_dirty() is overkill.  A mark_inode_dirty_sync(), on the
+ * other hand, is not sufficient, because I_DIRTY_DATASYNC needs to be set to
+ * ensure ->write_inode is called from generic_osync_inode() and this needs to
+ * happen or the file data would not necessarily hit the device synchronously,
+ * even though the vfs inode has the O_SYNC flag set.  Also, I_DIRTY_DATASYNC
+ * simply "feels" better than just I_DIRTY_SYNC, since the file data has not
+ * actually hit the block device yet, which is not what I_DIRTY_SYNC on its own
+ * would suggest.
+ */
+void __mark_mft_record_dirty(ntfs_inode *ni)
+{
+       struct page *page = ni->page;
+       ntfs_inode *base_ni;
+
+       ntfs_debug("Entering for inode 0x%lx.", ni->mft_no);
+       BUG_ON(!page);
+       BUG_ON(NInoAttr(ni));
+
+       /*
+        * Set the page containing the mft record dirty.  This also marks the
+        * $MFT inode dirty (I_DIRTY_PAGES).
+        */
+       __set_page_dirty_nobuffers(page);
+
+       /* Determine the base vfs inode and mark it dirty, too. */
+       down(&ni->extent_lock);
+       if (likely(ni->nr_extents >= 0))
+               base_ni = ni;
+       else
+               base_ni = ni->ext.base_ntfs_ino;
+       up(&ni->extent_lock);
+       __mark_inode_dirty(VFS_I(base_ni), I_DIRTY_SYNC | I_DIRTY_DATASYNC);
+}
+
+static const char *ntfs_please_email = "Please email "
+               "linux-ntfs-dev@lists.sourceforge.net and say that you saw "
+               "this message.  Thank you.";
+
+/**
+ * sync_mft_mirror_umount - synchronise an mft record to the mft mirror
+ * @ni:                ntfs inode whose mft record to synchronize
+ * @m:         mapped, mst protected (extent) mft record to synchronize
+ *
+ * Write the mapped, mst protected (extent) mft record @m described by the
+ * (regular or extent) ntfs inode @ni to the mft mirror ($MFTMirr) bypassing
+ * the page cache and the $MFTMirr inode itself.
+ *
+ * This function is only for use at umount time when the mft mirror inode has
+ * already been disposed off.  We BUG() if we are called while the mft mirror
+ * inode is still attached to the volume.
+ *
+ * On success return 0.  On error return -errno.
+ *
+ * NOTE:  This function is not implemented yet as I am not convinced it can
+ * actually be triggered considering the sequence of commits we do in super.c::
+ * ntfs_put_super().  But just in case we provide this place holder as the
+ * alternative would be either to BUG() or to get a NULL pointer dereference
+ * and Oops.
+ */
+static int sync_mft_mirror_umount(ntfs_inode *ni, MFT_RECORD *m)
+{
+       ntfs_volume *vol = ni->vol;
+
+       BUG_ON(vol->mftmirr_ino);
+       ntfs_error(vol->sb, "Umount time mft mirror syncing is not "
+                       "implemented yet.  %s", ntfs_please_email);
+       return -EOPNOTSUPP;
+}
+
+/**
+ * sync_mft_mirror - synchronize an mft record to the mft mirror
+ * @ni:                ntfs inode whose mft record to synchronize
+ * @m:         mapped, mst protected (extent) mft record to synchronize
+ * @sync:      if true, wait for i/o completion
+ *
+ * Write the mapped, mst protected (extent) mft record @m described by the
+ * (regular or extent) ntfs inode @ni to the mft mirror ($MFTMirr).
+ *
+ * On success return 0.  On error return -errno and set the volume errors flag
+ * in the ntfs_volume to which @ni belongs.
+ *
+ * NOTE:  We always perform synchronous i/o and ignore the @sync parameter.
+ *
+ * TODO:  If @sync is false, want to do truly asynchronous i/o, i.e. just
+ * schedule i/o via ->writepage or do it via kntfsd or whatever.
+ */
+static int sync_mft_mirror(ntfs_inode *ni, MFT_RECORD *m, int sync)
+{
+       ntfs_volume *vol = ni->vol;
+       struct page *page;
+       unsigned int blocksize = vol->sb->s_blocksize;
+       int max_bhs = vol->mft_record_size / blocksize;
+       struct buffer_head *bhs[max_bhs];
+       struct buffer_head *bh, *head;
+       u8 *kmirr;
+       unsigned int block_start, block_end, m_start, m_end;
+       int i_bhs, nr_bhs, err = 0;
+
+       ntfs_debug("Entering for inode 0x%lx.", ni->mft_no);
+       BUG_ON(!max_bhs);
+       if (unlikely(!vol->mftmirr_ino)) {
+               /* This could happen during umount... */
+               err = sync_mft_mirror_umount(ni, m);
+               if (likely(!err))
+                       return err;
+               goto err_out;
+       }
+       /* Get the page containing the mirror copy of the mft record @m. */
+       page = ntfs_map_page(vol->mftmirr_ino->i_mapping, ni->mft_no >>
+                       (PAGE_CACHE_SHIFT - vol->mft_record_size_bits));
+       if (unlikely(IS_ERR(page))) {
+               ntfs_error(vol->sb, "Failed to map mft mirror page.");
+               err = PTR_ERR(page);
+               goto err_out;
+       }
+       /*
+        * Exclusion against other writers.   This should never be a problem
+        * since the page in which the mft record @m resides is also locked and
+        * hence any other writers would be held up there but it is better to
+        * make sure no one is writing from elsewhere.
+        */
+       lock_page(page);
+       /* The address in the page of the mirror copy of the mft record @m. */
+       kmirr = page_address(page) + ((ni->mft_no << vol->mft_record_size_bits)
+                       & ~PAGE_CACHE_MASK);
+       /* Copy the mst protected mft record to the mirror. */
+       memcpy(kmirr, m, vol->mft_record_size);
+       /* Make sure we have mapped buffers. */
+       if (!page_has_buffers(page)) {
+no_buffers_err_out:
+               ntfs_error(vol->sb, "Writing mft mirror records without "
+                               "existing buffers is not implemented yet.  %s",
+                               ntfs_please_email);
+               err = -EOPNOTSUPP;
+               goto unlock_err_out;
+       }
+       bh = head = page_buffers(page);
+       if (!bh)
+               goto no_buffers_err_out;
+       nr_bhs = 0;
+       block_start = 0;
+       m_start = kmirr - (u8*)page_address(page);
+       m_end = m_start + vol->mft_record_size;
+       do {
+               block_end = block_start + blocksize;
+               /*
+                * If the buffer is outside the mft record, just skip it,
+                * clearing it if it is dirty to make sure it is not written
+                * out.  It should never be marked dirty but better be safe.
+                */
+               if ((block_end <= m_start) || (block_start >= m_end)) {
+                       if (buffer_dirty(bh)) {
+                               ntfs_warning(vol->sb, "Clearing dirty mft "
+                                               "record page buffer.  %s",
+                                               ntfs_please_email);
+                               clear_buffer_dirty(bh);
+                       }
+                       continue;
+               }
+               if (!buffer_mapped(bh)) {
+                       ntfs_error(vol->sb, "Writing mft mirror records "
+                                       "without existing mapped buffers is "
+                                       "not implemented yet.  %s",
+                                       ntfs_please_email);
+                       err = -EOPNOTSUPP;
+                       continue;
+               }
+               if (!buffer_uptodate(bh)) {
+                       ntfs_error(vol->sb, "Writing mft mirror records "
+                                       "without existing uptodate buffers is "
+                                       "not implemented yet.  %s",
+                                       ntfs_please_email);
+                       err = -EOPNOTSUPP;
+                       continue;
+               }
+               BUG_ON(!nr_bhs && (m_start != block_start));
+               BUG_ON(nr_bhs >= max_bhs);
+               bhs[nr_bhs++] = bh;
+               BUG_ON((nr_bhs >= max_bhs) && (m_end != block_end));
+       } while (block_start = block_end, (bh = bh->b_this_page) != head);
+       if (likely(!err)) {
+               /* Lock buffers and start synchronous write i/o on them. */
+               for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) {
+                       struct buffer_head *tbh = bhs[i_bhs];
+
+                       if (unlikely(test_set_buffer_locked(tbh)))
+                               BUG();
+                       BUG_ON(!buffer_uptodate(tbh));
+                       if (buffer_dirty(tbh))
+                               clear_buffer_dirty(tbh);
+                       get_bh(tbh);
+                       tbh->b_end_io = end_buffer_write_sync;
+                       submit_bh(WRITE, tbh);
+               }
+               /* Wait on i/o completion of buffers. */
+               for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) {
+                       struct buffer_head *tbh = bhs[i_bhs];
+
+                       wait_on_buffer(tbh);
+                       if (unlikely(!buffer_uptodate(tbh))) {
+                               err = -EIO;
+                               /*
+                                * Set the buffer uptodate so the page & buffer
+                                * states don't become out of sync.
+                                */
+                               if (PageUptodate(page))
+                                       set_buffer_uptodate(tbh);
+                       }
+               }
+       } else /* if (unlikely(err)) */ {
+               /* Clean the buffers. */
+               for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++)
+                       clear_buffer_dirty(bhs[i_bhs]);
+       }
+unlock_err_out:
+       /* Current state: all buffers are clean, unlocked, and uptodate. */
+       /* Remove the mst protection fixups again. */
+       post_write_mst_fixup((NTFS_RECORD*)kmirr);
+       flush_dcache_page(page);
+       unlock_page(page);
+       ntfs_unmap_page(page);
+       if (unlikely(err)) {
+               /* I/O error during writing.  This is really bad! */
+               ntfs_error(vol->sb, "I/O error while writing mft mirror "
+                               "record 0x%lx!  You should unmount the volume "
+                               "and run chkdsk or ntfsfix.", ni->mft_no);
+               goto err_out;
+       }
+       ntfs_debug("Done.");
+       return 0;
+err_out:
+       ntfs_error(vol->sb, "Failed to synchronize $MFTMirr (error code %i).  "
+                       "Volume will be left marked dirty on umount.  Run "
+                       "ntfsfix on the partition after umounting to correct "
+                       "this.", -err);
+       /* We don't want to clear the dirty bit on umount. */
+       NVolSetErrors(vol);
+       return err;
+}
+
+/**
+ * write_mft_record_nolock - write out a mapped (extent) mft record
+ * @ni:                ntfs inode describing the mapped (extent) mft record
+ * @m:         mapped (extent) mft record to write
+ * @sync:      if true, wait for i/o completion
+ *
+ * Write the mapped (extent) mft record @m described by the (regular or extent)
+ * ntfs inode @ni to backing store.  If the mft record @m has a counterpart in
+ * the mft mirror, that is also updated.
+ *
+ * On success, clean the mft record and return 0.  On error, leave the mft
+ * record dirty and return -errno.  The caller should call make_bad_inode() on
+ * the base inode to ensure no more access happens to this inode.  We do not do
+ * it here as the caller may want to finish writing other extent mft records
+ * first to minimize on-disk metadata inconsistencies.
+ *
+ * NOTE:  We always perform synchronous i/o and ignore the @sync parameter.
+ * However, if the mft record has a counterpart in the mft mirror and @sync is
+ * true, we write the mft record, wait for i/o completion, and only then write
+ * the mft mirror copy.  This ensures that if the system crashes either the mft
+ * or the mft mirror will contain a self-consistent mft record @m.  If @sync is
+ * false on the other hand, we start i/o on both and then wait for completion
+ * on them.  This provides a speedup but no longer guarantees that you will end
+ * up with a self-consistent mft record in the case of a crash but if you asked
+ * for asynchronous writing you probably do not care about that anyway.
+ *
+ * TODO:  If @sync is false, want to do truly asynchronous i/o, i.e. just
+ * schedule i/o via ->writepage or do it via kntfsd or whatever.
+ */
+int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync)
+{
+       ntfs_volume *vol = ni->vol;
+       struct page *page = ni->page;
+       unsigned int blocksize = vol->sb->s_blocksize;
+       int max_bhs = vol->mft_record_size / blocksize;
+       struct buffer_head *bhs[max_bhs];
+       struct buffer_head *bh, *head;
+       unsigned int block_start, block_end, m_start, m_end;
+       int i_bhs, nr_bhs, err = 0;
+
+       ntfs_debug("Entering for inode 0x%lx.", ni->mft_no);
+       BUG_ON(NInoAttr(ni));
+       BUG_ON(!max_bhs);
+       BUG_ON(!page);
+       BUG_ON(!PageLocked(page));
+       /*
+        * If the ntfs_inode is clean no need to do anything.  If it is dirty,
+        * mark it as clean now so that it can be redirtied later on if needed.
+        * There is no danger of races as as long as the caller is holding the
+        * locks for the mft record @m and the page it is in.
+        */
+       if (!NInoTestClearDirty(ni))
+               goto done;
+       /* Make sure we have mapped buffers. */
+       if (!page_has_buffers(page)) {
+no_buffers_err_out:
+               ntfs_error(vol->sb, "Writing mft records without existing "
+                               "buffers is not implemented yet.  %s",
+                               ntfs_please_email);
+               err = -EOPNOTSUPP;
+               goto err_out;
+       }
+       bh = head = page_buffers(page);
+       if (!bh)
+               goto no_buffers_err_out;
+       nr_bhs = 0;
+       block_start = 0;
+       m_start = ni->page_ofs;
+       m_end = m_start + vol->mft_record_size;
+       do {
+               block_end = block_start + blocksize;
+               /*
+                * If the buffer is outside the mft record, just skip it,
+                * clearing it if it is dirty to make sure it is not written
+                * out.  It should never be marked dirty but better be safe.
+                */
+               if ((block_end <= m_start) || (block_start >= m_end)) {
+                       if (buffer_dirty(bh)) {
+                               ntfs_warning(vol->sb, "Clearing dirty mft "
+                                               "record page buffer.  %s",
+                                               ntfs_please_email);
+                               clear_buffer_dirty(bh);
+                       }
+                       continue;
+               }
+               if (!buffer_mapped(bh)) {
+                       ntfs_error(vol->sb, "Writing mft records without "
+                                       "existing mapped buffers is not "
+                                       "implemented yet.  %s",
+                                       ntfs_please_email);
+                       err = -EOPNOTSUPP;
+                       continue;
+               }
+               if (!buffer_uptodate(bh)) {
+                       ntfs_error(vol->sb, "Writing mft records without "
+                                       "existing uptodate buffers is not "
+                                       "implemented yet.  %s",
+                                       ntfs_please_email);
+                       err = -EOPNOTSUPP;
+                       continue;
+               }
+               BUG_ON(!nr_bhs && (m_start != block_start));
+               BUG_ON(nr_bhs >= max_bhs);
+               bhs[nr_bhs++] = bh;
+               BUG_ON((nr_bhs >= max_bhs) && (m_end != block_end));
+       } while (block_start = block_end, (bh = bh->b_this_page) != head);
+       if (unlikely(err))
+               goto cleanup_out;
+       /* Apply the mst protection fixups. */
+       err = pre_write_mst_fixup((NTFS_RECORD*)m, vol->mft_record_size);
+       if (err) {
+               ntfs_error(vol->sb, "Failed to apply mst fixups!");
+               goto cleanup_out;
+       }
+       flush_dcache_mft_record_page(ni);
+       /* Lock buffers and start synchronous write i/o on them. */
+       for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) {
+               struct buffer_head *tbh = bhs[i_bhs];
+
+               if (unlikely(test_set_buffer_locked(tbh)))
+                       BUG();
+               BUG_ON(!buffer_uptodate(tbh));
+               if (buffer_dirty(tbh))
+                       clear_buffer_dirty(tbh);
+               get_bh(tbh);
+               tbh->b_end_io = end_buffer_write_sync;
+               submit_bh(WRITE, tbh);
+       }
+       /* Synchronize the mft mirror now if not @sync. */
+       if (!sync && ni->mft_no < vol->mftmirr_size)
+               sync_mft_mirror(ni, m, sync);
+       /* Wait on i/o completion of buffers. */
+       for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) {
+               struct buffer_head *tbh = bhs[i_bhs];
+
+               wait_on_buffer(tbh);
+               if (unlikely(!buffer_uptodate(tbh))) {
+                       err = -EIO;
+                       /*
+                        * Set the buffer uptodate so the page & buffer states
+                        * don't become out of sync.
+                        */
+                       if (PageUptodate(page))
+                               set_buffer_uptodate(tbh);
+               }
+       }
+       /* If @sync, now synchronize the mft mirror. */
+       if (sync && ni->mft_no < vol->mftmirr_size)
+               sync_mft_mirror(ni, m, sync);
+       /* Remove the mst protection fixups again. */
+       post_write_mst_fixup((NTFS_RECORD*)m);
+       flush_dcache_mft_record_page(ni);
+       if (unlikely(err)) {
+               /* I/O error during writing.  This is really bad! */
+               ntfs_error(vol->sb, "I/O error while writing mft record "
+                               "0x%lx!  Marking base inode as bad.  You "
+                               "should unmount the volume and run chkdsk.",
+                               ni->mft_no);
+               goto err_out;
+       }
+done:
+       ntfs_debug("Done.");
+       return 0;
+cleanup_out:
+       /* Clean the buffers. */
+       for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++)
+               clear_buffer_dirty(bhs[i_bhs]);
+err_out:
+       /*
+        * Current state: all buffers are clean, unlocked, and uptodate.
+        * The caller should mark the base inode as bad so that no more i/o
+        * happens.  ->clear_inode() will still be invoked so all extent inodes
+        * and other allocated memory will be freed.
+        */
+       if (err == -ENOMEM) {
+               ntfs_error(vol->sb, "Not enough memory to write mft record.  "
+                               "Redirtying so the write is retried later.");
+               mark_mft_record_dirty(ni);
+               err = 0;
+       }
+       return err;
+}
+
+/**
+ * ntfs_mft_writepage - check if a metadata page contains dirty mft records
+ * @page:      metadata page possibly containing dirty mft records
+ * @wbc:       writeback control structure
+ *
+ * This is called from the VM when it wants to have a dirty $MFT/$DATA metadata
+ * page cache page cleaned.  The VM has already locked the page and marked it
+ * clean.  Instead of writing the page as a conventional ->writepage function
+ * would do, we check if the page still contains any dirty mft records (it must
+ * have done at some point in the past since the page was marked dirty) and if
+ * none are found, i.e. all mft records are clean, we unlock the page and
+ * return.  The VM is then free to do with the page as it pleases.  If on the
+ * other hand we do find any dirty mft records in the page, we redirty the page
+ * before unlocking it and returning so the VM knows that the page is still
+ * busy and cannot be thrown out.
+ *
+ * Note, we do not actually write any dirty mft records here because they are
+ * dirty inodes and hence will be written by the VFS inode dirty code paths.
+ * There is no need to write them from the VM page dirty code paths, too and in
+ * fact once we implement journalling it would be a complete nightmare having
+ * two code paths leading to mft record writeout.
+ */
+static int ntfs_mft_writepage(struct page *page, struct writeback_control *wbc)
+{
+       struct inode *mft_vi = page->mapping->host;
+       struct super_block *sb = mft_vi->i_sb;
+       ntfs_volume *vol = NTFS_SB(sb);
+       u8 *maddr;
+       MFT_RECORD *m;
+       ntfs_inode **extent_nis;
+       unsigned long mft_no;
+       int nr, i, j;
+       BOOL is_dirty = FALSE;
+
+       BUG_ON(mft_vi != vol->mft_ino);
+       /* The first mft record number in the page. */
+       mft_no = page->index << (PAGE_CACHE_SHIFT - vol->mft_record_size_bits);
+       /* Number of mft records in the page. */
+       nr = PAGE_CACHE_SIZE >> vol->mft_record_size_bits;
+       BUG_ON(!nr);
+       ntfs_debug("Entering for %i inodes starting at 0x%lx.", nr, mft_no);
+       /* Iterate over the mft records in the page looking for a dirty one. */
+       maddr = (u8*)kmap(page);
+       for (i = 0; i < nr; ++i, ++mft_no, maddr += vol->mft_record_size) {
+               struct inode *vi;
+               ntfs_inode *ni, *eni;
+               ntfs_attr na;
+
+               na.mft_no = mft_no;
+               na.name = NULL;
+               na.name_len = 0;
+               na.type = AT_UNUSED;
+               /*
+                * Check if the inode corresponding to this mft record is in
+                * the VFS inode cache and obtain a reference to it if it is.
+                */
+               ntfs_debug("Looking for inode 0x%lx in icache.", mft_no);
+               /*
+                * For inode 0, i.e. $MFT itself, we cannot use ilookup5() from
+                * here or we deadlock because the inode is already locked by
+                * the kernel (fs/fs-writeback.c::__sync_single_inode()) and
+                * ilookup5() waits until the inode is unlocked before
+                * returning it and it never gets unlocked because
+                * ntfs_mft_writepage() never returns.  )-:  Fortunately, we
+                * have inode 0 pinned in icache for the duration of the mount
+                * so we can access it directly.
+                */
+               if (!mft_no) {
+                       /* Balance the below iput(). */
+                       vi = igrab(mft_vi);
+                       BUG_ON(vi != mft_vi);
+               } else
+                       vi = ilookup5(sb, mft_no, (test_t)ntfs_test_inode, &na);
+               if (vi) {
+                       ntfs_debug("Inode 0x%lx is in icache.", mft_no);
+                       /* The inode is in icache.  Check if it is dirty. */
+                       ni = NTFS_I(vi);
+                       if (!NInoDirty(ni)) {
+                               /* The inode is not dirty, skip this record. */
+                               ntfs_debug("Inode 0x%lx is not dirty, "
+                                               "continuing search.", mft_no);
+                               iput(vi);
+                               continue;
+                       }
+                       ntfs_debug("Inode 0x%lx is dirty, aborting search.",
+                                       mft_no);
+                       /* The inode is dirty, no need to search further. */
+                       iput(vi);
+                       is_dirty = TRUE;
+                       break;
+               }
+               ntfs_debug("Inode 0x%lx is not in icache.", mft_no);
+               /* The inode is not in icache. */
+               /* Skip the record if it is not a mft record (type "FILE"). */
+               if (!ntfs_is_mft_recordp(maddr)) {
+                       ntfs_debug("Mft record 0x%lx is not a FILE record, "
+                                       "continuing search.", mft_no);
+                       continue;
+               }
+               m = (MFT_RECORD*)maddr;
+               /*
+                * Skip the mft record if it is not in use.  FIXME:  What about
+                * deleted/deallocated (extent) inodes?  (AIA)
+                */
+               if (!(m->flags & MFT_RECORD_IN_USE)) {
+                       ntfs_debug("Mft record 0x%lx is not in use, "
+                                       "continuing search.", mft_no);
+                       continue;
+               }
+               /* Skip the mft record if it is a base inode. */
+               if (!m->base_mft_record) {
+                       ntfs_debug("Mft record 0x%lx is a base record, "
+                                       "continuing search.", mft_no);
+                       continue;
+               }
+               /*
+                * This is an extent mft record.  Check if the inode
+                * corresponding to its base mft record is in icache.
+                */
+               na.mft_no = MREF_LE(m->base_mft_record);
+               ntfs_debug("Mft record 0x%lx is an extent record.  Looking "
+                               "for base inode 0x%lx in icache.", mft_no,
+                               na.mft_no);
+               vi = ilookup5(sb, na.mft_no, (test_t)ntfs_test_inode,
+                               &na);
+               if (!vi) {
+                       /*
+                        * The base inode is not in icache.  Skip this extent
+                        * mft record.
+                        */
+                       ntfs_debug("Base inode 0x%lx is not in icache, "
+                                       "continuing search.", na.mft_no);
+                       continue;
+               }
+               ntfs_debug("Base inode 0x%lx is in icache.", na.mft_no);
+               /*
+                * The base inode is in icache.  Check if it has the extent
+                * inode corresponding to this extent mft record attached.
+                */
+               ni = NTFS_I(vi);
+               down(&ni->extent_lock);
+               if (ni->nr_extents <= 0) {
+                       /*
+                        * The base inode has no attached extent inodes.  Skip
+                        * this extent mft record.
+                        */
+                       up(&ni->extent_lock);
+                       iput(vi);
+                       continue;
+               }
+               /* Iterate over the attached extent inodes. */
+               extent_nis = ni->ext.extent_ntfs_inos;
+               for (eni = NULL, j = 0; j < ni->nr_extents; ++j) {
+                       if (mft_no == extent_nis[j]->mft_no) {
+                               /*
+                                * Found the extent inode corresponding to this
+                                * extent mft record.
+                                */
+                               eni = extent_nis[j];
+                               break;
+                       }
+               }
+               /*
+                * If the extent inode was not attached to the base inode, skip
+                * this extent mft record.
+                */
+               if (!eni) {
+                       up(&ni->extent_lock);
+                       iput(vi);
+                       continue;
+               }
+               /*
+                * Found the extent inode corrsponding to this extent mft
+                * record.  If it is dirty, no need to search further.
+                */
+               if (NInoDirty(eni)) {
+                       up(&ni->extent_lock);
+                       iput(vi);
+                       is_dirty = TRUE;
+                       break;
+               }
+               /* The extent inode is not dirty, so do the next record. */
+               up(&ni->extent_lock);
+               iput(vi);
+       }
+       kunmap(page);
+       /* If a dirty mft record was found, redirty the page. */
+       if (is_dirty) {
+               ntfs_debug("Inode 0x%lx is dirty.  Redirtying the page "
+                               "starting at inode 0x%lx.", mft_no,
+                               page->index << (PAGE_CACHE_SHIFT -
+                               vol->mft_record_size_bits));
+               redirty_page_for_writepage(wbc, page);
+               unlock_page(page);
+       } else {
+               /*
+                * Keep the VM happy.  This must be done otherwise the
+                * radix-tree tag PAGECACHE_TAG_DIRTY remains set even though
+                * the page is clean.
+                */
+               BUG_ON(PageWriteback(page));
+               set_page_writeback(page);
+               unlock_page(page);
+               end_page_writeback(page);
+       }
+       ntfs_debug("Done.");
+       return 0;
+}
+
+#endif /* NTFS_RW */
index d23724a..4fd9b5e 100644 (file)
@@ -57,6 +57,60 @@ static inline void flush_dcache_mft_record_page(ntfs_inode *ni)
        flush_dcache_page(ni->page);
 }
 
+extern void __mark_mft_record_dirty(ntfs_inode *ni);
+
+/**
+ * mark_mft_record_dirty - set the mft record and the page containing it dirty
+ * @ni:                ntfs inode describing the mapped mft record
+ *
+ * Set the mapped (extent) mft record of the (base or extent) ntfs inode @ni,
+ * as well as the page containing the mft record, dirty.  Also, mark the base
+ * vfs inode dirty.  This ensures that any changes to the mft record are
+ * written out to disk.
+ *
+ * NOTE:  Do not do anything if the mft record is already marked dirty.
+ */
+static inline void mark_mft_record_dirty(ntfs_inode *ni)
+{
+       if (!NInoTestSetDirty(ni))
+               __mark_mft_record_dirty(ni);
+}
+
+extern int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync);
+
+/**
+ * write_mft_record - write out a mapped (extent) mft record
+ * @ni:                ntfs inode describing the mapped (extent) mft record
+ * @m:         mapped (extent) mft record to write
+ * @sync:      if true, wait for i/o completion
+ *
+ * This is just a wrapper for write_mft_record_nolock() (see mft.c), which
+ * locks the page for the duration of the write.  This ensures that there are
+ * no race conditions between writing the mft record via the dirty inode code
+ * paths and via the page cache write back code paths or between writing
+ * neighbouring mft records residing in the same page.
+ *
+ * Locking the page also serializes us against ->readpage() if the page is not
+ * uptodate.
+ *
+ * On success, clean the mft record and return 0.  On error, leave the mft
+ * record dirty and return -errno.  The caller should call make_bad_inode() on
+ * the base inode to ensure no more access happens to this inode.  We do not do
+ * it here as the caller may want to finish writing other extent mft records
+ * first to minimize on-disk metadata inconsistencies.
+ */
+static inline int write_mft_record(ntfs_inode *ni, MFT_RECORD *m, int sync)
+{
+       struct page *page = ni->page;
+       int err;
+
+       BUG_ON(!page);
+       lock_page(page);
+       err = write_mft_record_nolock(ni, m, sync);
+       unlock_page(page);
+       return err;
+}
+
 #endif /* NTFS_RW */
 
 #endif /* _LINUX_NTFS_MFT_H */
index 22939a5..4c3a32b 100644 (file)
@@ -291,6 +291,101 @@ needs_val:
        return FALSE;
 }
 
+#ifdef NTFS_RW
+
+/**
+ * ntfs_write_volume_flags - write new flags to the volume information flags
+ * @vol:       ntfs volume on which to modify the flags
+ * @flags:     new flags value for the volume information flags
+ *
+ * Internal function.  You probably want to use ntfs_{set,clear}_volume_flags()
+ * instead (see below).
+ *
+ * Replace the volume information flags on the volume @vol with the value
+ * supplied in @flags.  Note, this overwrites the volume information flags, so
+ * make sure to combine the flags you want to modify with the old flags and use
+ * the result when calling ntfs_write_volume_flags().
+ *
+ * Return 0 on success and -errno on error.
+ */
+static int ntfs_write_volume_flags(ntfs_volume *vol, const VOLUME_FLAGS flags)
+{
+       ntfs_inode *ni = NTFS_I(vol->vol_ino);
+       MFT_RECORD *m;
+       VOLUME_INFORMATION *vi;
+       attr_search_context *ctx;
+       int err;
+
+       ntfs_debug("Entering, old flags = 0x%x, new flags = 0x%x.",
+                       vol->vol_flags, flags);
+       if (vol->vol_flags == flags)
+               goto done;
+       BUG_ON(!ni);
+       m = map_mft_record(ni);
+       if (IS_ERR(m)) {
+               err = PTR_ERR(m);
+               goto err_out;
+       }
+       ctx = get_attr_search_ctx(ni, m);
+       if (!ctx) {
+               err = -ENOMEM;
+               goto put_unm_err_out;
+       }
+       if (!lookup_attr(AT_VOLUME_INFORMATION, NULL, 0, 0, 0, NULL, 0, ctx)) {
+               err = -EIO;
+               goto put_unm_err_out;
+       }
+       vi = (VOLUME_INFORMATION*)((u8*)ctx->attr +
+                       le16_to_cpu(ctx->attr->data.resident.value_offset));
+       vol->vol_flags = vi->flags = flags;
+       flush_dcache_mft_record_page(ctx->ntfs_ino);
+       mark_mft_record_dirty(ctx->ntfs_ino);
+       put_attr_search_ctx(ctx);
+       unmap_mft_record(ni);
+done:
+       ntfs_debug("Done.");
+       return 0;
+put_unm_err_out:
+       if (ctx)
+               put_attr_search_ctx(ctx);
+       unmap_mft_record(ni);
+err_out:
+       ntfs_error(vol->sb, "Failed with error code %i.", -err);
+       return err;
+}
+
+/**
+ * ntfs_set_volume_flags - set bits in the volume information flags
+ * @vol:       ntfs volume on which to modify the flags
+ * @flags:     flags to set on the volume
+ *
+ * Set the bits in @flags in the volume information flags on the volume @vol.
+ *
+ * Return 0 on success and -errno on error.
+ */
+static inline int ntfs_set_volume_flags(ntfs_volume *vol, VOLUME_FLAGS flags)
+{
+       flags &= VOLUME_FLAGS_MASK;
+       return ntfs_write_volume_flags(vol, vol->vol_flags | flags);
+}
+
+/**
+ * ntfs_clear_volume_flags - clear bits in the volume information flags
+ * @vol:       ntfs volume on which to modify the flags
+ * @flags:     flags to clear on the volume
+ *
+ * Clear the bits in @flags in the volume information flags on the volume @vol.
+ *
+ * Return 0 on success and -errno on error.
+ */
+static inline int ntfs_clear_volume_flags(ntfs_volume *vol, VOLUME_FLAGS flags)
+{
+       flags &= VOLUME_FLAGS_MASK;
+       return ntfs_write_volume_flags(vol, vol->vol_flags & ~flags);
+}
+
+#endif /* NTFS_RW */
+
 /**
  * ntfs_remount - change the mount options of a mounted ntfs filesystem
  * @sb:                superblock of mounted ntfs filesystem
@@ -316,30 +411,72 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
         * For the read-write compiled driver, if we are remounting read-write,
         * make sure there are no volume errors and that no unsupported volume
         * flags are set.  Also, empty the logfile journal as it would become
-        * stale as soon as something is written to the volume.
+        * stale as soon as something is written to the volume and mark the
+        * volume dirty so that chkdsk is run if the volume is not umounted
+        * cleanly.
+        *
+        * When remounting read-only, mark the volume clean if no volume errors
+        * have occured.
         */
        if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
                static const char *es = ".  Cannot remount read-write.";
 
+               /* Remounting read-write. */
                if (NVolErrors(vol)) {
                        ntfs_error(sb, "Volume has errors and is read-only%s",
                                        es);
                        return -EROFS;
                }
+               if (vol->vol_flags & VOLUME_IS_DIRTY) {
+                       ntfs_error(sb, "Volume is dirty and read-only%s", es);
+                       return -EROFS;
+               }
                if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
                        ntfs_error(sb, "Volume has unsupported flags set and "
                                        "is read-only%s", es);
                        return -EROFS;
                }
+               if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) {
+                       ntfs_error(sb, "Failed to set dirty bit in volume "
+                                       "information flags%s", es);
+                       return -EROFS;
+               }
+#if 0
+               // TODO: Enable this code once we start modifying anything that
+               //       is different between NTFS 1.2 and 3.x...
+               /* Set NT4 compatibility flag on newer NTFS version volumes. */
+               if ((vol->major_ver > 1)) {
+                       if (ntfs_set_volume_flags(vol, VOLUME_MOUNTED_ON_NT4)) {
+                               ntfs_error(sb, "Failed to set NT4 "
+                                               "compatibility flag%s", es);
+                               NVolSetErrors(vol);
+                               return -EROFS;
+                       }
+               }
+#endif
                if (!ntfs_empty_logfile(vol->logfile_ino)) {
                        ntfs_error(sb, "Failed to empty journal $LogFile%s",
                                        es);
                        NVolSetErrors(vol);
                        return -EROFS;
                }
+       } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {
+               /* Remounting read-only. */
+               if (!NVolErrors(vol)) {
+                       if (ntfs_clear_volume_flags(vol, VOLUME_IS_DIRTY))
+                               ntfs_warning(sb, "Failed to clear dirty bit "
+                                               "in volume information "
+                                               "flags.  Run chkdsk.");
+               }
        }
        // TODO:  For now we enforce no atime and dir atime updates as they are
        // not implemented.
+       if ((sb->s_flags & MS_NOATIME) && !(*flags & MS_NOATIME))
+               ntfs_warning(sb, "Atime updates are not implemented yet.  "
+                               "Leaving them disabled.");
+       else if ((sb->s_flags & MS_NODIRATIME) && !(*flags & MS_NODIRATIME))
+               ntfs_warning(sb, "Directory atime updates are not implemented "
+                               "yet.  Leaving them disabled.");
        *flags |= MS_NOATIME | MS_NODIRATIME;
 #endif /* ! NTFS_RW */
 
@@ -1131,7 +1268,7 @@ get_ctx_vol_failed:
                        le32_to_cpu(ctx->attr->data.resident.value_length) >
                        (u8*)ctx->attr + le32_to_cpu(ctx->attr->length))
                goto err_put_vol;
-       /* Setup volume flags and version. */
+       /* Copy the volume flags and version to the ntfs_volume structure. */
        vol->vol_flags = vi->flags;
        vol->major_ver = vi->major_ver;
        vol->minor_ver = vi->minor_ver;
@@ -1142,9 +1279,12 @@ get_ctx_vol_failed:
 #ifdef NTFS_RW
        /* Make sure that no unsupported volume flags are set. */
        if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
-               static const char *es1 = "Volume has unsupported flags set";
+               static const char *es1a = "Volume is dirty";
+               static const char *es1b = "Volume has unsupported flags set";
                static const char *es2 = ".  Run chkdsk and mount in Windows.";
-
+               const char *es1;
+               
+               es1 = vol->vol_flags & VOLUME_IS_DIRTY ? es1a : es1b;
                /* If a read-write mount, convert it to a read-only mount. */
                if (!(sb->s_flags & MS_RDONLY)) {
                        if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |
@@ -1171,10 +1311,12 @@ get_ctx_vol_failed:
         */
        if (!load_and_check_logfile(vol) ||
                        !ntfs_is_logfile_clean(vol->logfile_ino)) {
-               static const char *es1 = "Failed to load $LogFile";
-               static const char *es2 = "$LogFile is not clean";
-               static const char *es3 = ".  Mount in Windows.";
+               static const char *es1a = "Failed to load $LogFile";
+               static const char *es1b = "$LogFile is not clean";
+               static const char *es2 = ".  Mount in Windows.";
+               const char *es1;
 
+               es1 = !vol->logfile_ino ? es1a : es1b;
                /* If a read-write mount, convert it to a read-only mount. */
                if (!(sb->s_flags & MS_RDONLY)) {
                        if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |
@@ -1182,21 +1324,66 @@ get_ctx_vol_failed:
                                ntfs_error(sb, "%s and neither on_errors="
                                                "continue nor on_errors="
                                                "remount-ro was specified%s",
-                                               !vol->logfile_ino ? es1 : es2,
-                                               es3);
+                                               es1, es2);
                                goto iput_logfile_err_out;
                        }
                        sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
-                       ntfs_error(sb, "%s.  Mounting read-only%s",
-                                       !vol->logfile_ino ? es1 : es2, es3);
+                       ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
                } else
                        ntfs_warning(sb, "%s.  Will not be able to remount "
-                                       "read-write%s",
-                                       !vol->logfile_ino ? es1 : es2, es3);
+                                       "read-write%s", es1, es2);
                /* This will prevent a read-write remount. */
                NVolSetErrors(vol);
-       /* If a read-write mount, empty the logfile. */
-       } else if (!(sb->s_flags & MS_RDONLY) &&
+       }
+       /* If (still) a read-write mount, mark the volume dirty. */
+       if (!(sb->s_flags & MS_RDONLY) &&
+                       ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) {
+               static const char *es1 = "Failed to set dirty bit in volume "
+                               "information flags";
+               static const char *es2 = ".  Run chkdsk.";
+
+               /* Convert to a read-only mount. */
+               if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |
+                               ON_ERRORS_CONTINUE))) {
+                       ntfs_error(sb, "%s and neither on_errors=continue nor "
+                                       "on_errors=remount-ro was specified%s",
+                                       es1, es2);
+                       goto iput_logfile_err_out;
+               }
+               ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
+               sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+               /*
+                * Do not set NVolErrors() because ntfs_remount() might manage
+                * to set the dirty flag in which case all would be well.
+                */
+       }
+#if 0
+       // TODO: Enable this code once we start modifying anything that is
+       //       different between NTFS 1.2 and 3.x...
+       /*
+        * If (still) a read-write mount, set the NT4 compatibility flag on
+        * newer NTFS version volumes.
+        */
+       if (!(sb->s_flags & MS_RDONLY) && (vol->major_ver > 1) &&
+                       ntfs_set_volume_flags(vol, VOLUME_MOUNTED_ON_NT4)) {
+               static const char *es1 = "Failed to set NT4 compatibility flag";
+               static const char *es2 = ".  Run chkdsk.";
+
+               /* Convert to a read-only mount. */
+               if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |
+                               ON_ERRORS_CONTINUE))) {
+                       ntfs_error(sb, "%s and neither on_errors=continue nor "
+                                       "on_errors=remount-ro was specified%s",
+                                       es1, es2);
+                       goto iput_logfile_err_out;
+               }
+               ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
+               sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+               NVolSetErrors(vol);
+       }
+#endif
+       /* If (still) a read-write mount, empty the logfile. */
+       if (!(sb->s_flags & MS_RDONLY) &&
                        !ntfs_empty_logfile(vol->logfile_ino)) {
                static const char *es1 = "Failed to empty $LogFile";
                static const char *es2 = ".  Mount in Windows.";
@@ -1209,12 +1396,11 @@ get_ctx_vol_failed:
                                        es1, es2);
                        goto iput_logfile_err_out;
                }
-               sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
                ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
-               /* This will prevent a read-write remount. */
+               sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
                NVolSetErrors(vol);
        }
-#endif
+#endif /* NTFS_RW */
        /*
         * Get the inode for the attribute definitions file and parse the
         * attribute definitions.
@@ -1289,18 +1475,69 @@ iput_mirr_err_out:
 
 /**
  * ntfs_put_super - called by the vfs to unmount a volume
- * @vfs_sb:    vfs superblock of volume to unmount
+ * @sb:                vfs superblock of volume to unmount
  *
  * ntfs_put_super() is called by the VFS (from fs/super.c::do_umount()) when
  * the volume is being unmounted (umount system call has been invoked) and it
  * releases all inodes and memory belonging to the NTFS specific part of the
  * super block.
  */
-static void ntfs_put_super(struct super_block *vfs_sb)
+static void ntfs_put_super(struct super_block *sb)
 {
-       ntfs_volume *vol = NTFS_SB(vfs_sb);
+       ntfs_volume *vol = NTFS_SB(sb);
 
        ntfs_debug("Entering.");
+#ifdef NTFS_RW
+       /*
+        * Commit all inodes while they are still open in case some of them
+        * cause others to be dirtied.
+        */
+       ntfs_commit_inode(vol->vol_ino);
+
+       /* NTFS 3.0+ specific. */
+       if (vol->major_ver >= 3) {
+               if (vol->secure_ino)
+                       ntfs_commit_inode(vol->secure_ino);
+       }
+
+       ntfs_commit_inode(vol->root_ino);
+
+       down_write(&vol->lcnbmp_lock);
+       ntfs_commit_inode(vol->lcnbmp_ino);
+       up_write(&vol->lcnbmp_lock);
+
+       down_write(&vol->mftbmp_lock);
+       ntfs_commit_inode(vol->mftbmp_ino);
+       up_write(&vol->mftbmp_lock);
+
+       if (vol->logfile_ino)
+               ntfs_commit_inode(vol->logfile_ino);
+
+       if (vol->mftmirr_ino)
+               ntfs_commit_inode(vol->mftmirr_ino);
+       ntfs_commit_inode(vol->mft_ino);
+
+       /*
+        * If a read-write mount and no volume errors have occured, mark the
+        * volume clean.  Also, re-commit all affected inodes.
+        */
+       if (!(sb->s_flags & MS_RDONLY)) {
+               if (!NVolErrors(vol)) {
+                       if (ntfs_clear_volume_flags(vol, VOLUME_IS_DIRTY))
+                               ntfs_warning(sb, "Failed to clear dirty bit "
+                                               "in volume information "
+                                               "flags.  Run chkdsk.");
+                       ntfs_commit_inode(vol->vol_ino);
+                       ntfs_commit_inode(vol->root_ino);
+                       if (vol->mftmirr_ino)
+                               ntfs_commit_inode(vol->mftmirr_ino);
+                       ntfs_commit_inode(vol->mft_ino);
+               } else {
+                       ntfs_warning(sb, "Volume has errors.  Leaving volume "
+                                       "marked dirty.  Run chkdsk.");
+               }
+       }
+#endif /* NTFS_RW */
 
        iput(vol->vol_ino);
        vol->vol_ino = NULL;
@@ -1331,11 +1568,47 @@ static void ntfs_put_super(struct super_block *vfs_sb)
                iput(vol->logfile_ino);
                vol->logfile_ino = NULL;
        }
-
        if (vol->mftmirr_ino) {
+               /* Re-commit the mft mirror and mft just in case. */
+               ntfs_commit_inode(vol->mftmirr_ino);
+               ntfs_commit_inode(vol->mft_ino);
                iput(vol->mftmirr_ino);
                vol->mftmirr_ino = NULL;
        }
+       /*
+        * If any dirty inodes are left, throw away all mft data page cache
+        * pages to allow a clean umount.  This should never happen any more
+        * due to mft.c::ntfs_mft_writepage() cleaning all the dirty pages as
+        * the underlying mft records are written out and cleaned.  If it does,
+        * happen anyway, we want to know...
+        */
+       ntfs_commit_inode(vol->mft_ino);
+       write_inode_now(vol->mft_ino, 1);
+       if (!list_empty(&sb->s_dirty)) {
+               const char *s1, *s2;
+
+               down(&vol->mft_ino->i_sem);
+               truncate_inode_pages(vol->mft_ino->i_mapping, 0);
+               up(&vol->mft_ino->i_sem);
+               write_inode_now(vol->mft_ino, 1);
+               if (!list_empty(&sb->s_dirty)) {
+                       static const char *_s1 = "inodes";
+                       static const char *_s2 = "";
+                       s1 = _s1;
+                       s2 = _s2;
+               } else {
+                       static const char *_s1 = "mft pages";
+                       static const char *_s2 = "They have been thrown "
+                                       "away.  ";
+                       s1 = _s1;
+                       s2 = _s2;
+               }
+               ntfs_error(sb, "Dirty %s found at umount time.  %sYou should "
+                               "run chkdsk.  Please email "
+                               "linux-ntfs-dev@lists.sourceforge.net and say "
+                               "that you saw this message.  Thank you.", s1,
+                               s2);
+       }
 #endif /* NTFS_RW */
 
        iput(vol->mft_ino);
@@ -1344,7 +1617,7 @@ static void ntfs_put_super(struct super_block *vfs_sb)
        vol->upcase_len = 0;
        /*
         * Decrease the number of mounts and destroy the global default upcase
-        * table if necessary. Also decrease the number of upcase users if we
+        * table if necessary.  Also decrease the number of upcase users if we
         * are a user.
         */
        down(&ntfs_lock);
@@ -1368,7 +1641,7 @@ static void ntfs_put_super(struct super_block *vfs_sb)
                unload_nls(vol->nls_map);
                vol->nls_map = NULL;
        }
-       vfs_sb->s_fs_info = NULL;
+       sb->s_fs_info = NULL;
        kfree(vol);
        return;
 }
@@ -1629,8 +1902,8 @@ struct super_operations ntfs_sops = {
 #ifdef NTFS_RW
        //.dirty_inode  = NULL,                 /* VFS: Called from
        //                                         __mark_inode_dirty(). */
-       //.write_inode  = NULL,                 /* VFS: Write dirty inode to
-       //                                         disk. */
+       .write_inode    = ntfs_write_inode,     /* VFS: Write dirty inode to
+                                                  disk. */
        //.drop_inode   = NULL,                 /* VFS: Called just after the
        //                                         inode reference count has
        //                                         been decreased to zero.
@@ -1719,8 +1992,12 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
 #ifndef NTFS_RW
        sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
 #else
-       // TODO:  For now we enforce no atime and dir atime updates as they are
-       // not implemented.
+       if (!(sb->s_flags & MS_NOATIME))
+               ntfs_warning(sb, "Atime updates are not implemented yet.  "
+                               "Disabling them.");
+       else if (!(sb->s_flags & MS_NODIRATIME))
+               ntfs_warning(sb, "Directory atime updates are not implemented "
+                               "yet.  Disabling them.");
        sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
 #endif
        /* Allocate a new ntfs_volume and place it in sb->s_fs_info. */
index cf379e6..7d74b00 100644 (file)
@@ -187,13 +187,6 @@ config LDM_DEBUG
 
          If unsure, say N.
 
-config NEC98_PARTITION
-       bool "NEC PC-9800 partition table support" if PARTITION_ADVANCED
-       default y if !PARTITION_ADVANCED && X86_PC9800
-       help
-         Say Y here if you would like to be able to read the hard disk
-         partition table format used by NEC PC-9800 machines.
-
 config SGI_PARTITION
        bool "SGI partition support" if PARTITION_ADVANCED
        default y if !PARTITION_ADVANCED && (SGI_IP22 || SGI_IP27)
index b16b949..cc107c3 100644 (file)
@@ -29,7 +29,6 @@
 #include "ldm.h"
 #include "mac.h"
 #include "msdos.h"
-#include "nec98.h"
 #include "osf.h"
 #include "sgi.h"
 #include "sun.h"
index 1a67374..e98505b 100644 (file)
@@ -389,8 +389,23 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
                put_dev_sector(sect);
                return 0;
        }
+
+       /*
+        * Now that the 55aa signature is present, this is probably
+        * either the boot sector of a FAT filesystem or a DOS-type
+        * partition table. Reject this in case the boot indicator
+        * is not 0 or 0x80.
+        */
        p = (struct partition *) (data + 0x1be);
+       for (slot = 1; slot <= 4; slot++, p++) {
+               if (p->boot_ind != 0 && p->boot_ind != 0x80) {
+                       put_dev_sector(sect);
+                       return 0;
+               }
+       }
+
 #ifdef CONFIG_EFI_PARTITION
+       p = (struct partition *) (data + 0x1be);
        for (slot = 1 ; slot <= 4 ; slot++, p++) {
                /* If this is an EFI GPT disk, msdos should ignore it. */
                if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) {
@@ -398,8 +413,8 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
                        return 0;
                }
        }
-       p = (struct partition *) (data + 0x1be);
 #endif
+       p = (struct partition *) (data + 0x1be);
 
        /*
         * Look for partitions in two passes:
index 6bfde43..bcd3fb4 100644 (file)
@@ -1162,7 +1162,7 @@ static struct inode_operations proc_task_inode_operations = {
 };
 
 #ifdef CONFIG_SECURITY
-static ssize_t proc_pid_attr_read(struct file * file, char * buf,
+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;
@@ -1199,7 +1199,7 @@ static ssize_t proc_pid_attr_read(struct file * file, char * buf,
        return count;
 }
 
-static ssize_t proc_pid_attr_write(struct file * file, const char * buf,
+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;
index 474bee8..549bc43 100644 (file)
@@ -288,18 +288,20 @@ static spinlock_t proc_inum_lock = SPIN_LOCK_UNLOCKED; /* protects the above */
  */
 static unsigned int get_inode_number(void)
 {
-       unsigned int i, inum = 0;
+       int i, inum = 0;
+       int error;
 
 retry:
        if (idr_pre_get(&proc_inum_idr, GFP_KERNEL) == 0)
                return 0;
 
        spin_lock(&proc_inum_lock);
-       i = idr_get_new(&proc_inum_idr, NULL);
+       error = idr_get_new(&proc_inum_idr, NULL, &i);
        spin_unlock(&proc_inum_lock);
-
-       if (i == -1)
+       if (error == -EAGAIN)
                goto retry;
+       else if (error)
+               return 0;
 
        inum = (i & MAX_ID_MASK) + PROC_DYNAMIC_FIRST;
 
index 60e38c7..2066d25 100644 (file)
@@ -47,7 +47,6 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
-#include <asm/pgalloc.h>
 #include <asm/tlb.h>
 #include <asm/div64.h>
 
index 2ffb492..7c7de91 100644 (file)
@@ -52,6 +52,8 @@ static int v1_read_dqblk(struct dquot *dquot)
 
        /* Now we are sure filp is valid */
        offset = v1_dqoff(dquot->dq_id);
+       /* Set structure to 0s in case read fails/is after end of file */
+       memset(&dqblk, 0, sizeof(struct v1_disk_dqblk));
        fs = get_fs();
        set_fs(KERNEL_DS);
        filp->f_op->read(filp, (char *)&dqblk, sizeof(struct v1_disk_dqblk), &offset);
index 8663901..ac92dc5 100644 (file)
@@ -30,6 +30,9 @@
 #define  _ALLOC_hashed_formatted_nodes 7
 #define  _ALLOC_old_way 8
 #define  _ALLOC_hundredth_slices 9
+#define  _ALLOC_dirid_groups 10
+#define  _ALLOC_oid_groups 11
+#define  _ALLOC_packing_groups 12
 
 #define  concentrating_formatted_nodes(s)      test_bit(_ALLOC_concentrating_formatted_nodes, &SB_ALLOC_OPTS(s))
 #define  displacing_large_files(s)             test_bit(_ALLOC_displacing_large_files, &SB_ALLOC_OPTS(s))
@@ -150,11 +153,6 @@ static int scan_bitmap_block (struct reiserfs_transaction_handle *th,
        __wait_on_buffer (bi->bh);
     }
 
-    /* If we know that first zero bit is only one or first zero bit is
-       closer to the end of bitmap than our start pointer */
-    if (bi->first_zero_hint > *beg || bi->free_count == 1)
-       *beg = bi->first_zero_hint;
-
     while (1) {
        cont:
        if (bi->free_count < min)
@@ -204,21 +202,12 @@ static int scan_bitmap_block (struct reiserfs_transaction_handle *th,
                    while (--i >= *beg)
                        reiserfs_test_and_clear_le_bit (i, bi->bh->b_data);
                    reiserfs_restore_prepared_buffer (s, bi->bh);
-                   *beg = max(org, (int)bi->first_zero_hint);
+                   *beg = org;
                    /* ... and search again in current block from beginning */
                    goto cont;  
                }
            }
            bi->free_count -= (end - *beg);
-
-           /* if search started from zero_hint bit, and zero hint have not
-                changed since, then we need to update first_zero_hint */
-           if ( bi->first_zero_hint >= *beg)
-               /* no point in looking for free bit if there is not any */
-               bi->first_zero_hint = (bi->free_count > 0 ) ?
-                       reiserfs_find_next_zero_le_bit
-                       ((unsigned long*)(bi->bh->b_data), s->s_blocksize << 3, end) : (s->s_blocksize << 3);
-
            journal_mark_dirty (th, s, bi->bh);
 
            /* free block count calculation */
@@ -231,7 +220,57 @@ static int scan_bitmap_block (struct reiserfs_transaction_handle *th,
            *beg = next;
        }
     }
-  }
+}
+
+static int bmap_hash_id(struct super_block *s, u32 id) {
+    char * hash_in = NULL;
+    unsigned long hash;
+    unsigned bm;
+
+    if (id <= 2) {
+       bm = 1;
+    } else {
+        hash_in = (char *)(&id);
+        hash = keyed_hash(hash_in, 4);
+       bm = hash % SB_BMAP_NR(s);
+       if (!bm)
+           bm = 1;
+    }
+    return bm;
+}
+
+/*
+ * hashes the id and then returns > 0 if the block group for the
+ * corresponding hash is full
+ */
+static inline int block_group_used(struct super_block *s, u32 id) {
+    int bm;
+    bm = bmap_hash_id(s, id);
+    if (SB_AP_BITMAP(s)[bm].free_count > ((s->s_blocksize << 3) * 60 / 100) ) {
+        return 0;
+    }
+    return 1;
+}
+
+/*
+ * the packing is returned in disk byte order
+ */
+u32 reiserfs_choose_packing(struct inode *dir) {
+    u32 packing;
+    if (TEST_OPTION(packing_groups, dir->i_sb)) {
+       u32 parent_dir = le32_to_cpu(INODE_PKEY(dir)->k_dir_id);
+       /*
+        * some versions of reiserfsck expect packing locality 1 to be
+        * special
+        */
+       if (parent_dir == 1 || block_group_used(dir->i_sb,parent_dir))
+            packing = INODE_PKEY(dir)->k_objectid;
+        else
+            packing = INODE_PKEY(dir)->k_dir_id;
+    } else
+        packing = INODE_PKEY(dir)->k_objectid;
+    return packing;
+}
   
 /* Tries to find contiguous zero bit window (given size) in given region of
  * bitmap and place new blocks there. Returns number of allocated blocks. */
@@ -255,8 +294,18 @@ static int scan_bitmap (struct reiserfs_transaction_handle *th,
     get_bit_address (s, *start, &bm, &off);
     get_bit_address (s, finish, &end_bm, &end_off);
 
-    // With this option set first we try to find a bitmap that is at least 10%
-    // free, and if that fails, then we fall back to old whole bitmap scanning
+    /* When the bitmap is more than 10% free, anyone can allocate.
+     * When it's less than 10% free, only files that already use the
+     * bitmap are allowed. Once we pass 80% full, this restriction
+     * is lifted.
+     *
+     * We do this so that files that grow later still have space close to
+     * their original allocation. This improves locality, and presumably
+     * performance as a result.
+     *
+     * This is only an allocation policy and does not make up for getting a
+     * bad hint. Decent hinting must be implemented for this to work well.
+     */
     if ( TEST_OPTION(skip_busy, s) && SB_FREE_BLOCKS(s) > SB_BLOCK_COUNT(s)/20 ) {
        for (;bm < end_bm; bm++, off = 0) {
            if ( ( off && (!unfm || (file_block != 0))) || SB_AP_BITMAP(s)[bm].free_count > (s->s_blocksize << 3) / 10 )
@@ -314,9 +363,6 @@ static void _reiserfs_free_block (struct reiserfs_transaction_handle *th,
                          "free_block (%s:%lu)[dev:blocknr]: bit already cleared",
                          reiserfs_bdevname (s), block);
     }
-    if (offset < apbi[nr].first_zero_hint) {
-      apbi[nr].first_zero_hint = offset;
-    }
     apbi[nr].free_count ++;
     journal_mark_dirty (th, s, apbi[nr].bh);
 
@@ -396,6 +442,14 @@ void reiserfs_discard_all_prealloc (struct reiserfs_transaction_handle *th)
        __discard_prealloc(th, ei);
     }
 }
+
+void reiserfs_init_alloc_options (struct super_block *s)
+{
+    set_bit (_ALLOC_skip_busy, &SB_ALLOC_OPTS(s));
+    set_bit (_ALLOC_dirid_groups, &SB_ALLOC_OPTS(s));
+    set_bit (_ALLOC_packing_groups, &SB_ALLOC_OPTS(s));
+}
+
 /* block allocator related options are parsed here */
 int reiserfs_parse_alloc_options(struct super_block * s, char * options)
 {
@@ -439,6 +493,18 @@ int reiserfs_parse_alloc_options(struct super_block * s, char * options)
            continue;
        }
 
+        if (!strcmp(this_char, "dirid_groups")) {
+           SET_OPTION(dirid_groups);
+           continue;
+        }
+        if (!strcmp(this_char, "oid_groups")) {
+           SET_OPTION(oid_groups);
+           continue;
+        }
+        if (!strcmp(this_char, "packing_groups")) {
+           SET_OPTION(packing_groups);
+           continue;
+        }
        if (!strcmp(this_char, "hashed_formatted_nodes")) {
            SET_OPTION(hashed_formatted_nodes);
            continue;
@@ -481,6 +547,7 @@ int reiserfs_parse_alloc_options(struct super_block * s, char * options)
        return 1;
       }
   
+    reiserfs_warning (s, "allocator options = [%08x]\n", SB_ALLOC_OPTS(s));
     return 0;
 }
   
@@ -503,17 +570,76 @@ static inline void new_hashed_relocation (reiserfs_blocknr_hint_t * hint)
     hint->search_start = hint->beg + keyed_hash(hash_in, 4) % (hint->end - hint->beg);
 }
 
-static inline void get_left_neighbor(reiserfs_blocknr_hint_t *hint)
+/*
+ * Relocation based on dirid, hashing them into a given bitmap block
+ * files. Formatted nodes are unaffected, a seperate policy covers them
+ */
+static void
+dirid_groups (reiserfs_blocknr_hint_t *hint)
+{
+    unsigned long hash;
+    __u32 dirid = 0;
+    int bm = 0;
+    struct super_block *sb = hint->th->t_super;
+    if (hint->inode)
+       dirid = le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id);
+    else if (hint->formatted_node)
+        dirid = hint->key.k_dir_id;
+
+    if (dirid) {
+       bm = bmap_hash_id(sb, dirid);
+       hash = bm * (sb->s_blocksize << 3);
+       /* give a portion of the block group to metadata */
+       if (hint->inode)
+           hash += sb->s_blocksize/2;
+       hint->search_start = hash;
+    }
+}
+
+/*
+ * Relocation based on oid, hashing them into a given bitmap block
+ * files. Formatted nodes are unaffected, a seperate policy covers them
+ */
+static void
+oid_groups (reiserfs_blocknr_hint_t *hint)
+{
+    if (hint->inode) {
+       unsigned long hash;
+       __u32 oid;
+       __u32 dirid;
+       int bm;
+
+       dirid = le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id);
+
+       /* keep the root dir and it's first set of subdirs close to
+        * the start of the disk
+        */
+       if (dirid <= 2)
+           hash = (hint->inode->i_sb->s_blocksize << 3);
+       else {
+           oid = le32_to_cpu(INODE_PKEY(hint->inode)->k_objectid);
+           bm = bmap_hash_id(hint->inode->i_sb, oid);
+           hash = bm * (hint->inode->i_sb->s_blocksize << 3);
+       }
+       hint->search_start = hash;
+    }
+}
+
+/* returns 1 if it finds an indirect item and gets valid hint info
+ * from it, otherwise 0
+ */
+static int get_left_neighbor(reiserfs_blocknr_hint_t *hint)
 {
     struct path * path;
     struct buffer_head * bh;
     struct item_head * ih;
     int pos_in_item;
     __u32 * item;
+    int ret = 0;
 
     if (!hint->path)           /* reiserfs code can call this function w/o pointer to path
                                 * structure supplied; then we rely on supplied search_start */
-       return;
+       return 0;
 
     path = hint->path;
     bh = get_last_bh(path);
@@ -534,15 +660,15 @@ static inline void get_left_neighbor(reiserfs_blocknr_hint_t *hint)
            int t=get_block_num(item,pos_in_item);
            if (t) {
                hint->search_start = t;
+               ret = 1;
                break;
            }
            pos_in_item --;
        }
-    } else {
-      }
+    }
 
     /* does result value fit into specified region? */
-    return;
+    return ret;
 }
 
 /* should be, if formatted node, then try to put on first part of the device
@@ -639,10 +765,12 @@ static inline void hundredth_slices (reiserfs_blocknr_hint_t * hint)
     }
 }
   
-static inline void determine_search_start(reiserfs_blocknr_hint_t *hint,
+static void determine_search_start(reiserfs_blocknr_hint_t *hint,
                                          int amount_needed)
 {
     struct super_block *s = hint->th->t_super;
+    int unfm_hint;
+
     hint->beg = 0;
     hint->end = SB_BLOCK_COUNT(s) - 1;
 
@@ -673,19 +801,14 @@ static inline void determine_search_start(reiserfs_blocknr_hint_t *hint,
        return;
     }
 
-    /* attempt to copy a feature from old block allocator code */
-    if (TEST_OPTION(old_hashed_relocation, s) && !hint->formatted_node) {
-       old_hashed_relocation(hint);
-    }
-
     /* if none of our special cases is relevant, use the left neighbor in the
        tree order of the new node we are allocating for */
     if (hint->formatted_node && TEST_OPTION(hashed_formatted_nodes,s)) {
-       hash_formatted_node(hint);
+        hash_formatted_node(hint);
        return;
-    } 
+    }
 
-    get_left_neighbor(hint);
+    unfm_hint = get_left_neighbor(hint);
 
     /* Mimic old block allocator behaviour, that is if VFS allowed for preallocation,
        new blocks are displaced based on directory ID. Also, if suggested search_start
@@ -710,10 +833,36 @@ static inline void determine_search_start(reiserfs_blocknr_hint_t *hint,
        return;
     }
 
-    if (TEST_OPTION(old_hashed_relocation, s))
+    /* old_hashed_relocation only works on unformatted */
+    if (!unfm_hint && !hint->formatted_node &&
+        TEST_OPTION(old_hashed_relocation, s))
+    {
        old_hashed_relocation(hint);
-    if (TEST_OPTION(new_hashed_relocation, s))
+    }
+    /* new_hashed_relocation works with both formatted/unformatted nodes */
+    if ((!unfm_hint || hint->formatted_node) &&
+        TEST_OPTION(new_hashed_relocation, s))
+    {
        new_hashed_relocation(hint);
+    }
+    /* dirid grouping works only on unformatted nodes */
+    if (!unfm_hint && !hint->formatted_node && TEST_OPTION(dirid_groups,s))
+    {
+        dirid_groups(hint);
+    }
+
+#ifdef DISPLACE_NEW_PACKING_LOCALITIES
+    if (hint->formatted_node && TEST_OPTION(dirid_groups,s))
+    {
+        dirid_groups(hint);
+    }
+#endif
+
+    /* oid grouping works only on unformatted nodes */
+    if (!unfm_hint && !hint->formatted_node && TEST_OPTION(oid_groups,s))
+    {
+        oid_groups(hint);
+    }
     return;
 }
 
@@ -738,13 +887,14 @@ static int determine_prealloc_size(reiserfs_blocknr_hint_t * hint)
 static inline int allocate_without_wrapping_disk (reiserfs_blocknr_hint_t * hint,
                                         b_blocknr_t * new_blocknrs,
                                         b_blocknr_t start, b_blocknr_t finish,
+                                        int min,
                                         int amount_needed, int prealloc_size)
 {
     int rest = amount_needed;
     int nr_allocated;
   
     while (rest > 0 && start <= finish) {
-       nr_allocated = scan_bitmap (hint->th, &start, finish, 1,
+       nr_allocated = scan_bitmap (hint->th, &start, finish, min,
                                    rest + prealloc_size, !hint->formatted_node,
                                    hint->block);
 
@@ -777,8 +927,9 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
     struct super_block *s = hint->th->t_super;
     b_blocknr_t start = hint->search_start;
     b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1;
-    int second_pass = 0;
+    int passno = 0;
     int nr_allocated = 0;
+    int bigalloc = 0;
 
     determine_prealloc_size(hint);
     if (!hint->formatted_node) {
@@ -797,32 +948,64 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
            if (quota_ret)
                hint->preallocate=hint->prealloc_size=0;
        }
+       /* for unformatted nodes, force large allocations */
+       bigalloc = amount_needed + hint->prealloc_size;
+       /* try to make things even */
+       if (bigalloc & 1 && hint->prealloc_size)
+           bigalloc--;
     }
 
-    while((nr_allocated
-         += allocate_without_wrapping_disk(hint, new_blocknrs + nr_allocated, start, finish,
-                                         amount_needed - nr_allocated, hint->prealloc_size))
-         < amount_needed) {
-
-       /* not all blocks were successfully allocated yet*/
-       if (second_pass) {      /* it was a second pass; we must free all blocks */
+    do {
+       /* in bigalloc mode, nr_allocated should stay zero until
+        * the entire allocation is filled
+        */
+       if (unlikely(bigalloc && nr_allocated)) {
+           reiserfs_warning(s, "bigalloc is %d, nr_allocated %d\n",
+           bigalloc, nr_allocated);
+           /* reset things to a sane value */
+           bigalloc = amount_needed - nr_allocated;
+       }
+       /*
+        * try pass 0 and pass 1 looking for a nice big
+        * contiguous allocation.  Then reset and look
+        * for anything you can find.
+        */
+       if (passno == 2 && bigalloc) {
+           passno = 0;
+           bigalloc = 0;
+       }
+       switch (passno++) {
+        case 0: /* Search from hint->search_start to end of disk */
+           start = hint->search_start;
+           finish = SB_BLOCK_COUNT(s) - 1;
+           break;
+        case 1: /* Search from hint->beg to hint->search_start */
+           start = hint->beg;
+           finish = hint->search_start;
+           break;
+       case 2: /* Last chance: Search from 0 to hint->beg */
+           start = 0;
+           finish = hint->beg;
+           break;
+       default: /* We've tried searching everywhere, not enough space */
+           /* Free the blocks */
            if (!hint->formatted_node) {
 #ifdef REISERQUOTA_DEBUG
                reiserfs_debug (s, "reiserquota: freeing (nospace) %d blocks id=%u", amount_needed + hint->prealloc_size - nr_allocated, hint->inode->i_uid);
 #endif
                DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated);     /* Free not allocated blocks */
            }
-           while (nr_allocated --)
+           while (nr_allocated --)
                reiserfs_free_block(hint->th, hint->inode, new_blocknrs[nr_allocated], !hint->formatted_node);
 
            return NO_DISK_SPACE;
-       } else {                /* refine search parameters for next pass */
-           second_pass = 1;
-           finish = start;
-           start = 0;
-           continue;
        }
-    }
+    } while ((nr_allocated += allocate_without_wrapping_disk (hint,
+                           new_blocknrs + nr_allocated, start, finish,
+                           bigalloc ? bigalloc : 1,
+                           amount_needed - nr_allocated,
+                           hint->prealloc_size))
+                       < amount_needed);
     if ( !hint->formatted_node &&
          amount_needed + hint->prealloc_size >
         nr_allocated + REISERFS_I(hint->inode)->i_prealloc_count) {
index 12090d1..887fab3 100644 (file)
@@ -64,6 +64,7 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
 
     /*  reiserfs_warning (inode->i_sb, "reiserfs_readdir 1: f_pos = %Ld", filp->f_pos);*/
 
+    path_to_entry.reada = PATH_READA;
     while (1) {
     research:
        /* search the directory item, containing entry with specified key */
index b74f710..1b1892c 100644 (file)
@@ -176,12 +176,13 @@ int reiserfs_allocate_blocks_for_region(
     hint.formatted_node = 0; // We are allocating blocks for unformatted node.
 
     /* only preallocate if this is a small write */
-    if (blocks_to_allocate <
-        REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize)
+    if (REISERFS_I(inode)->i_prealloc_count ||
+       (!(write_bytes & (inode->i_sb->s_blocksize -1)) &&
+        blocks_to_allocate <
+        REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize))
         hint.preallocate = 1;
     else
         hint.preallocate = 0;
-
     /* Call block allocator to allocate blocks */
     res = reiserfs_allocate_blocknrs(&hint, allocated_blocks, blocks_to_allocate, blocks_to_allocate);
     if ( res != CARRY_ON ) {
@@ -467,6 +468,12 @@ retry:
     // the inode.
     //
     pathrelse(&path);
+    /*
+     * cleanup prellocation from previous writes
+     * if this is a partial block write
+     */
+    if (write_bytes & (inode->i_sb->s_blocksize -1))
+        reiserfs_discard_prealloc(th, inode);
     reiserfs_write_unlock(inode->i_sb);
 
     // go through all the pages/buffers and map the buffers to newly allocated
@@ -585,9 +592,19 @@ int reiserfs_commit_page(struct inode *inode, struct page *page,
     struct buffer_head *bh, *head;
     unsigned long i_size_index = inode->i_size >> PAGE_CACHE_SHIFT;
     int new;
+    int logit = reiserfs_file_data_log(inode);
+    struct super_block *s = inode->i_sb;
+    int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
+    struct reiserfs_transaction_handle th;
+    th.t_trans_id = 0;
 
     blocksize = 1 << inode->i_blkbits;
 
+    if (logit) {
+       reiserfs_write_lock(s);
+       journal_begin(&th, s, bh_per_page + 1);
+       reiserfs_update_inode_transaction(inode);
+    }
     for(bh = head = page_buffers(page), block_start = 0;
         bh != head || !block_start;
        block_start=block_end, bh = bh->b_this_page)
@@ -601,7 +618,10 @@ int reiserfs_commit_page(struct inode *inode, struct page *page,
                    partial = 1;
        } else {
            set_buffer_uptodate(bh);
-           if (!buffer_dirty(bh)) {
+           if (logit) {
+               reiserfs_prepare_for_journal(s, bh, 1);
+               journal_mark_dirty(&th, s, bh);
+           } else if (!buffer_dirty(bh)) {
                mark_buffer_dirty(bh);
                /* do data=ordered on any page past the end
                 * of file and any buffer marked BH_New.
@@ -613,7 +633,10 @@ int reiserfs_commit_page(struct inode *inode, struct page *page,
            }
        }
     }
-
+    if (logit) {
+       journal_end(&th, s, bh_per_page + 1);
+       reiserfs_write_unlock(s);
+    }
     /*
      * If this is a partial write which happened to make all buffers
      * uptodate then we can optimize away a bogus readpage() for
@@ -1254,6 +1277,7 @@ ssize_t reiserfs_file_write( struct file *file, /* the file we are going to writ
        journal_end(&th, th.t_super, th.t_blocks_allocated);
         reiserfs_write_unlock(inode->i_sb);
     }
+
     if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
        res = generic_osync_inode(inode, file->f_mapping, OSYNC_METADATA|OSYNC_DATA);
 
index 68050af..2c0c068 100644 (file)
@@ -1660,7 +1660,7 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th,
     sb = dir->i_sb;
 
     /* item head of new item */
-    ih.ih_key.k_dir_id = INODE_PKEY (dir)->k_objectid;
+    ih.ih_key.k_dir_id = reiserfs_choose_packing(dir);
     ih.ih_key.k_objectid = cpu_to_le32 (reiserfs_get_unused_objectid (th));
     if (!ih.ih_key.k_objectid) {
        err = -ENOMEM;
@@ -1729,7 +1729,6 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th,
        err = -EEXIST;
        goto out_bad_inode;
     }
-
     if (old_format_only (sb)) {
        if (inode->i_uid & ~0xffff || inode->i_gid & ~0xffff) {
            pathrelse (&path_to_key);
@@ -2148,6 +2147,11 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control
     struct buffer_head *head, *bh;
     int partial = 0 ;
     int nr = 0;
+    int checked = PageChecked(page);
+    struct reiserfs_transaction_handle th;
+    struct super_block *s = inode->i_sb;
+    int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
+    th.t_trans_id = 0;
 
     /* The page dirty bit is cleared before writepage is called, which
      * means we have to tell create_empty_buffers to make dirty buffers
@@ -2155,7 +2159,7 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control
      * in the BH_Uptodate is just a sanity check.
      */
     if (!page_has_buffers(page)) {
-       create_empty_buffers(page, inode->i_sb->s_blocksize, 
+       create_empty_buffers(page, s->s_blocksize,
                            (1 << BH_Dirty) | (1 << BH_Uptodate));
     }
     head = page_buffers(page) ;
@@ -2179,10 +2183,10 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control
        kunmap_atomic(kaddr, KM_USER0) ;
     }
     bh = head ;
-    block = page->index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits) ;
+    block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits) ;
     /* first map all the buffers, logging any direct items we find */
     do {
-       if (buffer_dirty(bh) && (!buffer_mapped(bh) ||
+       if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) ||
           (buffer_mapped(bh) && bh->b_blocknr == 0))) {
            /* not mapped yet, or it points to a direct item, search
             * the btree for the mapping info, and log any direct
@@ -2196,6 +2200,18 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control
        block++;
     } while(bh != head) ;
 
+    /*
+     * we start the transaction after map_block_for_writepage,
+     * because it can create holes in the file (an unbounded operation).
+     * starting it here, we can make a reliable estimate for how many
+     * blocks we're going to log
+     */
+    if (checked) {
+       ClearPageChecked(page);
+       reiserfs_write_lock(s);
+       journal_begin(&th, s, bh_per_page + 1);
+       reiserfs_update_inode_transaction(inode);
+    }
     /* now go through and lock any dirty buffers on the page */
     do {
        get_bh(bh);
@@ -2204,6 +2220,11 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control
        if (buffer_mapped(bh) && bh->b_blocknr == 0)
            continue;
 
+       if (checked) {
+           reiserfs_prepare_for_journal(s, bh, 1);
+           journal_mark_dirty(&th, s, bh);
+           continue;
+       }
        /* from this point on, we know the buffer is mapped to a
         * real block and not a direct item
         */
@@ -2222,6 +2243,10 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control
        }
     } while((bh = bh->b_this_page) != head);
 
+    if (checked) {
+       journal_end(&th, s, bh_per_page + 1);
+       reiserfs_write_unlock(s);
+    }
     BUG_ON(PageWriteback(page));
     set_page_writeback(page);
     unlock_page(page);
@@ -2481,17 +2506,15 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh)
     /* the page is locked, and the only places that log a data buffer
      * also lock the page.
      */
-#if 0
     if (reiserfs_file_data_log(inode)) {
-       /* very conservative, leave the buffer pinned if anyone might need it.
-       ** this should be changed to drop the buffer if it is only in the
-       ** current transaction
-       */
+       /*
+        * very conservative, leave the buffer pinned if
+        * anyone might need it.
+        */
         if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
            ret = 0 ;
        }
     } else
-#endif
     if (buffer_dirty(bh) || buffer_locked(bh)) {
        struct reiserfs_journal_list *jl;
        struct reiserfs_jh *jh = bh->b_private;
@@ -2529,6 +2552,10 @@ static int reiserfs_invalidatepage(struct page *page, unsigned long offset)
     int ret = 1;
 
     BUG_ON(!PageLocked(page));
+
+    if (offset == 0)
+       ClearPageChecked(page);
+
     if (!page_has_buffers(page))
        goto out;
 
@@ -2562,6 +2589,15 @@ out:
     return ret;
 }
 
+static int reiserfs_set_page_dirty(struct page *page) {
+    struct inode *inode = page->mapping->host;
+    if (reiserfs_file_data_log(inode)) {
+       SetPageChecked(page);
+       return __set_page_dirty_nobuffers(page);
+    }
+    return __set_page_dirty_buffers(page);
+}
+
 /*
  * Returns 1 if the page's buffers were dropped.  The page is locked.
  *
@@ -2579,6 +2615,7 @@ static int reiserfs_releasepage(struct page *page, int unused_gfp_flags)
     struct buffer_head *bh ;
     int ret = 1 ;
 
+    WARN_ON(PageChecked(page));
     spin_lock(&j->j_dirty_buffers_lock) ;
     head = page_buffers(page) ;
     bh = head ;
@@ -2684,5 +2721,6 @@ struct address_space_operations reiserfs_address_space_operations = {
     .prepare_write = reiserfs_prepare_write,
     .commit_write = reiserfs_commit_write,
     .bmap = reiserfs_aop_bmap,
-    .direct_IO = reiserfs_direct_IO
+    .direct_IO = reiserfs_direct_IO,
+    .set_page_dirty = reiserfs_set_page_dirty,
 } ;
index 52e637f..7ced010 100644 (file)
@@ -1024,7 +1024,6 @@ static int flush_commit_list(struct super_block *s, struct reiserfs_journal_list
   up(&jl->j_commit_lock);
 put_jl:
   put_journal_list(s, jl);
-
   return 0 ;
 }
 
@@ -1544,14 +1543,18 @@ static int flush_used_journal_lists(struct super_block *s,
     unsigned long cur_len;
     int ret;
     int i;
+    int limit = 256;
     struct reiserfs_journal_list *tjl;
     struct reiserfs_journal_list *flush_jl;
     unsigned long trans_id;
 
     flush_jl = tjl = jl;
 
-    /* flush for 256 transactions or 256 blocks, whichever comes first */
-    for(i = 0 ; i < 256 && len < 256 ; i++) {
+    /* in data logging mode, try harder to flush a lot of blocks */
+    if (reiserfs_data_log(s))
+       limit = 1024;
+    /* flush for 256 transactions or limit blocks, whichever comes first */
+    for(i = 0 ; i < 256 && len < limit ; i++) {
        if (atomic_read(&tjl->j_commit_left) ||
            tjl->j_trans_id < jl->j_trans_id) {
            break;
@@ -3482,10 +3485,16 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, struct super_b
     /* copy all the real blocks into log area.  dirty log blocks */
     if (test_bit(BH_JDirty, &cn->bh->b_state)) {
       struct buffer_head *tmp_bh ;
+      char *addr;
+      struct page *page;
       tmp_bh =  journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
                       ((cur_write_start + jindex) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
       set_buffer_uptodate(tmp_bh);
-      memcpy(tmp_bh->b_data, cn->bh->b_data, cn->bh->b_size) ;  
+      page = cn->bh->b_page;
+      addr = kmap(page);
+      memcpy(tmp_bh->b_data, addr + offset_in_page(cn->bh->b_data),
+             cn->bh->b_size);
+      kunmap(page);
       mark_buffer_dirty(tmp_bh);
       jindex++ ;
       set_bit(BH_JDirty_wait, &(cn->bh->b_state)) ; 
index ab1c01d..768b36f 100644 (file)
@@ -596,26 +596,29 @@ static int is_tree_node (struct buffer_head * bh, int level)
 
 
 
-#ifdef SEARCH_BY_KEY_READA
+#define SEARCH_BY_KEY_READA 16
 
 /* The function is NOT SCHEDULE-SAFE! */
-static void search_by_key_reada (struct super_block * s, int blocknr)
+static void search_by_key_reada (struct super_block * s,
+                                 struct buffer_head **bh,
+                                unsigned long *b, int num)
 {
-    struct buffer_head * bh;
-  
-    if (blocknr == 0)
-       return;
-
-    bh = sb_getblk (s, blocknr);
+    int i,j;
   
-    if (!buffer_uptodate (bh)) {
-       ll_rw_block (READA, 1, &bh);
+    for (i = 0 ; i < num ; i++) {
+       bh[i] = sb_getblk (s, b[i]);
+    }
+    for (j = 0 ; j < i ; j++) {
+       /*
+        * note, this needs attention if we are getting rid of the BKL
+        * you have to make sure the prepared bit isn't set on this buffer
+        */
+       if (!buffer_uptodate(bh[j]))
+           ll_rw_block(READA, 1, bh + j);
+       brelse(bh[j]);
     }
-    bh->b_count --;
 }
 
-#endif
-
 /**************************************************************************
  * Algorithm   SearchByKey                                                *
  *             look for item in the Disk S+Tree by its key                *
@@ -657,6 +660,9 @@ int search_by_key (struct super_block * p_s_sb,
     int                                n_node_level, n_retval;
     int                        right_neighbor_of_leaf_node;
     int                                fs_gen;
+    struct buffer_head *reada_bh[SEARCH_BY_KEY_READA];
+    unsigned long      reada_blocks[SEARCH_BY_KEY_READA];
+    int reada_count = 0;
 
 #ifdef CONFIG_REISERFS_CHECK
     int n_repeat_counter = 0;
@@ -691,19 +697,25 @@ int search_by_key (struct super_block * p_s_sb,
        p_s_last_element = PATH_OFFSET_PELEMENT(p_s_search_path, ++p_s_search_path->path_length);
        fs_gen = get_generation (p_s_sb);
 
-#ifdef SEARCH_BY_KEY_READA
-       /* schedule read of right neighbor */
-       search_by_key_reada (p_s_sb, right_neighbor_of_leaf_node);
-#endif
-
        /* Read the next tree node, and set the last element in the path to
            have a pointer to it. */
-       if ( ! (p_s_bh = p_s_last_element->pe_buffer =
-               sb_bread(p_s_sb, n_block_number)) ) {
+       if ((p_s_bh = p_s_last_element->pe_buffer =
+            sb_getblk(p_s_sb, n_block_number)) ) {
+           if (!buffer_uptodate(p_s_bh) && reada_count > 1) {
+               search_by_key_reada (p_s_sb, reada_bh,
+                                    reada_blocks, reada_count);
+           }
+           ll_rw_block(READ, 1, &p_s_bh);
+           wait_on_buffer(p_s_bh);
+           if (!buffer_uptodate(p_s_bh))
+               goto io_error;
+       } else {
+io_error:
            p_s_search_path->path_length --;
            pathrelse(p_s_search_path);
            return IO_ERROR;
        }
+       reada_count = 0;
        if (expected_level == -1)
                expected_level = SB_TREE_HEIGHT (p_s_sb);
        expected_level --;
@@ -784,11 +796,36 @@ int search_by_key (struct super_block * p_s_sb,
           position in the node. */
        n_block_number = B_N_CHILD_NUM(p_s_bh, p_s_last_element->pe_position);
 
-#ifdef SEARCH_BY_KEY_READA
-       /* if we are going to read leaf node, then calculate its right neighbor if possible */
-       if (n_node_level == DISK_LEAF_NODE_LEVEL + 1 && p_s_last_element->pe_position < B_NR_ITEMS (p_s_bh))
-           right_neighbor_of_leaf_node = B_N_CHILD_NUM(p_s_bh, p_s_last_element->pe_position + 1);
-#endif
+       /* if we are going to read leaf nodes, try for read ahead as well */
+       if ((p_s_search_path->reada & PATH_READA) &&
+           n_node_level == DISK_LEAF_NODE_LEVEL + 1)
+       {
+           int pos = p_s_last_element->pe_position;
+           int limit = B_NR_ITEMS(p_s_bh);
+           struct key *le_key;
+
+           if (p_s_search_path->reada & PATH_READA_BACK)
+               limit = 0;
+           while(reada_count < SEARCH_BY_KEY_READA) {
+               if (pos == limit)
+                   break;
+               reada_blocks[reada_count++] = B_N_CHILD_NUM(p_s_bh, pos);
+               if (p_s_search_path->reada & PATH_READA_BACK)
+                   pos--;
+               else
+                   pos++;
+
+               /*
+                * check to make sure we're in the same object
+                */
+               le_key = B_N_PDELIM_KEY(p_s_bh, pos);
+               if (le32_to_cpu(le_key->k_objectid) !=
+                   p_s_key->on_disk_key.k_objectid)
+               {
+                   break;
+               }
+           }
+        }
     }
 }
 
@@ -1458,6 +1495,41 @@ void reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inod
     reiserfs_delete_solid_item (th, inode, INODE_PKEY (inode));
 }
 
+static void
+unmap_buffers(struct page *page, loff_t pos) {
+    struct buffer_head *bh ;
+    struct buffer_head *head ;
+    struct buffer_head *next ;
+    unsigned long tail_index ;
+    unsigned long cur_index ;
+
+    if (page) {
+       if (page_has_buffers(page)) {
+           tail_index = pos & (PAGE_CACHE_SIZE - 1) ;
+           cur_index = 0 ;
+           head = page_buffers(page) ;
+           bh = head ;
+           do {
+               next = bh->b_this_page ;
+
+               /* we want to unmap the buffers that contain the tail, and
+               ** all the buffers after it (since the tail must be at the
+               ** end of the file).  We don't want to unmap file data
+               ** before the tail, since it might be dirty and waiting to
+               ** reach disk
+               */
+               cur_index += bh->b_size ;
+               if (cur_index > tail_index) {
+                   reiserfs_unmap_buffer(bh) ;
+               }
+               bh = next ;
+           } while (bh != head) ;
+           if ( PAGE_SIZE == bh->b_size ) {
+               clear_page_dirty(page);
+           }
+       }
+    }
+}
 
 static int maybe_indirect_to_direct (struct reiserfs_transaction_handle *th, 
                              struct inode * p_s_inode,
@@ -1550,7 +1622,7 @@ int reiserfs_cut_from_item (struct reiserfs_transaction_handle *th,
     char                c_mode;            /* Mode of the balance. */
     int retval2 = -1;
     int quota_cut_bytes;
-    
+    loff_t tail_pos = 0;
     
     init_tb_struct(th, &s_cut_balance, p_s_inode->i_sb, p_s_path, n_cut_size);
 
@@ -1590,6 +1662,7 @@ int reiserfs_cut_from_item (struct reiserfs_transaction_handle *th,
            set_cpu_key_k_type (p_s_item_key, TYPE_INDIRECT);
            p_s_item_key->key_length = 4;
            n_new_file_size -= (n_new_file_size & (p_s_sb->s_blocksize - 1));
+           tail_pos = n_new_file_size;
            set_cpu_key_k_offset (p_s_item_key, n_new_file_size + 1);
            if ( search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) == POSITION_NOT_FOUND ){
                print_block (PATH_PLAST_BUFFER (p_s_path), 3, PATH_LAST_POSITION (p_s_path) - 1, PATH_LAST_POSITION (p_s_path) + 1);
@@ -1687,9 +1760,10 @@ int reiserfs_cut_from_item (struct reiserfs_transaction_handle *th,
     if ( n_is_inode_locked ) {
        /* we've done an indirect->direct conversion.  when the data block
        ** was freed, it was removed from the list of blocks that must
-       ** be flushed before the transaction commits, so we don't need to
-       ** deal with it here.
+       ** be flushed before the transaction commits, make sure to
+       ** unmap and invalidate it
        */
+       unmap_buffers(page, tail_pos);
        REISERFS_I(p_s_inode)->i_flags &= ~i_pack_on_close_mask ;
     }
 #ifdef REISERQUOTA_DEBUG
@@ -1778,6 +1852,12 @@ void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
            space, this file would have this file size */
        n_file_size = offset + bytes - 1;
     }
+    /*
+     * are we doing a full truncate or delete, if so
+     * kick in the reada code
+     */
+    if (n_new_file_size == 0)
+        s_search_path.reada = PATH_READA | PATH_READA_BACK;
 
     if ( n_file_size == 0 || n_file_size < n_new_file_size ) {
        goto update_and_out ;
index 8872bad..3bed8d0 100644 (file)
@@ -492,7 +492,6 @@ static void reiserfs_clear_inode (struct inode *inode)
     REISERFS_I(inode)->i_acl_default = NULL;
 }
 
-
 struct super_operations reiserfs_sops = 
 {
   .alloc_inode = reiserfs_alloc_inode,
@@ -651,7 +650,7 @@ static int reiserfs_getopt ( struct super_block * s, char ** cur, opt_desc_t * o
        reiserfs_warning (s, "head of option \"%s\" is only correct", opt->option_name);
        return -1;
     }
-       
+
     /* move to the argument, or to next option if argument is not required */
     p ++;
     
@@ -1345,15 +1344,17 @@ static int reiserfs_fill_super (struct super_block * s, void * data, int silent)
     memset (sbi, 0, sizeof (struct reiserfs_sb_info));
     /* Set default values for options: non-aggressive tails */
     REISERFS_SB(s)->s_mount_opt = ( 1 << REISERFS_SMALLTAIL );
-    /* default block allocator option: skip_busy */
-    REISERFS_SB(s)->s_alloc_options.bits = ( 1 << 5);
-    /* If file grew past 4 blocks, start preallocation blocks for it. */
-    REISERFS_SB(s)->s_alloc_options.preallocmin = 4;
+    /* no preallocation minimum, be smart in
+       reiserfs_file_write instead */
+    REISERFS_SB(s)->s_alloc_options.preallocmin = 0;
     /* Preallocate by 16 blocks (17-1) at once */
     REISERFS_SB(s)->s_alloc_options.preallocsize = 17;
     /* Initialize the rwsem for xattr dir */
     init_rwsem(&REISERFS_SB(s)->xattr_dir_sem);
 
+    /* setup default block allocator options */
+    reiserfs_init_alloc_options(s);
+
     jdev_name = NULL;
     if (reiserfs_parse_options (s, (char *) data, &(sbi->s_mount_opt), &blocks, &jdev_name, &commit_max_age) == 0) {
        goto error;
index 29e6a7c..bbc0e50 100644 (file)
@@ -162,42 +162,6 @@ void reiserfs_unmap_buffer(struct buffer_head *bh) {
     unlock_buffer(bh) ;
 }
 
-static void
-unmap_buffers(struct page *page, loff_t pos) {
-  struct buffer_head *bh ;
-  struct buffer_head *head ;
-  struct buffer_head *next ;
-  unsigned long tail_index ;
-  unsigned long cur_index ;
-
-  if (page) {
-    if (page_has_buffers(page)) {
-      tail_index = pos & (PAGE_CACHE_SIZE - 1) ;
-      cur_index = 0 ;
-      head = page_buffers(page) ;
-      bh = head ;
-      do {
-       next = bh->b_this_page ;
-
-        /* we want to unmap the buffers that contain the tail, and
-        ** all the buffers after it (since the tail must be at the
-        ** end of the file).  We don't want to unmap file data 
-        ** before the tail, since it might be dirty and waiting to 
-        ** reach disk
-        */
-        cur_index += bh->b_size ;
-        if (cur_index > tail_index) {
-          reiserfs_unmap_buffer(bh) ;
-        }
-       bh = next ;
-      } while (bh != head) ;
-      if ( PAGE_SIZE == bh->b_size ) {
-       clear_page_dirty(page);
-      }
-    }
-  } 
-}
-
 /* this first locks inode (neither reads nor sync are permitted),
    reads tail through page cache, insert direct item. When direct item
    inserted successfully inode is left locked. Return value is always
@@ -287,11 +251,6 @@ int indirect2direct (struct reiserfs_transaction_handle *th,
     }
     kunmap(page) ;
 
-    /* this will invalidate all the buffers in the page after
-    ** pos1
-    */
-    unmap_buffers(page, pos1) ;
-
     /* make sure to get the i_blocks changes from reiserfs_insert_item */
     reiserfs_update_sd(th, p_s_inode);
 
index f1b17ac..12fc56c 100644 (file)
@@ -215,7 +215,7 @@ smb_updatepage(struct file *file, struct page *page, unsigned long offset,
 }
 
 static ssize_t
-smb_file_read(struct file * file, char * buf, size_t count, loff_t *ppos)
+smb_file_read(struct file * file, char __user * buf, size_t count, loff_t *ppos)
 {
        struct dentry * dentry = file->f_dentry;
        ssize_t status;
@@ -318,7 +318,7 @@ struct address_space_operations smb_file_aops = {
  * Write to a file (through the page cache).
  */
 static ssize_t
-smb_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+smb_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
        struct dentry * dentry = file->f_dentry;
        ssize_t result;
index 912c046..dbae1f8 100644 (file)
@@ -35,11 +35,11 @@ smb_ioctl(struct inode *inode, struct file *filp,
                uid_t uid32;
        case SMB_IOC_GETMOUNTUID:
                SET_UID(uid16, server->mnt->mounted_uid);
-               result = put_user(uid16, (uid16_t *) arg);
+               result = put_user(uid16, (uid16_t __user *) arg);
                break;
        case SMB_IOC_GETMOUNTUID32:
                SET_UID(uid32, server->mnt->mounted_uid);
-               result = put_user(uid32, (uid_t *) arg);
+               result = put_user(uid32, (uid_t __user *) arg);
                break;
 
        case SMB_IOC_NEWCONN:
@@ -56,7 +56,7 @@ smb_ioctl(struct inode *inode, struct file *filp,
                }
 
                result = -EFAULT;
-               if (!copy_from_user(&opt, (void *)arg, sizeof(opt)))
+               if (!copy_from_user(&opt, (void __user *)arg, sizeof(opt)))
                        result = smb_newconn(server, &opt);
                break;
        default:
index 2eefecb..6d8b287 100644 (file)
@@ -54,7 +54,7 @@ static int smbiod_start(void);
 /*
  * called when there's work for us to do
  */
-void smbiod_wake_up()
+void smbiod_wake_up(void)
 {
        if (smbiod_state == SMBIOD_DEAD)
                return;
index f28e994..6bda9bf 100644 (file)
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -131,6 +131,8 @@ static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * sta
        tmp.st_ino = stat->ino;
        tmp.st_mode = stat->mode;
        tmp.st_nlink = stat->nlink;
+       if (tmp.st_nlink != stat->nlink)
+               return -EOVERFLOW;
        SET_UID(tmp.st_uid, stat->uid);
        SET_GID(tmp.st_gid, stat->gid);
        tmp.st_rdev = old_encode_dev(stat->rdev);
@@ -199,6 +201,8 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
        tmp.st_ino = stat->ino;
        tmp.st_mode = stat->mode;
        tmp.st_nlink = stat->nlink;
+       if (tmp.st_nlink != stat->nlink)
+               return -EOVERFLOW;
        SET_UID(tmp.st_uid, stat->uid);
        SET_GID(tmp.st_gid, stat->gid);
 #if BITS_PER_LONG == 32
index 8d9bff1..ca60ada 100644 (file)
@@ -569,14 +569,19 @@ static spinlock_t unnamed_dev_lock = SPIN_LOCK_UNLOCKED;/* protects the above */
 int set_anon_super(struct super_block *s, void *data)
 {
        int dev;
+       int error;
 
-       spin_lock(&unnamed_dev_lock);
-       if (idr_pre_get(&unnamed_dev_idr, GFP_ATOMIC) == 0) {
-               spin_unlock(&unnamed_dev_lock);
+ retry:
+       if (idr_pre_get(&unnamed_dev_idr, GFP_ATOMIC) == 0)
                return -ENOMEM;
-       }
-       dev = idr_get_new(&unnamed_dev_idr, NULL);
+       spin_lock(&unnamed_dev_lock);
+       error = idr_get_new(&unnamed_dev_idr, NULL, &dev);
        spin_unlock(&unnamed_dev_lock);
+       if (error == -EAGAIN)
+               /* We raced and lost with another CPU. */
+               goto retry;
+       else if (error)
+               return -EAGAIN;
 
        if ((dev & MAX_ID_MASK) == (1 << MINORBITS)) {
                spin_lock(&unnamed_dev_lock);
index 47c98d0..72cd707 100644 (file)
@@ -89,6 +89,7 @@ static int fill_read_buffer(struct file * file, struct sysfs_buffer * buffer)
                return -ENOMEM;
 
        count = ops->show(kobj,attr,buffer->page);
+       BUG_ON(count > PAGE_SIZE);
        if (count >= 0)
                buffer->count = count;
        else
index 1dc900e..d95c6e3 100644 (file)
@@ -84,7 +84,7 @@ static uint16_t crc_table[256] = {
  *     July 21, 1997 - Andrew E. Mileski
  *     Adapted from OSTA-UDF(tm) 1.50 standard.
  */
-extern uint16_t
+uint16_t
 udf_crc(uint8_t *data, uint32_t size, uint16_t crc)
 {
        while (size--)
index 76ef18b..33640a9 100644 (file)
@@ -109,7 +109,7 @@ struct address_space_operations udf_adinicb_aops = {
        .commit_write           = udf_adinicb_commit_write,
 };
 
-static ssize_t udf_file_write(struct file * file, const char * buf,
+static ssize_t udf_file_write(struct file * file, const char __user * buf,
        size_t count, loff_t *ppos)
 {
        ssize_t retval;
@@ -204,26 +204,26 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
        switch (cmd)
        {
                case UDF_GETVOLIDENT:
-                       return copy_to_user((char *)arg,
+                       return copy_to_user((char __user *)arg,
                                UDF_SB_VOLIDENT(inode->i_sb), 32) ? -EFAULT : 0;
                case UDF_RELOCATE_BLOCKS:
                {
                        long old, new;
 
                        if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-                       if (get_user(old, (long *)arg)) return -EFAULT;
+                       if (get_user(old, (long __user *)arg)) return -EFAULT;
                        if ((result = udf_relocate_blocks(inode->i_sb,
                                        old, &new)) == 0)
-                               result = put_user(new, (long *)arg);
+                               result = put_user(new, (long __user *)arg);
 
                        return result;
                }
                case UDF_GETEASIZE:
-                       result = put_user(UDF_I_LENEATTR(inode), (int *)arg);
+                       result = put_user(UDF_I_LENEATTR(inode), (int __user *)arg);
                        break;
 
                case UDF_GETEABLOCK:
-                       result = copy_to_user((char *)arg, UDF_I_DATA(inode),
+                       result = copy_to_user((char __user *)arg, UDF_I_DATA(inode),
                                UDF_I_LENEATTR(inode)) ? -EFAULT : 0;
                        break;
        }
index b6e1c25..174d7a3 100644 (file)
@@ -34,7 +34,7 @@
 #include "udf_i.h"
 #include "udf_sb.h"
 
-extern struct buffer_head *
+struct buffer_head *
 udf_tgetblk(struct super_block *sb, int block)
 {
        if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
@@ -43,7 +43,7 @@ udf_tgetblk(struct super_block *sb, int block)
                return sb_getblk(sb, block);
 }
 
-extern struct buffer_head *
+struct buffer_head *
 udf_tread(struct super_block *sb, int block)
 {
        if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
@@ -52,7 +52,7 @@ udf_tread(struct super_block *sb, int block)
                return sb_bread(sb, block);
 }
 
-extern struct genericFormat *
+struct genericFormat *
 udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type,
        uint8_t loc)
 {
@@ -157,7 +157,7 @@ udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type,
        return NULL;
 }
 
-extern struct genericFormat *
+struct genericFormat *
 udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype)
 {
        struct genericFormat *gaf;
@@ -207,7 +207,7 @@ udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype)
  *     July 1, 1997 - Andrew E. Mileski
  *     Written, tested, and released.
  */
-extern struct buffer_head *
+struct buffer_head *
 udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint16_t *ident)
 {
        tag *tag_p;
@@ -272,7 +272,7 @@ error_out:
        return NULL;
 }
 
-extern struct buffer_head *
+struct buffer_head *
 udf_read_ptagged(struct super_block *sb, lb_addr loc, uint32_t offset, uint16_t *ident)
 {
        return udf_read_tagged(sb, udf_get_lb_pblock(sb, loc, offset),
index fadb1c9..c4d9a8e 100644 (file)
@@ -55,7 +55,7 @@
 
 /* ACPI PCI Interrupt Link (pci_link.c) */
 
-int acpi_pci_link_check (void);
+int acpi_irq_penalty_init (void);
 int acpi_pci_link_get_irq (acpi_handle handle, int index, int* edge_level, int* active_high_low);
 
 /* ACPI PCI Interrupt Routing (pci_irq.c) */
index 558d177..b94759c 100644 (file)
 #define RLIMIT_AS      7               /* address space limit(?) */
 #define RLIMIT_NPROC   8               /* max number of processes */
 #define RLIMIT_MEMLOCK 9               /* max locked-in-memory address space */
-#define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 /*
  * SuS says limits have to be unsigned.  Fine, it's unsigned, but
     {INR_OPEN, INR_OPEN},                      /* RLIMIT_NOFILE */     \
     {LONG_MAX, LONG_MAX},                      /* RLIMIT_AS */         \
     {LONG_MAX, LONG_MAX},                      /* RLIMIT_NPROC */      \
-    {PAGE_SIZE,PAGE_SIZE},                     /* RLIMIT_MEMLOCK */    \
-    {LONG_MAX, LONG_MAX},                       /* RLIMIT_LOCKS */      \
+    {LONG_MAX, LONG_MAX},                      /* RLIMIT_MEMLOCK */    \
+    {LONG_MAX, LONG_MAX},                      /* RLIMIT_LOCKS */      \
+    {MAX_SIGPENDING, MAX_SIGPENDING},          /* RLIMIT_SIGPENDING */ \
+    {MQ_BYTES_MAX, MQ_BYTES_MAX},              /* RLIMIT_MSGQUEUE */   \
 }
 
 #endif /* __KERNEL__ */
index a7a1d4c..52030ab 100644 (file)
@@ -50,7 +50,7 @@ void __writel(u32 val, void *addr);
 #define writew(v,b)            __writew(v,b)
 #define writel(v,b)            __writel(v,b)
 
-#define __arch_ioremap(cookie,sz,c)    ((void *)(cookie))
+#define __arch_ioremap(cookie,sz,c,a)  ((void *)(cookie))
 #define __arch_iounmap(cookie)         do { } while (0)
 
 #endif
index 3afdb3d..d7c8fec 100644 (file)
@@ -25,13 +25,13 @@ static inline void arch_idle(void)
        const char *irq_stat = (char *)0xff000000;
 
        /* disable clock switching */
-       asm volatile ("mcr%? p15, 0, ip, c15, c2, 2");
+       asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc");
 
        /* wait for an interrupt to occur */
        while (!*irq_stat);
 
        /* enable clock switching */
-       asm volatile ("mcr%? p15, 0, ip, c15, c1, 2");
+       asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc");
 }
 
 #define arch_reset(mode)       cpu_reset(0x80000000)
index 6cdd6b5..1e9ef04 100644 (file)
@@ -15,5 +15,5 @@
  * This is therefore not used to calculate the
  * divisor.
  */
-//#define CLOCK_TICK_RATE              2000000
+#define CLOCK_TICK_RATE                47894000
 
index 3ff4bd0..8396e9a 100644 (file)
  */
 static void puts(const char *s)
 {
-       __asm__ __volatile__("
-       ldrb    %0, [%2], #1
-       teq     %0, #0
-       beq     3f
-1:     strb    %0, [%3]
-2:     ldrb    %1, [%3, #0x14]
-       and     %1, %1, #0x60
-       teq     %1, #0x60
-       bne     2b
-       teq     %0, #'\n'
-       moveq   %0, #'\r'
-       beq     1b
-       ldrb    %0, [%2], #1
-       teq     %0, #0
-       bne     1b
-3:     ldrb    %1, [%3, #0x14]
-       and     %1, %1, #0x60
-       teq     %1, #0x60
-       bne     3b
-       : : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc");
+       __asm__ __volatile__(
+       "ldrb   %0, [%2], #1\n"
+"      teq     %0, #0\n"
+"      beq     3f\n"
+"1:    strb    %0, [%3]\n"
+"2:    ldrb    %1, [%3, #0x14]\n"
+"      and     %1, %1, #0x60\n"
+"      teq     %1, #0x60\n"
+"      bne     2b\n"
+"      teq     %0, #'\n'\n"
+"      moveq   %0, #'\r'\n"
+"      beq     1b\n"
+"      ldrb    %0, [%2], #1\n"
+"      teq     %0, #0\n"
+"      bne     1b\n"
+"3:    ldrb    %1, [%3, #0x14]\n"
+"      and     %1, %1, #0x60\n"
+"      teq     %1, #0x60\n"
+"      bne     3b"
+       : : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc");
 }
 
 /*
index 178fbac..d75de4b 100644 (file)
@@ -14,6 +14,5 @@
 
 struct device;
 
-void impd1_set_vco(struct device *dev, int vconr, unsigned long period);
 void impd1_tweak_control(struct device *dev, u32 mask, u32 val);
 
index 40e0004..aeb07c1 100644 (file)
@@ -37,10 +37,10 @@ typedef struct { volatile u32 offset[4096]; } __regbase;
 # define __REGP(x)     ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2]
 # define __REG(x)      __REGP(io_p2v(x))
 typedef struct { volatile u16 offset[4096]; } __regbase16;
-# define __REGP16(x)   ((__regbase16 *)((x)&~4095))->offset[((x)&4095)>>2]
+# define __REGP16(x)   ((__regbase16 *)((x)&~4095))->offset[((x)&4095)>>1]
 # define __REG16(x)    __REGP16(io_p2v(x))
 typedef struct { volatile u8 offset[4096]; } __regbase8;
-# define __REGP8(x)    ((__regbase8 *)((x)&~4095))->offset[((x)&4095)>>2]
+# define __REGP8(x)    ((__regbase8 *)((x)&~4095))->offset[(x)&4095]
 # define __REG8(x)     __REGP8(io_p2v(x))
 #endif
 
index 1a1b1a3..3480cb7 100644 (file)
@@ -6,14 +6,14 @@
  *  modify it under the terms of the GNU General Public License
  *  version 2 as published by the Free Software Foundation.
  *
+ *
+ *  Refer to <file:Documentation/arm/Sharp-LH/SDRAM> for more information.
+ *
  */
 
 #ifndef __ASM_ARCH_MEMORY_H
 #define __ASM_ARCH_MEMORY_H
 
-
-#define BANKS_PER_NODE 1       /* Define as either 1 or 2 */
-
 /*
  * Physical DRAM offset.
  */
 #define __bus_to_virt(x)        __phys_to_virt(x)
 
 #ifdef CONFIG_DISCONTIGMEM
-/*
- * Because of the wide memory address space between physical RAM
- * banks, it's convenient to use Linux's NUMA support to represent our
- * memory map.  Assuming all memory nodes have equal access
- * characteristics, we then have a generic discontiguous memory setup.
- *
- * Of course, all this isn't mandatory for implementations with only
- * one used memory bank.  For those, simply undefine
- * CONFIG_DISCONTIGMEM.  However, keep in mind that a featurefull
- * system will need more than 4MiB of RAM.
- *
- * The contiguous memory blocks are small enough that it pays to
- * aggregate two banks into one node.  Setting BANKS_PER_NODE to 2
- * puts pairs of banks into a node.
- *
- * A typical layout would start like this:
- *
- *  node 0: 0xc0000000
- *          0xc1000000
- *  node 1: 0xc4000000
- *          0xc5000000
- *  node 2: 0xc8000000
- *          0xc9000000
- *
- * The proximity of the pairs of blocks makes it feasible to combine them.
- *
- */
 
 /*
  * Given a kernel address, find the home node of the underlying memory.
  */
 
-#if BANKS_PER_NODE==1
-#define KVADDR_TO_NID(addr) \
+# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE
+#  define KVADDR_TO_NID(addr) \
   (  ((((unsigned long) (addr) - PAGE_OFFSET) >> 24) &  1)\
    | ((((unsigned long) (addr) - PAGE_OFFSET) >> 25) & ~1))
-#else  /* 2 banks per node */
-#define KVADDR_TO_NID(addr) \
-       ((unsigned long) (addr) - PAGE_OFFSET) >> 26)
-#endif
+# else  /* 2 banks per node */
+#  define KVADDR_TO_NID(addr) \
+      (((unsigned long) (addr) - PAGE_OFFSET) >> 26)
+# endif
 
 /*
  * Given a page frame number, convert it to a node id.
  */
 
-#if BANKS_PER_NODE==1
-#define PFN_TO_NID(pfn) \
+# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE
+#  define PFN_TO_NID(pfn) \
   (((((pfn) - PHYS_PFN_OFFSET) >> (24 - PAGE_SHIFT)) &  1)\
  | ((((pfn) - PHYS_PFN_OFFSET) >> (25 - PAGE_SHIFT)) & ~1))
-#else  /* 2 banks per node */
-#define PFN_TO_NID(addr) \
+# else  /* 2 banks per node */
+#  define PFN_TO_NID(pfn) \
     (((pfn) - PHYS_PFN_OFFSET) >> (26 - PAGE_SHIFT))
 #endif
 
  * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
  * and return the mem_map of that node.
  */
-#define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
+# define ADDR_TO_MAPBASE(kaddr)        NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
 
 /*
  * Given a page frame number, find the owning node of the memory
  * and return the mem_map of that node.
  */
-#define PFN_TO_MAPBASE(pfn)    NODE_MEM_MAP(PFN_TO_NID(pfn))
+# define PFN_TO_MAPBASE(pfn)   NODE_MEM_MAP(PFN_TO_NID(pfn))
 
 /*
  * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
  * node's mem_map.
  */
 
-#if BANKS_PER_NODE==1
-#define LOCAL_MAP_NR(addr) \
+# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE
+#  define LOCAL_MAP_NR(addr) \
        (((unsigned long)(addr) & 0x003fffff) >> PAGE_SHIFT)
-#else  /* 2 banks per node */
-#define LOCAL_MAP_NR(addr) \
+# else  /* 2 banks per node */
+#  define LOCAL_MAP_NR(addr) \
        (((unsigned long)(addr) & 0x01ffffff) >> PAGE_SHIFT)
-#endif
+# endif
 
 #else
 
-#define PFN_TO_NID(addr)       (0)
+# define PFN_TO_NID(addr)      (0)
 
 #endif
 
index beb5055..50671ba 100644 (file)
  *  OMAP-1510 FPGA
  * ---------------------------------------------------------------------------
  */
-#define OMAP1510P1_FPGA_BASE                   0xE8000000      /* Virtual */
-#define OMAP1510P1_FPGA_SIZE                   SZ_4K
-#define OMAP1510P1_FPGA_START                  0x08000000      /* Physical */
+#define OMAP1510_FPGA_BASE                     0xE8000000      /* Virtual */
+#define OMAP1510_FPGA_SIZE                     SZ_4K
+#define OMAP1510_FPGA_START                    0x08000000      /* Physical */
 
 /* Revision */
-#define OMAP1510P1_FPGA_REV_LOW                        (OMAP1510P1_FPGA_BASE + 0x0)
-#define OMAP1510P1_FPGA_REV_HIGH               (OMAP1510P1_FPGA_BASE + 0x1)
+#define OMAP1510_FPGA_REV_LOW                  (OMAP1510_FPGA_BASE + 0x0)
+#define OMAP1510_FPGA_REV_HIGH                 (OMAP1510_FPGA_BASE + 0x1)
 
-#define OMAP1510P1_FPGA_LCD_PANEL_CONTROL      (OMAP1510P1_FPGA_BASE + 0x2)
-#define OMAP1510P1_FPGA_LED_DIGIT              (OMAP1510P1_FPGA_BASE + 0x3)
-#define INNOVATOR_FPGA_HID_SPI                 (OMAP1510P1_FPGA_BASE + 0x4)
-#define OMAP1510P1_FPGA_POWER                  (OMAP1510P1_FPGA_BASE + 0x5)
+#define OMAP1510_FPGA_LCD_PANEL_CONTROL                (OMAP1510_FPGA_BASE + 0x2)
+#define OMAP1510_FPGA_LED_DIGIT                        (OMAP1510_FPGA_BASE + 0x3)
+#define INNOVATOR_FPGA_HID_SPI                 (OMAP1510_FPGA_BASE + 0x4)
+#define OMAP1510_FPGA_POWER                    (OMAP1510_FPGA_BASE + 0x5)
 
 /* Interrupt status */
-#define OMAP1510P1_FPGA_ISR_LO                 (OMAP1510P1_FPGA_BASE + 0x6)
-#define OMAP1510P1_FPGA_ISR_HI                 (OMAP1510P1_FPGA_BASE + 0x7)
+#define OMAP1510_FPGA_ISR_LO                   (OMAP1510_FPGA_BASE + 0x6)
+#define OMAP1510_FPGA_ISR_HI                   (OMAP1510_FPGA_BASE + 0x7)
 
 /* Interrupt mask */
-#define OMAP1510P1_FPGA_IMR_LO                 (OMAP1510P1_FPGA_BASE + 0x8)
-#define OMAP1510P1_FPGA_IMR_HI                 (OMAP1510P1_FPGA_BASE + 0x9)
+#define OMAP1510_FPGA_IMR_LO                   (OMAP1510_FPGA_BASE + 0x8)
+#define OMAP1510_FPGA_IMR_HI                   (OMAP1510_FPGA_BASE + 0x9)
 
 /* Reset registers */
-#define OMAP1510P1_FPGA_HOST_RESET             (OMAP1510P1_FPGA_BASE + 0xa)
-#define OMAP1510P1_FPGA_RST                    (OMAP1510P1_FPGA_BASE + 0xb)
-
-#define OMAP1510P1_FPGA_AUDIO                  (OMAP1510P1_FPGA_BASE + 0xc)
-#define OMAP1510P1_FPGA_DIP                    (OMAP1510P1_FPGA_BASE + 0xe)
-#define OMAP1510P1_FPGA_FPGA_IO                        (OMAP1510P1_FPGA_BASE + 0xf)
-#define OMAP1510P1_FPGA_UART1                  (OMAP1510P1_FPGA_BASE + 0x14)
-#define OMAP1510P1_FPGA_UART2                  (OMAP1510P1_FPGA_BASE + 0x15)
-#define OMAP1510P1_FPGA_OMAP1510_STATUS                (OMAP1510P1_FPGA_BASE + 0x16)
-#define OMAP1510P1_FPGA_BOARD_REV              (OMAP1510P1_FPGA_BASE + 0x18)
-#define OMAP1510P1_PPT_DATA                    (OMAP1510P1_FPGA_BASE + 0x100)
-#define OMAP1510P1_PPT_STATUS                  (OMAP1510P1_FPGA_BASE + 0x101)
-#define OMAP1510P1_PPT_CONTROL                 (OMAP1510P1_FPGA_BASE + 0x102)
-
-#define OMAP1510P1_FPGA_TOUCHSCREEN            (OMAP1510P1_FPGA_BASE + 0x204)
-
-#define INNOVATOR_FPGA_INFO                    (OMAP1510P1_FPGA_BASE + 0x205)
-#define INNOVATOR_FPGA_LCD_BRIGHT_LO           (OMAP1510P1_FPGA_BASE + 0x206)
-#define INNOVATOR_FPGA_LCD_BRIGHT_HI           (OMAP1510P1_FPGA_BASE + 0x207)
-#define INNOVATOR_FPGA_LED_GRN_LO              (OMAP1510P1_FPGA_BASE + 0x208)
-#define INNOVATOR_FPGA_LED_GRN_HI              (OMAP1510P1_FPGA_BASE + 0x209)
-#define INNOVATOR_FPGA_LED_RED_LO              (OMAP1510P1_FPGA_BASE + 0x20a)
-#define INNOVATOR_FPGA_LED_RED_HI              (OMAP1510P1_FPGA_BASE + 0x20b)
-#define INNOVATOR_FPGA_CAM_USB_CONTROL         (OMAP1510P1_FPGA_BASE + 0x20c)
-#define INNOVATOR_FPGA_EXP_CONTROL             (OMAP1510P1_FPGA_BASE + 0x20d)
-#define INNOVATOR_FPGA_ISR2                    (OMAP1510P1_FPGA_BASE + 0x20e)
-#define INNOVATOR_FPGA_IMR2                    (OMAP1510P1_FPGA_BASE + 0x210)
-
-#define OMAP1510P1_FPGA_ETHR_START             (OMAP1510P1_FPGA_START + 0x300)
-#define OMAP1510P1_FPGA_ETHR_BASE              (OMAP1510P1_FPGA_BASE + 0x300)
+#define OMAP1510_FPGA_HOST_RESET               (OMAP1510_FPGA_BASE + 0xa)
+#define OMAP1510_FPGA_RST                      (OMAP1510_FPGA_BASE + 0xb)
+
+#define OMAP1510_FPGA_AUDIO                    (OMAP1510_FPGA_BASE + 0xc)
+#define OMAP1510_FPGA_DIP                      (OMAP1510_FPGA_BASE + 0xe)
+#define OMAP1510_FPGA_FPGA_IO                  (OMAP1510_FPGA_BASE + 0xf)
+#define OMAP1510_FPGA_UART1                    (OMAP1510_FPGA_BASE + 0x14)
+#define OMAP1510_FPGA_UART2                    (OMAP1510_FPGA_BASE + 0x15)
+#define OMAP1510_FPGA_OMAP1510_STATUS          (OMAP1510_FPGA_BASE + 0x16)
+#define OMAP1510_FPGA_BOARD_REV                        (OMAP1510_FPGA_BASE + 0x18)
+#define OMAP1510P1_PPT_DATA                    (OMAP1510_FPGA_BASE + 0x100)
+#define OMAP1510P1_PPT_STATUS                  (OMAP1510_FPGA_BASE + 0x101)
+#define OMAP1510P1_PPT_CONTROL                 (OMAP1510_FPGA_BASE + 0x102)
+
+#define OMAP1510_FPGA_TOUCHSCREEN              (OMAP1510_FPGA_BASE + 0x204)
+
+#define INNOVATOR_FPGA_INFO                    (OMAP1510_FPGA_BASE + 0x205)
+#define INNOVATOR_FPGA_LCD_BRIGHT_LO           (OMAP1510_FPGA_BASE + 0x206)
+#define INNOVATOR_FPGA_LCD_BRIGHT_HI           (OMAP1510_FPGA_BASE + 0x207)
+#define INNOVATOR_FPGA_LED_GRN_LO              (OMAP1510_FPGA_BASE + 0x208)
+#define INNOVATOR_FPGA_LED_GRN_HI              (OMAP1510_FPGA_BASE + 0x209)
+#define INNOVATOR_FPGA_LED_RED_LO              (OMAP1510_FPGA_BASE + 0x20a)
+#define INNOVATOR_FPGA_LED_RED_HI              (OMAP1510_FPGA_BASE + 0x20b)
+#define INNOVATOR_FPGA_CAM_USB_CONTROL         (OMAP1510_FPGA_BASE + 0x20c)
+#define INNOVATOR_FPGA_EXP_CONTROL             (OMAP1510_FPGA_BASE + 0x20d)
+#define INNOVATOR_FPGA_ISR2                    (OMAP1510_FPGA_BASE + 0x20e)
+#define INNOVATOR_FPGA_IMR2                    (OMAP1510_FPGA_BASE + 0x210)
+
+#define OMAP1510_FPGA_ETHR_START               (OMAP1510_FPGA_START + 0x300)
+#define OMAP1510_FPGA_ETHR_BASE                        (OMAP1510_FPGA_BASE + 0x300)
 
 /*
  * Power up Giga UART driver, turn on HID clock.
  * Turn off BT power, since we're not using it and it
  * draws power.
  */
-#define OMAP1510P1_FPGA_RESET_VALUE            0x42
-
-#define OMAP1510P1_FPGA_PCR_IF_PD0             (1 << 7)
-#define OMAP1510P1_FPGA_PCR_COM2_EN            (1 << 6)
-#define OMAP1510P1_FPGA_PCR_COM1_EN            (1 << 5)
-#define OMAP1510P1_FPGA_PCR_EXP_PD0            (1 << 4)
-#define OMAP1510P1_FPGA_PCR_EXP_PD1            (1 << 3)
-#define OMAP1510P1_FPGA_PCR_48MHZ_CLK          (1 << 2)
-#define OMAP1510P1_FPGA_PCR_4MHZ_CLK           (1 << 1)
-#define OMAP1510P1_FPGA_PCR_RSRVD_BIT0         (1 << 0)
+#define OMAP1510_FPGA_RESET_VALUE              0x42
+
+#define OMAP1510_FPGA_PCR_IF_PD0               (1 << 7)
+#define OMAP1510_FPGA_PCR_COM2_EN              (1 << 6)
+#define OMAP1510_FPGA_PCR_COM1_EN              (1 << 5)
+#define OMAP1510_FPGA_PCR_EXP_PD0              (1 << 4)
+#define OMAP1510_FPGA_PCR_EXP_PD1              (1 << 3)
+#define OMAP1510_FPGA_PCR_48MHZ_CLK            (1 << 2)
+#define OMAP1510_FPGA_PCR_4MHZ_CLK             (1 << 1)
+#define OMAP1510_FPGA_PCR_RSRVD_BIT0           (1 << 0)
 
 /*
  * Innovator/OMAP1510 FPGA HID register bit definitions
index ff35947..afb61f8 100644 (file)
@@ -72,8 +72,12 @@ struct omap_driver {
  * Device ID numbers for bus types
  */
 #define OMAP_OCP_DEVID_USB     0
+
+#define OMAP_TIPB_DEVID_OHCI   0
 #define OMAP_TIPB_DEVID_LCD    1
 #define OMAP_TIPB_DEVID_MMC    2
+#define OMAP_TIPB_DEVID_OTG    3
+#define OMAP_TIPB_DEVID_UDC    4
 
 /*
  * Virtual bus definitions for OMAP
index a7d7a36..bf87b3a 100644 (file)
 #define OMAP_DMA_EXT_NDMA_REQ          5
 #define OMAP_DMA_EXT_NDMA_REQ2         6
 #define OMAP_DMA_UWIRE_TX              7
-#define OMAP_DMA_MCBSP1_DMA_TX         8
-#define OMAP_DMA_MCBSP1_DMA_RX         9
-#define OMAP_DMA_MCBSP3_DMA_TX         10
-#define OMAP_DMA_MCBSP3_DMA_RX         11
+#define OMAP_DMA_MCBSP1_TX             8
+#define OMAP_DMA_MCBSP1_RX             9
+#define OMAP_DMA_MCBSP3_TX             10
+#define OMAP_DMA_MCBSP3_RX             11
 #define OMAP_DMA_UART1_TX              12
 #define OMAP_DMA_UART1_RX              13
 #define OMAP_DMA_UART2_TX              14
 #define OMAP_DMA_CRYPTO_DES_OUT                56
 
 
-#define OMAP_DMA_BASE                  0xfffed800
-#define OMAP_DMA_GCR_REG               (OMAP_DMA_BASE + 0x400)
-#define OMAP_DMA_GSCR_REG              (OMAP_DMA_BASE + 0x404)
-#define OMAP_DMA_GRST_REG              (OMAP_DMA_BASE + 0x408)
-#define OMAP_DMA_HW_ID_REG             (OMAP_DMA_BASE + 0x442)
-#define OMAP_DMA_PCH2_ID_REG           (OMAP_DMA_BASE + 0x444)
+#define OMAP_DMA_BASE                  (0xfffed800)
+#define OMAP_DMA_GCR                   (OMAP_DMA_BASE + 0x400)
+#define OMAP_DMA_GSCR                  (OMAP_DMA_BASE + 0x404)
+#define OMAP_DMA_GRST                  (OMAP_DMA_BASE + 0x408)
+#define OMAP_DMA_HW_ID                 (OMAP_DMA_BASE + 0x442)
+#define OMAP_DMA_PCH2_ID               (OMAP_DMA_BASE + 0x444)
 #define OMAP_DMA_PCH0_ID               (OMAP_DMA_BASE + 0x446)
 #define OMAP_DMA_PCH1_ID               (OMAP_DMA_BASE + 0x448)
 #define OMAP_DMA_PCHG_ID               (OMAP_DMA_BASE + 0x44a)
 #define OMAP_DMA_PCHD_ID               (OMAP_DMA_BASE + 0x44c)
-#define OMAP_DMA_CAPS_0_U_REG          (OMAP_DMA_BASE + 0x44e)
-#define OMAP_DMA_CAPS_0_L_REG          (OMAP_DMA_BASE + 0x450)
-#define OMAP_DMA_CAPS_1_U_REG          (OMAP_DMA_BASE + 0x452)
-#define OMAP_DMA_CAPS_1_L_REG          (OMAP_DMA_BASE + 0x454)
-#define OMAP_DMA_CAPS_2_REG            (OMAP_DMA_BASE + 0x456)
-#define OMAP_DMA_CAPS_3_REG            (OMAP_DMA_BASE + 0x458)
-#define OMAP_DMA_CAPS_4_REG            (OMAP_DMA_BASE + 0x45a)
-#define OMAP_DMA_PCH2_SR_REG           (OMAP_DMA_BASE + 0x460)
-#define OMAP_DMA_PCH0_SR_REG           (OMAP_DMA_BASE + 0x480)
-#define OMAP_DMA_PCH1_SR_REG           (OMAP_DMA_BASE + 0x482)
-#define OMAP_DMA_PCHD_SR_REG           (OMAP_DMA_BASE + 0x4c0)
-
-#define OMAP1510_DMA_LCD_CTRL          0xfffedb00
-#define OMAP1510_DMA_LCD_TOP_F1_L      0xfffedb02
-#define OMAP1510_DMA_LCD_TOP_F1_U      0xfffedb04
-#define OMAP1510_DMA_LCD_BOT_F1_L      0xfffedb06
-#define OMAP1510_DMA_LCD_BOT_F1_U      0xfffedb08
-
-#define OMAP1610_DMA_LCD_CSDP          0xfffee3c0
-#define OMAP1610_DMA_LCD_CCR           0xfffee3c2
-#define OMAP1610_DMA_LCD_CTRL          0xfffee3c4
-#define OMAP1610_DMA_LCD_TOP_B1_L      0xfffee3c8
-#define OMAP1610_DMA_LCD_TOP_B1_U      0xfffee3ca
-#define OMAP1610_DMA_LCD_BOT_B1_L      0xfffee3cc
-#define OMAP1610_DMA_LCD_BOT_B1_U      0xfffee3ce
-#define OMAP1610_DMA_LCD_TOP_B2_L      0xfffee3d0
-#define OMAP1610_DMA_LCD_TOP_B2_U      0xfffee3d2
-#define OMAP1610_DMA_LCD_BOT_B2_L      0xfffee3d4
-#define OMAP1610_DMA_LCD_BOT_B2_U      0xfffee3d6
-#define OMAP1610_DMA_LCD_SRC_EI_B1     0xfffee3d8
-#define OMAP1610_DMA_LCD_SRC_FI_B1_L   0xfffee3da
-#define OMAP1610_DMA_LCD_SRC_EN_B1     0xfffee3e0
-#define OMAP1610_DMA_LCD_SRC_FN_B1     0xfffee3e4
-#define OMAP1610_DMA_LCD_LCH_CTRL      0xfffee3ea
-#define OMAP1610_DMA_LCD_SRC_FI_B1_U   0xfffee3f4
+#define OMAP_DMA_CAPS_0_U              (OMAP_DMA_BASE + 0x44e)
+#define OMAP_DMA_CAPS_0_L              (OMAP_DMA_BASE + 0x450)
+#define OMAP_DMA_CAPS_1_U              (OMAP_DMA_BASE + 0x452)
+#define OMAP_DMA_CAPS_1_L              (OMAP_DMA_BASE + 0x454)
+#define OMAP_DMA_CAPS_2                        (OMAP_DMA_BASE + 0x456)
+#define OMAP_DMA_CAPS_3                        (OMAP_DMA_BASE + 0x458)
+#define OMAP_DMA_CAPS_4                        (OMAP_DMA_BASE + 0x45a)
+#define OMAP_DMA_PCH2_SR               (OMAP_DMA_BASE + 0x460)
+#define OMAP_DMA_PCH0_SR               (OMAP_DMA_BASE + 0x480)
+#define OMAP_DMA_PCH1_SR               (OMAP_DMA_BASE + 0x482)
+#define OMAP_DMA_PCHD_SR               (OMAP_DMA_BASE + 0x4c0)
+
+#define OMAP1510_DMA_LCD_BASE          (0xfffedb00)
+#define OMAP1510_DMA_LCD_CTRL          (OMAP1510_DMA_LCD_BASE + 0x00)
+#define OMAP1510_DMA_LCD_TOP_F1_L      (OMAP1510_DMA_LCD_BASE + 0x02)
+#define OMAP1510_DMA_LCD_TOP_F1_U      (OMAP1510_DMA_LCD_BASE + 0x04)
+#define OMAP1510_DMA_LCD_BOT_F1_L      (OMAP1510_DMA_LCD_BASE + 0x06)
+#define OMAP1510_DMA_LCD_BOT_F1_U      (OMAP1510_DMA_LCD_BASE + 0x08)
+
+#define OMAP1610_DMA_LCD_BASE          (0xfffee300)
+#define OMAP1610_DMA_LCD_CSDP          (OMAP1610_DMA_LCD_BASE + 0xc0)
+#define OMAP1610_DMA_LCD_CCR           (OMAP1610_DMA_LCD_BASE + 0xc2)
+#define OMAP1610_DMA_LCD_CTRL          (OMAP1610_DMA_LCD_BASE + 0xc4)
+#define OMAP1610_DMA_LCD_TOP_B1_L      (OMAP1610_DMA_LCD_BASE + 0xc8)
+#define OMAP1610_DMA_LCD_TOP_B1_U      (OMAP1610_DMA_LCD_BASE + 0xca)
+#define OMAP1610_DMA_LCD_BOT_B1_L      (OMAP1610_DMA_LCD_BASE + 0xcc)
+#define OMAP1610_DMA_LCD_BOT_B1_U      (OMAP1610_DMA_LCD_BASE + 0xce)
+#define OMAP1610_DMA_LCD_TOP_B2_L      (OMAP1610_DMA_LCD_BASE + 0xd0)
+#define OMAP1610_DMA_LCD_TOP_B2_U      (OMAP1610_DMA_LCD_BASE + 0xd2)
+#define OMAP1610_DMA_LCD_BOT_B2_L      (OMAP1610_DMA_LCD_BASE + 0xd4)
+#define OMAP1610_DMA_LCD_BOT_B2_U      (OMAP1610_DMA_LCD_BASE + 0xd6)
+#define OMAP1610_DMA_LCD_SRC_EI_B1     (OMAP1610_DMA_LCD_BASE + 0xd8)
+#define OMAP1610_DMA_LCD_SRC_FI_B1_L   (OMAP1610_DMA_LCD_BASE + 0xda)
+#define OMAP1610_DMA_LCD_SRC_EN_B1     (OMAP1610_DMA_LCD_BASE + 0xe0)
+#define OMAP1610_DMA_LCD_SRC_FN_B1     (OMAP1610_DMA_LCD_BASE + 0xe4)
+#define OMAP1610_DMA_LCD_LCH_CTRL      (OMAP1610_DMA_LCD_BASE + 0xea)
+#define OMAP1610_DMA_LCD_SRC_FI_B1_U   (OMAP1610_DMA_LCD_BASE + 0xf4)
 
 
 /* Every LCh has its own set of the registers below */
-#define OMAP_DMA_CSDP_REG(n)           (OMAP_DMA_BASE + 0x40 * (n) + 0x00)
-#define OMAP_DMA_CCR_REG(n)            (OMAP_DMA_BASE + 0x40 * (n) + 0x02)
-#define OMAP_DMA_CICR_REG(n)           (OMAP_DMA_BASE + 0x40 * (n) + 0x04)
-#define OMAP_DMA_CSR_REG(n)            (OMAP_DMA_BASE + 0x40 * (n) + 0x06)
-#define OMAP_DMA_CSSA_L_REG(n)         (OMAP_DMA_BASE + 0x40 * (n) + 0x08)
-#define OMAP_DMA_CSSA_U_REG(n)         (OMAP_DMA_BASE + 0x40 * (n) + 0x0a)
-#define OMAP_DMA_CDSA_L_REG(n)         (OMAP_DMA_BASE + 0x40 * (n) + 0x0c)
-#define OMAP_DMA_CDSA_U_REG(n)         (OMAP_DMA_BASE + 0x40 * (n) + 0x0e)
-#define OMAP_DMA_CEN_REG(n)            (OMAP_DMA_BASE + 0x40 * (n) + 0x10)
-#define OMAP_DMA_CFN_REG(n)            (OMAP_DMA_BASE + 0x40 * (n) + 0x12)
-#define OMAP_DMA_CSFI_REG(n)           (OMAP_DMA_BASE + 0x40 * (n) + 0x14)
-#define OMAP_DMA_CSEI_REG(n)           (OMAP_DMA_BASE + 0x40 * (n) + 0x16)
-#define OMAP_DMA_CSAC_REG(n)           (OMAP_DMA_BASE + 0x40 * (n) + 0x18)
-#define OMAP_DMA_CDAC_REG(n)           (OMAP_DMA_BASE + 0x40 * (n) + 0x1a)
-#define OMAP_DMA_CDEI_REG(n)           (OMAP_DMA_BASE + 0x40 * (n) + 0x1c)
-#define OMAP_DMA_CDFI_REG(n)           (OMAP_DMA_BASE + 0x40 * (n) + 0x1e)
-#define OMAP_DMA_COLOR_L_REG(n)                (OMAP_DMA_BASE + 0x40 * (n) + 0x20)
-#define OMAP_DMA_COLOR_U_REG(n)                (OMAP_DMA_BASE + 0x40 * (n) + 0x22)
-#define OMAP_DMA_CCR2_REG(n)           (OMAP_DMA_BASE + 0x40 * (n) + 0x24)
-#define OMAP_DMA_CLNK_CTRL_REG(n)      (OMAP_DMA_BASE + 0x40 * (n) + 0x28)
-#define OMAP_DMA_LCH_CTRL_REG(n)       (OMAP_DMA_BASE + 0x40 * (n) + 0x2a)
+#define OMAP_DMA_CSDP(n)               (OMAP_DMA_BASE + 0x40 * (n) + 0x00)
+#define OMAP_DMA_CCR(n)                        (OMAP_DMA_BASE + 0x40 * (n) + 0x02)
+#define OMAP_DMA_CICR(n)               (OMAP_DMA_BASE + 0x40 * (n) + 0x04)
+#define OMAP_DMA_CSR(n)                        (OMAP_DMA_BASE + 0x40 * (n) + 0x06)
+#define OMAP_DMA_CSSA_L(n)             (OMAP_DMA_BASE + 0x40 * (n) + 0x08)
+#define OMAP_DMA_CSSA_U(n)             (OMAP_DMA_BASE + 0x40 * (n) + 0x0a)
+#define OMAP_DMA_CDSA_L(n)             (OMAP_DMA_BASE + 0x40 * (n) + 0x0c)
+#define OMAP_DMA_CDSA_U(n)             (OMAP_DMA_BASE + 0x40 * (n) + 0x0e)
+#define OMAP_DMA_CEN(n)                        (OMAP_DMA_BASE + 0x40 * (n) + 0x10)
+#define OMAP_DMA_CFN(n)                        (OMAP_DMA_BASE + 0x40 * (n) + 0x12)
+#define OMAP_DMA_CSFI(n)               (OMAP_DMA_BASE + 0x40 * (n) + 0x14)
+#define OMAP_DMA_CSEI(n)               (OMAP_DMA_BASE + 0x40 * (n) + 0x16)
+#define OMAP_DMA_CSAC(n)               (OMAP_DMA_BASE + 0x40 * (n) + 0x18)
+#define OMAP_DMA_CDAC(n)               (OMAP_DMA_BASE + 0x40 * (n) + 0x1a)
+#define OMAP_DMA_CDEI(n)               (OMAP_DMA_BASE + 0x40 * (n) + 0x1c)
+#define OMAP_DMA_CDFI(n)               (OMAP_DMA_BASE + 0x40 * (n) + 0x1e)
+#define OMAP_DMA_COLOR_L(n)            (OMAP_DMA_BASE + 0x40 * (n) + 0x20)
+#define OMAP_DMA_COLOR_U(n)            (OMAP_DMA_BASE + 0x40 * (n) + 0x22)
+#define OMAP_DMA_CCR2(n)               (OMAP_DMA_BASE + 0x40 * (n) + 0x24)
+#define OMAP_DMA_CLNK_CTRL(n)          (OMAP_DMA_BASE + 0x40 * (n) + 0x28)
+#define OMAP_DMA_LCH_CTRL(n)           (OMAP_DMA_BASE + 0x40 * (n) + 0x2a)
 
 #define OMAP_DMA_TOUT_IRQ              (1 << 0)
 #define OMAP_DMA_DROP_IRQ              (1 << 1)
@@ -192,6 +194,11 @@ enum {
        OMAP_LCD_DMA_B2_BOTTOM
 };
 
+enum {
+       OMAP_DMA_DATA_BURST_4,
+       OMAP_DMA_DATA_BURST_8
+};
+
 extern int omap_request_dma(int dev_id, const char *dev_name,
                            void (* callback)(int lch, u16 ch_status, void *data),
                            void *data, int *dma_ch);
@@ -203,10 +210,20 @@ extern void omap_stop_dma(int lch);
 extern void omap_set_dma_transfer_params(int lch, int data_type,
                                         int elem_count, int frame_count,
                                         int sync_mode);
+extern void omap_set_dma_constant_fill(int lch, u32 color);
+extern void omap_set_dma_transparent_copy(int lch, u32 color);
+
 extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
                                    unsigned long src_start);
+extern void omap_set_dma_src_index(int lch, int eidx, int fidx);
+extern void omap_set_dma_src_data_pack(int lch, int enable);
+extern void omap_set_dma_src_burst_mode(int lch, int burst_mode);
+
 extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
                                     unsigned long dest_start);
+extern void omap_set_dma_dest_index(int lch, int eidx, int fidx);
+extern void omap_set_dma_dest_data_pack(int lch, int enable);
+extern void omap_set_dma_dest_burst_mode(int lch, int burst_mode);
 
 extern void omap_dma_link_lch (int lch_head, int lch_queue);
 extern void omap_dma_unlink_lch (int lch_head, int lch_queue);
index d54e36c..3b1680d 100644 (file)
 
 #define OMAP_MPUIO_BASE                        0xfffb5000
 #define OMAP_MPUIO_INPUT_LATCH         0x00
-#define OMAP_MPUIO_OUTPUT_REG          0x04
+#define OMAP_MPUIO_OUTPUT              0x04
 #define OMAP_MPUIO_IO_CNTL             0x08
 #define OMAP_MPUIO_KBR_LATCH           0x10
-#define OMAP_MPUIO_KBC_REG             0x14
-#define OMAP_MPUIO_GPIO_EVENT_MODE_REG 0x18
-#define OMAP_MPUIO_GPIO_INT_EDGE_REG   0x1c
+#define OMAP_MPUIO_KBC                 0x14
+#define OMAP_MPUIO_GPIO_EVENT_MODE     0x18
+#define OMAP_MPUIO_GPIO_INT_EDGE       0x1c
 #define OMAP_MPUIO_KBD_INT             0x20
 #define OMAP_MPUIO_GPIO_INT            0x24
 #define OMAP_MPUIO_KBD_MASKIT          0x28
 #define OMAP_MPUIO_GPIO_MASKIT         0x2c
-#define OMAP_MPUIO_GPIO_DEBOUNCING_REG 0x30
-#define OMAP_MPUIO_LATCH_REG           0x34
+#define OMAP_MPUIO_GPIO_DEBOUNCING     0x30
+#define OMAP_MPUIO_LATCH               0x34
 
 #define OMAP_MPUIO(nr)         (OMAP_MAX_GPIO_LINES + (nr))
 #define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES)
index c388942..348072b 100644 (file)
@@ -10,6 +10,7 @@
  * Author: RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
  *
  * Reorganized for Linux-2.6 by Tony Lindgren <tony@atomide.com>
+ *                          and Dirk Behme <dirk.behme@de.bosch.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
 #ifndef __ASSEMBLER__
 #include <asm/types.h>
 #endif
-
-/*
- * ----------------------------------------------------------------------------
- * I/O mapping
- * ----------------------------------------------------------------------------
- */
-#define IO_PHYS                        0xFFFB0000
-#define IO_OFFSET              0x01000000      /* Virtual IO = 0xfefb0000 */
-#define IO_VIRT                        (IO_PHYS - IO_OFFSET)
-#define IO_SIZE                        0x40000
-#define IO_ADDRESS(x)          ((x) - IO_OFFSET)
-
-#define PCIO_BASE              0
-
-#define io_p2v(x)               ((x) - IO_OFFSET)
-#define io_v2p(x)               ((x) + IO_OFFSET)
-
-#ifndef __ASSEMBLER__
-
-/* 16 bit uses LDRH/STRH, base +/- offset_8 */
-typedef struct { volatile u16 offset[256]; } __regbase16;
-#define __REGV16(vaddr)                ((__regbase16 *)((vaddr)&~0xff)) \
-                                       ->offset[((vaddr)&0xff)>>1]
-#define __REG16(paddr)          __REGV16(io_p2v(paddr))
-
-/* 8/32 bit uses LDR/STR, base +/- offset_12 */
-typedef struct { volatile u8 offset[4096]; } __regbase8;
-#define __REGV8(vaddr)         ((__regbase8  *)((paddr)&~4095)) \
-                                       ->offset[((paddr)&4095)>>0]
-#define __REG8(paddr)          __REGV8(io_p2v(paddr))
-
-typedef struct { volatile u32 offset[4096]; } __regbase32;
-#define __REGV32(vaddr)                ((__regbase32 *)((vaddr)&~4095)) \
-                                       ->offset[((vaddr)&4095)>>2]
-#define __REG32(paddr)         __REGV32(io_p2v(paddr))
-
-#else
-
-#define __REG8(paddr)          io_p2v(paddr)
-#define __REG16(paddr)         io_p2v(paddr)
-#define __REG32(paddr)         io_p2v(paddr)
-
-#endif
+#include <asm/arch/io.h>
 
 /*
  * ---------------------------------------------------------------------------
@@ -97,14 +56,14 @@ typedef struct { volatile u32 offset[4096]; } __regbase32;
  * Clocks
  * ----------------------------------------------------------------------------
  */
-#define CLKGEN_RESET_BASE      (0xfffece00)
-#define ARM_CKCTL              (CLKGEN_RESET_BASE + 0x0)
-#define ARM_IDLECT1            (CLKGEN_RESET_BASE + 0x4)
-#define ARM_IDLECT2            (CLKGEN_RESET_BASE + 0x8)
-#define ARM_EWUPCT             (CLKGEN_RESET_BASE + 0xC)
-#define ARM_RSTCT1             (CLKGEN_RESET_BASE + 0x10)
-#define ARM_RSTCT2             (CLKGEN_RESET_BASE + 0x14)
-#define ARM_SYSST              (CLKGEN_RESET_BASE + 0x18)
+#define CLKGEN_REG_BASE                (0xfffece00)
+#define ARM_CKCTL              (CLKGEN_REG_BASE + 0x0)
+#define ARM_IDLECT1            (CLKGEN_REG_BASE + 0x4)
+#define ARM_IDLECT2            (CLKGEN_REG_BASE + 0x8)
+#define ARM_EWUPCT             (CLKGEN_REG_BASE + 0xC)
+#define ARM_RSTCT1             (CLKGEN_REG_BASE + 0x10)
+#define ARM_RSTCT2             (CLKGEN_REG_BASE + 0x14)
+#define ARM_SYSST              (CLKGEN_REG_BASE + 0x18)
 
 #define CK_RATEF               1
 #define CK_IDLEF               2
@@ -113,19 +72,27 @@ typedef struct { volatile u32 offset[4096]; } __regbase32;
 #define SETARM_IDLE_SHIFT
 
 /* DPLL control registers */
-#define DPLL_CTL_REG           (0xfffecf00)
-#define CK_DPLL1               (0xfffecf00)
+#define DPLL_CTL               (0xfffecf00)
 
-/* ULPD */
+/* DSP clock control */
+#define DSP_CONFIG_REG_BASE     (0xe1008000)
+#define DSP_IDLECT1            (DSP_CONFIG_REG_BASE + 0x4)
+#define DSP_IDLECT2            (DSP_CONFIG_REG_BASE + 0x8)
+
+/*
+ * ---------------------------------------------------------------------------
+ * UPLD
+ * ---------------------------------------------------------------------------
+ */
 #define ULPD_REG_BASE          (0xfffe0800)
-#define ULPD_IT_STATUS_REG     (ULPD_REG_BASE + 0x14)
-#define ULPD_CLOCK_CTRL_REG    (ULPD_REG_BASE + 0x30)
-#define ULPD_SOFT_REQ_REG      (ULPD_REG_BASE + 0x34)
-#define ULPD_DPLL_CTRL_REG     (ULPD_REG_BASE + 0x3c)
-#define ULPD_STATUS_REQ_REG    (ULPD_REG_BASE + 0x40)
-#define ULPD_APLL_CTRL_REG     (ULPD_REG_BASE + 0x4c)
-#define ULPD_POWER_CTRL_REG    (ULPD_REG_BASE + 0x50)
-#define ULPD_CAM_CLK_CTRL_REG  (ULPD_REG_BASE + 0x7c)
+#define ULPD_IT_STATUS         (ULPD_REG_BASE + 0x14)
+#define ULPD_CLOCK_CTRL                (ULPD_REG_BASE + 0x30)
+#define ULPD_SOFT_REQ          (ULPD_REG_BASE + 0x34)
+#define ULPD_DPLL_CTRL         (ULPD_REG_BASE + 0x3c)
+#define ULPD_STATUS_REQ                (ULPD_REG_BASE + 0x40)
+#define ULPD_APLL_CTRL         (ULPD_REG_BASE + 0x4c)
+#define ULPD_POWER_CTRL                (ULPD_REG_BASE + 0x50)
+#define ULPD_CAM_CLK_CTRL      (ULPD_REG_BASE + 0x7c)
 
 /*
  * ---------------------------------------------------------------------------
@@ -146,18 +113,24 @@ typedef struct { volatile u32 offset[4096]; } __regbase32;
 #define TIMER32k_ARL           (1<<3)
 
 /* MPU Timer base addresses */
-#define OMAP_MPUTIMER_BASE     0xfffec500
-#define OMAP_MPUTIMER_OFF      0x00000100
-
-#define OMAP_TIMER1_BASE       0xfffec500
-#define OMAP_TIMER2_BASE       0xfffec600
-#define OMAP_TIMER3_BASE       0xfffec700
-#define OMAP_WATCHDOG_BASE     0xfffec800
+#define OMAP_TIMER1_BASE       (0xfffec500)
+#define OMAP_TIMER2_BASE       (0xfffec600)
+#define OMAP_TIMER3_BASE       (0xfffec700)
+#define OMAP_MPUTIMER_BASE     OMAP_TIMER1_BASE
+#define OMAP_MPUTIMER_OFFSET   0x100
 
 /* MPU Timer Registers */
-#define CNTL_TIMER             0
-#define LOAD_TIM               4
-#define READ_TIM               8
+#define OMAP_TIMER1_CNTL       (OMAP_TIMER_BASE1 + 0x0)
+#define OMAP_TIMER1_LOAD_TIM   (OMAP_TIMER_BASE1 + 0x4)
+#define OMAP_TIMER1_READ_TIM   (OMAP_TIMER_BASE1 + 0x8)
+
+#define OMAP_TIMER2_CNTL       (OMAP_TIMER_BASE2 + 0x0)
+#define OMAP_TIMER2_LOAD_TIM   (OMAP_TIMER_BASE2 + 0x4)
+#define OMAP_TIMER2_READ_TIM   (OMAP_TIMER_BASE2 + 0x8)
+
+#define OMAP_TIMER3_CNTL       (OMAP_TIMER_BASE3 + 0x0)
+#define OMAP_TIMER3_LOAD_TIM   (OMAP_TIMER_BASE3 + 0x4)
+#define OMAP_TIMER3_READ_TIM   (OMAP_TIMER_BASE3 + 0x8)
 
 /* CNTL_TIMER register bits */
 #define MPUTIM_FREE            (1<<6)
@@ -167,6 +140,13 @@ typedef struct { volatile u32 offset[4096]; } __regbase32;
 #define MPUTIM_AR              (1<<1)
 #define MPUTIM_ST              (1<<0)
 
+/* Watchdog */
+#define OMAP_WATCHDOG_BASE     (0xfffec800)
+#define OMAP_WDT_TIMER         (OMAP_WATCHDOG_BASE + 0x0)
+#define OMAP_WDT_LOAD_TIM      (OMAP_WATCHDOG_BASE + 0x4)
+#define OMAP_WDT_READ_TIM      (OMAP_WATCHDOG_BASE + 0x4)
+#define OMAP_WDT_TIMER_MODE    (OMAP_WATCHDOG_BASE + 0x8)
+
 /*
  * ---------------------------------------------------------------------------
  * Interrupts
@@ -174,22 +154,30 @@ typedef struct { volatile u32 offset[4096]; } __regbase32;
  */
 #define OMAP_IH1_BASE          0xfffecb00
 #define OMAP_IH2_BASE          0xfffe0000
-#define OMAP_ITR               0x0
-#define OMAP_MASK              0x4
-
-#define IRQ_ITR                        0x00
-#define IRQ_MIR                        0x04
-#define IRQ_SIR_IRQ            0x10
-#define IRQ_SIR_FIQ            0x14
-#define IRQ_CONTROL_REG                0x18
-#define IRQ_ISR                        0x9c
-#define IRQ_ILR0               0x1c
-
-/* OMAP-1610 specific interrupt handler registers */
-#define OMAP_IH2_SECT1         (OMAP_IH2_BASE)
-#define OMAP_IH2_SECT2         (OMAP_IH2_BASE + 0x100)
-#define OMAP_IH2_SECT3         (OMAP_IH2_BASE + 0x200)
-#define OMAP_IH2_SECT4         (OMAP_IH2_BASE + 0x300)
+
+#define OMAP_IH1_ITR           (OMAP_IH1_BASE + 0x00)
+#define OMAP_IH1_MIR           (OMAP_IH1_BASE + 0x04)
+#define OMAP_IH1_SIR_IRQ       (OMAP_IH1_BASE + 0x10)
+#define OMAP_IH1_SIR_FIQ       (OMAP_IH1_BASE + 0x14)
+#define OMAP_IH1_CONTROL       (OMAP_IH1_BASE + 0x18)
+#define OMAP_IH1_ILR0          (OMAP_IH1_BASE + 0x1c)
+#define OMAP_IH1_ISR           (OMAP_IH1_BASE + 0x9c)
+
+#define OMAP_IH2_ITR           (OMAP_IH2_BASE + 0x00)
+#define OMAP_IH2_MIR           (OMAP_IH2_BASE + 0x04)
+#define OMAP_IH2_SIR_IRQ       (OMAP_IH2_BASE + 0x10)
+#define OMAP_IH2_SIR_FIQ       (OMAP_IH2_BASE + 0x14)
+#define OMAP_IH2_CONTROL       (OMAP_IH2_BASE + 0x18)
+#define OMAP_IH2_ILR0          (OMAP_IH2_BASE + 0x1c)
+#define OMAP_IH2_ISR           (OMAP_IH2_BASE + 0x9c)
+
+#define IRQ_ITR_REG_OFFSET     0x00
+#define IRQ_MIR_REG_OFFSET     0x04
+#define IRQ_SIR_IRQ_REG_OFFSET 0x10
+#define IRQ_SIR_FIQ_REG_OFFSET 0x14
+#define IRQ_CONTROL_REG_OFFSET 0x18
+#define IRQ_ISR_REG_OFFSET     0x9c
+#define IRQ_ILR0_REG_OFFSET    0x1c
 
 /*
  * ---------------------------------------------------------------------------
@@ -198,9 +186,9 @@ typedef struct { volatile u32 offset[4096]; } __regbase32;
  */
 #define TCMIF_BASE             0xfffecc00
 #define IMIF_PRIO              (TCMIF_BASE + 0x00)
-#define EMIFS_PRIO_REG         (TCMIF_BASE + 0x04)
-#define EMIFF_PRIO_REG         (TCMIF_BASE + 0x08)
-#define EMIFS_CONFIG_REG       (TCMIF_BASE + 0x0c)
+#define EMIFS_PRIO             (TCMIF_BASE + 0x04)
+#define EMIFF_PRIO             (TCMIF_BASE + 0x08)
+#define EMIFS_CONFIG           (TCMIF_BASE + 0x0c)
 #define EMIFS_CS0_CONFIG       (TCMIF_BASE + 0x10)
 #define EMIFS_CS1_CONFIG       (TCMIF_BASE + 0x14)
 #define EMIFS_CS2_CONFIG       (TCMIF_BASE + 0x18)
@@ -213,7 +201,6 @@ typedef struct { volatile u32 offset[4096]; } __regbase32;
 #define TC_ENDIANISM           (TCMIF_BASE + 0x34)
 #define EMIFF_SDRAM_CONFIG_2   (TCMIF_BASE + 0x3c)
 #define EMIF_CFG_DYNAMIC_WS    (TCMIF_BASE + 0x40)
-
 /*
  * ----------------------------------------------------------------------------
  * System control registers
@@ -265,25 +252,24 @@ typedef struct { volatile u32 offset[4096]; } __regbase32;
  * ---------------------------------------------------------------------------
  */
 #define TIPB_PUBLIC_CNTL_BASE          0xfffed300
-#define MPU_PUBLIC_TIPB_CNTL_REG       (TIPB_PUBLIC_CNTL_BASE + 0x8)
+#define MPU_PUBLIC_TIPB_CNTL           (TIPB_PUBLIC_CNTL_BASE + 0x8)
 #define TIPB_PRIVATE_CNTL_BASE         0xfffeca00
-#define MPU_PRIVATE_TIPB_CNTL_REG      (TIPB_PRIVATE_CNTL_BASE + 0x8)
+#define MPU_PRIVATE_TIPB_CNTL          (TIPB_PRIVATE_CNTL_BASE + 0x8)
 
 /*
  * ----------------------------------------------------------------------------
- * DSP control registers
+ * MPUI interface
  * ----------------------------------------------------------------------------
  */
-/*  MPUI Interface Registers */
-#define MPUI_CTRL_REG          (0xfffec900)
-#define MPUI_DEBUG_ADDR                (0xfffec904)
-#define MPUI_DEBUG_DATA                (0xfffec908)
-#define MPUI_DEBUG_FLAG                (0xfffec90c)
-#define MPUI_STATUS_REG                (0xfffec910)
-#define MPUI_DSP_STATUS_REG    (0xfffec914)
-#define MPUI_DSP_BOOT_CONFIG   (0xfffec918)
-#define MPUI_DSP_API_CONFIG    (0xfffec91c)
-
+#define MPUI_BASE                      (0xfffec900)
+#define MPUI_CTRL                      (MPUI_BASE + 0x0)
+#define MPUI_DEBUG_ADDR                        (MPUI_BASE + 0x4)
+#define MPUI_DEBUG_DATA                        (MPUI_BASE + 0x8)
+#define MPUI_DEBUG_FLAG                        (MPUI_BASE + 0xc)
+#define MPUI_STATUS_REG                        (MPUI_BASE + 0x10)
+#define MPUI_DSP_STATUS                        (MPUI_BASE + 0x14)
+#define MPUI_DSP_BOOT_CONFIG           (MPUI_BASE + 0x18)
+#define MPUI_DSP_API_CONFIG            (MPUI_BASE + 0x1c)
 
 #ifndef __ASSEMBLER__
 
@@ -292,34 +278,38 @@ typedef struct { volatile u32 offset[4096]; } __regbase32;
  * Processor differentiation
  * ---------------------------------------------------------------------------
  */
-#define OMAP_ID_REG            __REG32(0xfffed404)
+#define OMAP_ID_BASE           (0xfffed400)
+#define OMAP_ID_REG            __REG32(OMAP_ID_BASE +  0x04)
+
+#define ID_SHIFT               12
+#define ID_MASK                        0x7fff
 
 /* See also uncompress.h */
-#define OMAP_ID_730            0xB55F
-#define OMAP_ID_1510           0xB470
-#define OMAP_ID_1610           0xB576
-#define OMAP_ID_1710           0xB5F7
-#define OMAP_ID_5912           0xB58C
+#define OMAP_ID_730            0x355F
+#define OMAP_ID_1510           0x3470
+#define OMAP_ID_1610           0x3576
+#define OMAP_ID_1710           0x35F7
+#define OMAP_ID_5912           0x358C
 
 #ifdef CONFIG_ARCH_OMAP730
 #include "omap730.h"
-#define cpu_is_omap730()       (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_730)
+#define cpu_is_omap730()       (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_730)
 #else
 #define cpu_is_omap730()       0
 #endif
 
 #ifdef CONFIG_ARCH_OMAP1510
 #include "omap1510.h"
-#define cpu_is_omap1510()      (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_1510)
+#define cpu_is_omap1510()      (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_1510)
 #else
 #define cpu_is_omap1510()      0
 #endif
 
 #ifdef CONFIG_ARCH_OMAP1610
 #include "omap1610.h"
-#define cpu_is_omap1710()       (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_1710)
+#define cpu_is_omap1710()       (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_1710)
 /* Detect 1710 as 1610 for now */
-#define cpu_is_omap1610()      (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_1610 \
+#define cpu_is_omap1610()      (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_1610 \
                                || cpu_is_omap1710())
 #else
 #define cpu_is_omap1610()      0
@@ -328,7 +318,7 @@ typedef struct { volatile u32 offset[4096]; } __regbase32;
 
 #ifdef CONFIG_ARCH_OMAP5912
 #include "omap5912.h"
-#define cpu_is_omap5912()      (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_5912)
+#define cpu_is_omap5912()      (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_5912)
 #else
 #define cpu_is_omap5912()      0
 #endif
index 86c1cb3..6622ba3 100644 (file)
@@ -1,13 +1,36 @@
 /*
  * linux/include/asm-arm/arch-omap/io.h
  *
+ * IO definitions for TI OMAP processors and boards
+ *
  * Copied from linux/include/asm-arm/arch-sa1100/io.h
  * Copyright (C) 1997-1999 Russell King
  *
+ * 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.
+ *
  * Modifications:
  *  06-12-1997 RMK     Created.
  *  07-04-1999 RMK     Major cleanup
  */
+
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H
 
 #define __mem_pci(a)           ((unsigned long)(a))
 #define __mem_isa(a)           ((unsigned long)(a))
 
+/*
+ * ----------------------------------------------------------------------------
+ * I/O mapping
+ * ----------------------------------------------------------------------------
+ */
+#define IO_PHYS                        0xFFFB0000
+#define IO_OFFSET              0x01000000      /* Virtual IO = 0xfefb0000 */
+#define IO_VIRT                        (IO_PHYS - IO_OFFSET)
+#define IO_SIZE                        0x40000
+#define IO_ADDRESS(x)          ((x) - IO_OFFSET)
+
+#define PCIO_BASE              0
+
+#define io_p2v(x)               ((x) - IO_OFFSET)
+#define io_v2p(x)               ((x) + IO_OFFSET)
+
+#ifndef __ASSEMBLER__
+
 /*
  * Functions to access the OMAP IO region
  *
 #define omap_writew(v,a)       (*(volatile unsigned short *)IO_ADDRESS(a) = (v))
 #define omap_writel(v,a)       (*(volatile unsigned int   *)IO_ADDRESS(a) = (v))
 
+/* 16 bit uses LDRH/STRH, base +/- offset_8 */
+typedef struct { volatile u16 offset[256]; } __regbase16;
+#define __REGV16(vaddr)                ((__regbase16 *)((vaddr)&~0xff)) \
+                                       ->offset[((vaddr)&0xff)>>1]
+#define __REG16(paddr)          __REGV16(io_p2v(paddr))
+
+/* 8/32 bit uses LDR/STR, base +/- offset_12 */
+typedef struct { volatile u8 offset[4096]; } __regbase8;
+#define __REGV8(vaddr)         ((__regbase8  *)((vaddr)&~4095)) \
+                                       ->offset[((vaddr)&4095)>>0]
+#define __REG8(paddr)          __REGV8(io_p2v(paddr))
+
+typedef struct { volatile u32 offset[4096]; } __regbase32;
+#define __REGV32(vaddr)                ((__regbase32 *)((vaddr)&~4095)) \
+                                       ->offset[((vaddr)&4095)>>2]
+#define __REG32(paddr)         __REGV32(io_p2v(paddr))
+
+#else
+
+#define __REG8(paddr)          io_p2v(paddr)
+#define __REG16(paddr)         io_p2v(paddr)
+#define __REG32(paddr)         io_p2v(paddr)
+
+#endif
+
 #endif
index a5ecbec..4053957 100644 (file)
@@ -140,16 +140,20 @@ typedef enum {
        R18_1510_USB_GPIO0,
        W4_USB_PUEN,
        W4_USB_CLKO,
+       W4_USB_HIGHZ,
+       W4_GPIO58,
 
        /* USB1 master */
        USB1_SUSP,
        USB1_SEO,
+       W13_1610_USB1_SE0,
        USB1_TXEN,
        USB1_TXD,
        USB1_VP,
        USB1_VM,
        USB1_RCV,
        USB1_SPEED,
+       R13_1610_USB1_SPEED,
 
        /* USB2 master */
        USB2_SUSP,
@@ -216,6 +220,7 @@ typedef enum {
        /* OMAP-1610 GPIO */
        P20_1610_GPIO4,
        V9_1610_GPIO7,
+       W8_1610_GPIO9,
        N19_1610_GPIO13,
        P10_1610_GPIO22,
        V5_1610_GPIO24,
@@ -317,16 +322,20 @@ MUX_CFG("R18_USB_VBUS",            7,    9,    2,   1,  11,   0,   NA,     0,  1)
 MUX_CFG("R18_1510_USB_GPIO0",   7,    9,    0,   1,  11,   1,   NA,     0,  1)
 MUX_CFG("W4_USB_PUEN",          D,    3,    0,   3,   5,   1,   NA,     0,  1)
 MUX_CFG("W4_USB_CLKO",          D,    3,    1,   3,   5,   0,   NA,     0,  1)
+MUX_CFG("W4_USB_HIGHZ",                 D,    3,    4,   3,   5,   0,    3,     0,  1)
+MUX_CFG("W4_GPIO58",            D,    3,    7,   3,   5,   0,    3,     0,  1)
 
 /* USB1 master */
 MUX_CFG("USB1_SUSP",            8,   27,    2,   1,  27,   0,   NA,     0,  1)
 MUX_CFG("USB1_SE0",             9,    0,    2,   1,  28,   0,   NA,     0,  1)
+MUX_CFG("W13_1610_USB1_SE0",    9,    0,    4,   1,  28,   0,   NA,     0,  1)
 MUX_CFG("USB1_TXEN",            9,    3,    2,   1,  29,   0,   NA,     0,  1)
 MUX_CFG("USB1_TXD",             9,   24,    1,   2,   4,   0,   NA,     0,  1)
 MUX_CFG("USB1_VP",              A,    3,    1,   2,   7,   0,   NA,     0,  1)
 MUX_CFG("USB1_VM",              A,    6,    1,   2,   8,   0,   NA,     0,  1)
 MUX_CFG("USB1_RCV",             A,    9,    1,   2,   9,   0,   NA,     0,  1)
 MUX_CFG("USB1_SPEED",           A,   12,    2,   2,  10,   0,   NA,     0,  1)
+MUX_CFG("R13_1610_USB1_SPEED",  A,   12,    5,   2,  10,   0,   NA,     0,  1)
 
 /* USB2 master */
 MUX_CFG("USB2_SUSP",            B,    3,    1,   2,  17,   0,   NA,     0,  1)
@@ -394,6 +403,7 @@ MUX_CFG("J18_1610_ETM_D7",   5,   27,    1,   0,  19,   0,    0,     0,  1)
 /* OMAP-1610 GPIO */
 MUX_CFG("P20_1610_GPIO4",       6,   27,    0,   1,   7,   0,    1,     1,  1)
 MUX_CFG("V9_1610_GPIO7",        B,   12,    1,   2,  20,   0,    2,     1,  1)
+MUX_CFG("W8_1610_GPIO9",        B,   21,    0,   2,  23,   0,    2,     1,  1)
 MUX_CFG("N19_1610_GPIO13",      6,   12,    0,   1,   2,   0,    1,     1,  1)
 MUX_CFG("P10_1610_GPIO22",      C,    0,    7,   2,  26,   0,    2,     1,  1)
 MUX_CFG("V5_1610_GPIO24",       B,   15,    7,   2,  21,   0,    2,     1,  1)
@@ -405,7 +415,7 @@ MUX_CFG("U18_1610_UWIRE_SDI",        8,    0,    0,   1,  18,   0,    1,     1,  1)
 MUX_CFG("W21_1610_UWIRE_SDO",   8,    3,    0,   1,  19,   0,    1,     1,  1)
 MUX_CFG("N14_1610_UWIRE_CS0",   8,    9,    1,   1,  21,   0,    1,     1,  1)
 MUX_CFG("P15_1610_UWIRE_CS3",   8,   12,    1,   1,  22,   0,    1,     1,  1)
-MUX_CFG("N15_1610_UWIRE_CS1",   7,   18,    2,  NA,   0,   0,   NA,     0,  0)
+MUX_CFG("N15_1610_UWIRE_CS1",   7,   18,    2,   1,  14,   0,   NA,     0,  1)
 
 /* First MMC interface, same on 1510 and 1610 */
 MUX_CFG("MMC_CMD",              A,   27,    0,   2,  15,   1,    2,     1,  1)
index c2ef7c3..667a6f6 100644 (file)
 #define OMAP1610_DSPREG_SIZE   SZ_128K
 #define OMAP1610_DSPREG_START  0xE1000000
 
-#define OMAP_IH2_0_BASE          0xfffe0000
-#define OMAP_IH2_1_BASE          0xfffe0100
-#define OMAP_IH2_2_BASE          0xfffe0200
-#define OMAP_IH2_3_BASE          0xfffe0300
+/*
+ * ---------------------------------------------------------------------------
+ * Interrupts
+ * ---------------------------------------------------------------------------
+ */
+#define OMAP_IH2_0_BASE                (0xfffe0000)
+#define OMAP_IH2_1_BASE                (0xfffe0100)
+#define OMAP_IH2_2_BASE                (0xfffe0200)
+#define OMAP_IH2_3_BASE                (0xfffe0300)
+
+#define OMAP_IH2_0_ITR         (OMAP_IH2_0_BASE + 0x00)
+#define OMAP_IH2_0_MIR         (OMAP_IH2_0_BASE + 0x04)
+#define OMAP_IH2_0_SIR_IRQ     (OMAP_IH2_0_BASE + 0x10)
+#define OMAP_IH2_0_SIR_FIQ     (OMAP_IH2_0_BASE + 0x14)
+#define OMAP_IH2_0_CONTROL     (OMAP_IH2_0_BASE + 0x18)
+#define OMAP_IH2_0_ILR0                (OMAP_IH2_0_BASE + 0x1c)
+#define OMAP_IH2_0_ISR         (OMAP_IH2_0_BASE + 0x9c)
+
+#define OMAP_IH2_1_ITR         (OMAP_IH2_1_BASE + 0x00)
+#define OMAP_IH2_1_MIR         (OMAP_IH2_1_BASE + 0x04)
+#define OMAP_IH2_1_SIR_IRQ     (OMAP_IH2_1_BASE + 0x10)
+#define OMAP_IH2_1_SIR_FIQ     (OMAP_IH2_1_BASE + 0x14)
+#define OMAP_IH2_1_CONTROL     (OMAP_IH2_1_BASE + 0x18)
+#define OMAP_IH2_1_ILR1                (OMAP_IH2_1_BASE + 0x1c)
+#define OMAP_IH2_1_ISR         (OMAP_IH2_1_BASE + 0x9c)
+
+#define OMAP_IH2_2_ITR         (OMAP_IH2_2_BASE + 0x00)
+#define OMAP_IH2_2_MIR         (OMAP_IH2_2_BASE + 0x04)
+#define OMAP_IH2_2_SIR_IRQ     (OMAP_IH2_2_BASE + 0x10)
+#define OMAP_IH2_2_SIR_FIQ     (OMAP_IH2_2_BASE + 0x14)
+#define OMAP_IH2_2_CONTROL     (OMAP_IH2_2_BASE + 0x18)
+#define OMAP_IH2_2_ILR2                (OMAP_IH2_2_BASE + 0x1c)
+#define OMAP_IH2_2_ISR         (OMAP_IH2_2_BASE + 0x9c)
+
+#define OMAP_IH2_3_ITR         (OMAP_IH2_3_BASE + 0x00)
+#define OMAP_IH2_3_MIR         (OMAP_IH2_3_BASE + 0x04)
+#define OMAP_IH2_3_SIR_IRQ     (OMAP_IH2_3_BASE + 0x10)
+#define OMAP_IH2_3_SIR_FIQ     (OMAP_IH2_3_BASE + 0x14)
+#define OMAP_IH2_3_CONTROL     (OMAP_IH2_3_BASE + 0x18)
+#define OMAP_IH2_3_ILR3                (OMAP_IH2_3_BASE + 0x1c)
+#define OMAP_IH2_3_ISR         (OMAP_IH2_3_BASE + 0x9c)
 
 /*
  * ----------------------------------------------------------------------------
- * System control registers
+ * Clocks
  * ----------------------------------------------------------------------------
  */
+#define OMAP1610_ARM_IDLECT3   (CLKGEN_REG_BASE + 0x24)
 
-#define OMAP1610_RESET_CONTROL         0xfffe1140
-#define OMAP1610_ARM_IDLECT3           (CLKGEN_RESET_BASE + 0x24)
-#define OMAP1610_CONF_VOLTAGE_CTRL_0   0xfffe1060
+/*
+ * ----------------------------------------------------------------------------
+ * Pin configuration registers
+ * ----------------------------------------------------------------------------
+ */
 #define OMAP1610_CONF_VOLTAGE_VDDSHV6  (1 << 8)
 #define OMAP1610_CONF_VOLTAGE_VDDSHV7  (1 << 9)
 #define OMAP1610_CONF_VOLTAGE_VDDSHV8  (1 << 10)
  * TIPB bus interface
  * ---------------------------------------------------------------------------
  */
-
-#define OMAP1610_TIPB_SWITCH           0xfffbc800
-#define OMAP1610_TIPB_BRIDGE_INT       0xfffeca00      /* Private TIPB_CNTL */
-#define OMAP1610_PRIVATE_MPU_TIPB_CNTL 0xfffeca08
-#define OMAP1610_TIPB_BRIDGE_EXT       0xfffed300      /* Public (Shared) TIPB_CNTL */
-#define OMAP1610_PUBLIC_MPU_TIPB_CNTL  0xfffed308
-#define OMAP1610_TIPB_SWITCH_CFG       OMAP_TIPB_SWITCH
-#define OMAP1610_MMCSD2_SSW_MPU_CONF   (TIPB_SWITCH_CFG + 0x160)
+#define TIPB_SWITCH_BASE                (0xfffbc800)
+#define OMAP1610_MMCSD2_SSW_MPU_CONF   (TIPB_SWITCH_BASE + 0x160)
 
 #endif /*  __ASM_ARCH_OMAP1610_H */
 
index aa72dd5..f996af7 100644 (file)
 #define OMAP5912_DSPREG_SIZE   SZ_128K
 #define OMAP5912_DSPREG_START  0xE1000000
 
+/*
+ * ---------------------------------------------------------------------------
+ * Interrupts
+ * ---------------------------------------------------------------------------
+ */
+#define OMAP_IH2_0_BASE                (0xfffe0000)
+#define OMAP_IH2_1_BASE                (0xfffe0100)
+#define OMAP_IH2_2_BASE                (0xfffe0200)
+#define OMAP_IH2_3_BASE                (0xfffe0300)
+
+#define OMAP_IH2_0_ITR         (OMAP_IH2_0_BASE + 0x00)
+#define OMAP_IH2_0_MIR         (OMAP_IH2_0_BASE + 0x04)
+#define OMAP_IH2_0_SIR_IRQ     (OMAP_IH2_0_BASE + 0x10)
+#define OMAP_IH2_0_SIR_FIQ     (OMAP_IH2_0_BASE + 0x14)
+#define OMAP_IH2_0_CONTROL     (OMAP_IH2_0_BASE + 0x18)
+#define OMAP_IH2_0_ILR0                (OMAP_IH2_0_BASE + 0x1c)
+#define OMAP_IH2_0_ISR         (OMAP_IH2_0_BASE + 0x9c)
+
+#define OMAP_IH2_1_ITR         (OMAP_IH2_1_BASE + 0x00)
+#define OMAP_IH2_1_MIR         (OMAP_IH2_1_BASE + 0x04)
+#define OMAP_IH2_1_SIR_IRQ     (OMAP_IH2_1_BASE + 0x10)
+#define OMAP_IH2_1_SIR_FIQ     (OMAP_IH2_1_BASE + 0x14)
+#define OMAP_IH2_1_CONTROL     (OMAP_IH2_1_BASE + 0x18)
+#define OMAP_IH2_1_ILR1                (OMAP_IH2_1_BASE + 0x1c)
+#define OMAP_IH2_1_ISR         (OMAP_IH2_1_BASE + 0x9c)
+
+#define OMAP_IH2_2_ITR         (OMAP_IH2_2_BASE + 0x00)
+#define OMAP_IH2_2_MIR         (OMAP_IH2_2_BASE + 0x04)
+#define OMAP_IH2_2_SIR_IRQ     (OMAP_IH2_2_BASE + 0x10)
+#define OMAP_IH2_2_SIR_FIQ     (OMAP_IH2_2_BASE + 0x14)
+#define OMAP_IH2_2_CONTROL     (OMAP_IH2_2_BASE + 0x18)
+#define OMAP_IH2_2_ILR2                (OMAP_IH2_2_BASE + 0x1c)
+#define OMAP_IH2_2_ISR         (OMAP_IH2_2_BASE + 0x9c)
+
+#define OMAP_IH2_3_ITR         (OMAP_IH2_3_BASE + 0x00)
+#define OMAP_IH2_3_MIR         (OMAP_IH2_3_BASE + 0x04)
+#define OMAP_IH2_3_SIR_IRQ     (OMAP_IH2_3_BASE + 0x10)
+#define OMAP_IH2_3_SIR_FIQ     (OMAP_IH2_3_BASE + 0x14)
+#define OMAP_IH2_3_CONTROL     (OMAP_IH2_3_BASE + 0x18)
+#define OMAP_IH2_3_ILR3                (OMAP_IH2_3_BASE + 0x1c)
+#define OMAP_IH2_3_ISR         (OMAP_IH2_3_BASE + 0x9c)
+
 /*
  * ----------------------------------------------------------------------------
  * System control registers
  * ----------------------------------------------------------------------------
  */
 
-#define OMAP5912_ARM_IDLECT3           (CLKGEN_RESET_BASE + 0x24)
+#define OMAP5912_ARM_IDLECT3   (CLKGEN_REG_BASE + 0x24)
 
 #endif /*  __ASM_ARCH_OMAP5912_H */
 
index 82aca67..8ca7636 100644 (file)
  * OMAP730 PCC_UPLD configuration registers
  * ----------------------------------------------------------------------------
  */
-#define OMAP730_PCC_UPLD_CTRL_REG_BASE (0xfffe0900)
-#define OMAP730_PCC_UPLD_CTRL_REG      (OMAP730_PCC_UPLD_CTRL_REG_BASE + 0x00)
+#define OMAP730_PCC_UPLD_CTRL_BASE     (0xfffe0900)
+#define OMAP730_PCC_UPLD_CTRL          (OMAP730_PCC_UPLD_CTRL_BASE + 0x00)
 
 #endif /*  __ASM_ARCH_OMAP730_H */
 
index 9e3cc95..85d4812 100644 (file)
@@ -52,7 +52,7 @@ typedef struct {
 
 #define mputimer_base(n) \
     ((volatile mputimer_regs_t*)IO_ADDRESS(OMAP_MPUTIMER_BASE + \
-                                (n)*OMAP_MPUTIMER_OFF))
+                                (n)*OMAP_MPUTIMER_OFFSET))
 
 static inline unsigned long timer32k_read(int reg) {
        unsigned long val;
index f0b82d3..9b28736 100644 (file)
@@ -25,7 +25,7 @@
 
 #define UART_OMAP_MDR1         0x08    /* mode definition register */
 #define check_port(base, shift) ((base[UART_OMAP_MDR1 << shift] & 7) == 0)
-#define omap_get_id() ((*(volatile unsigned int *)(0xfffed404)) >> 12) & 0xffff
+#define omap_get_id() ((*(volatile unsigned int *)(0xfffed404)) >> 12) & ID_MASK
 
 static void
 puts(const char *s)
index bd600bd..ffd2fa2 100644 (file)
@@ -90,13 +90,4 @@ extern unsigned int get_lcdclk_frequency_10khz(void);
 
 #endif
 
-
-/*
- * Implementation specifics
- */
-
-#include "lubbock.h"
-#include "mainstone.h"
-#include "idp.h"
-
 #endif  /* _ASM_ARCH_HARDWARE_H */
index 823ea8c..a8cc789 100644 (file)
 #define S3C2410_EINFLT2           S3C2410_GPIOREG(0x9C)
 #define S3C2410_EINFLT3           S3C2410_GPIOREG(0xA0)
 
-/* mask: 0=enable, 1=disable
- * 1 bit EINT, 4=EINT4, 23=EINT23
- * EINT0,1,2,3 are not handled here.
-*/
-#define S3C2410_EINTMASK   S3C2410_GPIOREG(0xA4)
-#define S3C2410_EINTPEND   S3C2410_GPIOREG(0xA8)
+/* removed EINTxxxx defs from here, not meant for this */
 
 /* GSTATUS have miscellaneous information in them
  *
index b6b0223..87edb61 100644 (file)
 #define S3C2410_SUBSRCPND      S3C2410_IRQREG(0x018)
 #define S3C2410_INTSUBMSK      S3C2410_IRQREG(0x01C)
 
+/* mask: 0=enable, 1=disable
+ * 1 bit EINT, 4=EINT4, 23=EINT23
+ * EINT0,1,2,3 are not handled here.
+*/
+
 #define S3C2410_EINTMASK       S3C2410_EINTREG(0x0A4)
 #define S3C2410_EINTPEND       S3C2410_EINTREG(0X0A8)
 
index 224c8d7..048ed44 100644 (file)
@@ -291,17 +291,7 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr)
  * about to change to user space.  This is the same method as used on SPARC64.
  * See update_mmu_cache for the user space part.
  */
-extern void __flush_dcache_page(struct page *);
-
-static inline void flush_dcache_page(struct page *page)
-{
-       struct address_space *mapping = page_mapping(page);
-
-       if (mapping && !mapping_mapped(mapping))
-               set_bit(PG_dcache_dirty, &page->flags);
-       else
-               __flush_dcache_page(page);
-}
+extern void flush_dcache_page(struct page *);
 
 #define flush_dcache_mmap_lock(mapping) \
        spin_lock_irq(&(mapping)->tree_lock)
index 785749b..7492cfa 100644 (file)
 
 #define FP_SIZE 35
 
+#ifndef __ASSEMBLY__
+
+/*
+ * VFP storage area has:
+ *  - FPEXC, FPSCR, FPINST and FPINST2.
+ *  - 16 double precision data registers
+ *  - an implementation-dependant word of state for FLDMX/FSTMX
+ * 
+ *  FPEXC will always be non-zero once the VFP has been used in this process.
+ */
+
+struct vfp_hard_struct {
+       __u64 fpregs[16];
+       __u32 fpmx_state;
+       __u32 fpexc;
+       __u32 fpscr;
+       /*
+        * VFP implementation specific state
+        */
+       __u32 fpinst;
+       __u32 fpinst2;
+};
+
+union vfp_state {
+       struct vfp_hard_struct  hard;
+};
+
+extern void vfp_flush_thread(union vfp_state *);
+extern void vfp_release_thread(union vfp_state *);
+
 struct fp_hard_struct {
        unsigned int save[FP_SIZE];             /* as yet undefined */
 };
@@ -27,3 +57,5 @@ union fp_state {
 };
 
 #endif
+
+#endif
index c561da3..14ac954 100644 (file)
@@ -312,6 +312,13 @@ PTE_BIT_FUNC(mkyoung,   |= L_PTE_YOUNG);
                flush_pmd_entry(pmdp);  \
        } while (0)
 
+#define copy_pmd(pmdpd,pmdps)          \
+       do {                            \
+               pmdpd[0] = pmdps[0];    \
+               pmdpd[1] = pmdps[1];    \
+               flush_pmd_entry(pmdpd); \
+       } while (0)
+
 #define pmd_clear(pmdp)                        \
        do {                            \
                pmdp[0] = __pmd(0);     \
index 0e42fa8..748c660 100644 (file)
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 #ifdef __KERNEL__
 
        { RLIM_INFINITY, RLIM_INFINITY },       \
        { 0,             0             },       \
        { INR_OPEN,      INR_OPEN      },       \
-       { PAGE_SIZE,      PAGE_SIZE    },       \
        { RLIM_INFINITY, RLIM_INFINITY },       \
        { RLIM_INFINITY, RLIM_INFINITY },       \
+       { RLIM_INFINITY, RLIM_INFINITY },       \
+       { MAX_SIGPENDING, MAX_SIGPENDING},      \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX},          \
 }
 
 #endif /* __KERNEL__ */
index f67431f..b3ef764 100644 (file)
 
 #ifdef __KERNEL__
 
+#include <asm/fpstate.h>
+
 #ifndef __ASSEMBLY__
 
 struct task_struct;
 struct exec_domain;
 
-#include <asm/fpstate.h>
 #include <asm/ptrace.h>
 #include <asm/types.h>
 #include <asm/domain.h>
@@ -53,7 +54,8 @@ struct thread_info {
        struct cpu_context_save cpu_context;    /* cpu context */
        __u8                    used_cp[16];    /* thread used copro */
        union fp_state          fpstate;
-       struct restart_block    restart_block;
+       union vfp_state         vfpstate;
+       struct restart_block    restart_block;
 };
 
 #define INIT_THREAD_INFO(tsk)                                          \
@@ -110,6 +112,7 @@ extern void free_thread_info(struct thread_info *);
 #define TI_CPU_SAVE    28
 #define TI_USED_CP     76
 #define TI_FPSTATE     (TI_USED_CP+16)
+#define TI_VFPSTATE    (TI_FPSTATE+FP_SIZE*4)
 
 #endif
 
index 119745a..d013105 100644 (file)
@@ -13,7 +13,7 @@
  */
 #include <linux/sched.h>
 #include <asm/errno.h>
-#include <asm/arch/memory.h>
+#include <asm/memory.h>
 #include <asm/domain.h>
 #include <asm/system.h>
 
index 5cd7165..1435eb3 100644 (file)
@@ -466,6 +466,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
index 1187008..748c660 100644 (file)
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 #ifdef __KERNEL__
 
        { RLIM_INFINITY, RLIM_INFINITY },       \
        { 0,             0             },       \
        { INR_OPEN,      INR_OPEN      },       \
-       { PAGE_SIZE,     PAGE_SIZE     },       \
        { RLIM_INFINITY, RLIM_INFINITY },       \
        { RLIM_INFINITY, RLIM_INFINITY },       \
+       { RLIM_INFINITY, RLIM_INFINITY },       \
+       { MAX_SIGPENDING, MAX_SIGPENDING},      \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX},          \
 }
 
 #endif /* __KERNEL__ */
index ee6d11d..b58e259 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __ASMARM_TLB_H
 #define __ASMARM_TLB_H
 
+#include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 
 /*
index 432eafc..e64b011 100644 (file)
@@ -397,6 +397,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) {                     \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
index 78848fb..e33ada0 100644 (file)
 #define RLIMIT_NOFILE  7               /* max number of open files */
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit */
-#define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 /*
  * SuS says limits have to be unsigned.
        { RLIM_INFINITY, RLIM_INFINITY },               \
        {             0,             0 },               \
        {      INR_OPEN,     INR_OPEN  },               \
-       { PAGE_SIZE,     PAGE_SIZE     },               \
-        { RLIM_INFINITY, RLIM_INFINITY },              \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { MAX_SIGPENDING, MAX_SIGPENDING },             \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX },                 \
 }
 
 #endif /* __KERNEL__ */
index 71b7f69..0b58c45 100644 (file)
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
index 1358c51..973808f 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/config.h>
 #include <linux/swap.h>
+#include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 
 /*
index ceef520..bd9f37c 100644 (file)
 
 static inline unsigned short _swapw(volatile unsigned short v)
 {
-       unsigned short r,t;
-       __asm__("mov.b %w2,%x1\n\t"
-               "mov.b %x2,%w1\n\t"
-               "mov.w %1,%0"
-               :"=r"(r),"=r"(t)
-               :"r"(v));
+#ifndef H8300_IO_NOSWAP
+       unsigned short r;
+       __asm__("xor.b %w0,%x0\n\t"
+               "xor.b %x0,%w0\n\t"
+               "xor.b %w0,%x0"
+               :"=r"(r)
+               :"0"(v));
        return r;
+#else
+       return v;
+#endif
 }
 
-static inline unsigned int _swapl(volatile unsigned long v)
+static inline unsigned long _swapl(volatile unsigned long v)
 {
-       unsigned int r,t;
-       __asm__("mov.b %w2,%x1\n\t"
-               "mov.b %x2,%w1\n\t"
-               "mov.w %f1,%e0\n\t"
-               "mov.w %e2,%f1\n\t"
-               "mov.b %w1,%x0\n\t"
-               "mov.b %x1,%w0"
-               :"=r"(r),"=r"(t)
-               :"r"(v));
+#ifndef H8300_IO_NOSWAP
+       unsigned long r;
+       __asm__("xor.b %w0,%x0\n\t"
+               "xor.b %x0,%w0\n\t"
+               "xor.b %w0,%x0\n\t"
+               "xor.w %e0,%f0\n\t"
+               "xor.w %f0,%e0\n\t"
+               "xor.w %e0,%f0\n\t"
+               "xor.b %w0,%x0\n\t"
+               "xor.b %x0,%w0\n\t"
+               "xor.b %w0,%x0"
+               :"=r"(r)
+               :"0"(v));
        return r;
+#else
+       return v;
+#endif
 }
 
 #define readb(addr) \
@@ -109,12 +120,28 @@ static inline void io_outsw(unsigned int addr, const void *buf, int len)
 
 static inline void io_outsl(unsigned int addr, const void *buf, int len)
 {
-       volatile unsigned int *ap = (volatile unsigned int *) addr;
+       volatile unsigned long *ap = (volatile unsigned long *) addr;
        unsigned long *bp = (unsigned long *) buf;
        while (len--)
                *ap = _swapl(*bp++);
 }
 
+static inline void io_outsw_noswap(unsigned int addr, const void *buf, int len)
+{
+       volatile unsigned short *ap = (volatile unsigned short *) addr;
+       unsigned short *bp = (unsigned short *) buf;
+       while (len--)
+               *ap = *bp++;
+}
+
+static inline void io_outsl_noswap(unsigned int addr, const void *buf, int len)
+{
+       volatile unsigned long *ap = (volatile unsigned long *) addr;
+       unsigned long *bp = (unsigned long *) buf;
+       while (len--)
+               *ap = *bp++;
+}
+
 static inline void io_insb(unsigned int addr, void *buf, int len)
 {
        volatile unsigned char  *ap_b;
@@ -142,12 +169,28 @@ static inline void io_insw(unsigned int addr, void *buf, int len)
 
 static inline void io_insl(unsigned int addr, void *buf, int len)
 {
-       volatile unsigned int *ap = (volatile unsigned int *) addr;
+       volatile unsigned long *ap = (volatile unsigned long *) addr;
        unsigned long *bp = (unsigned long *) buf;
        while (len--)
                *bp++ = _swapl(*ap);
 }
 
+static inline void io_insw_noswap(unsigned int addr, void *buf, int len)
+{
+       volatile unsigned short *ap = (volatile unsigned short *) addr;
+       unsigned short *bp = (unsigned short *) buf;
+       while (len--)
+               *bp++ = *ap;
+}
+
+static inline void io_insl_noswap(unsigned int addr, void *buf, int len)
+{
+       volatile unsigned long *ap = (volatile unsigned long *) addr;
+       unsigned long *bp = (unsigned long *) buf;
+       while (len--)
+               *bp++ = *ap;
+}
+
 /*
  *     make the short names macros so specific devices
  *     can override them as required
@@ -160,7 +203,8 @@ static inline void io_insl(unsigned int addr, void *buf, int len)
 #define inb(addr)    ((h8300_buswidth(addr))?readw((addr) & ~1) & 0xff:readb(addr))
 #define inw(addr)    _swapw(readw(addr))
 #define inl(addr)    _swapl(readl(addr))
-#define outb(x,addr) ((void)((h8300_buswidth(addr) && ((addr) & 1))?writew(x,(addr) & ~1):writeb(x,addr)))
+#define outb(x,addr) ((void)((h8300_buswidth(addr) && \
+                      ((addr) & 1))?writew(x,(addr) & ~1):writeb(x,addr)))
 #define outw(x,addr) ((void) writew(_swapw(x),addr))
 #define outl(x,addr) ((void) writel(_swapl(x),addr))
 
@@ -227,7 +271,7 @@ static __inline__ unsigned short ctrl_inw(unsigned long addr)
        return *(volatile unsigned short*)addr;
 }
 
-static __inline__ unsigned int ctrl_inl(unsigned long addr)
+static __inline__ unsigned long ctrl_inl(unsigned long addr)
 {
        return *(volatile unsigned long*)addr;
 }
@@ -242,7 +286,7 @@ static __inline__ void ctrl_outw(unsigned short b, unsigned long addr)
        *(volatile unsigned short*)addr = b;
 }
 
-static __inline__ void ctrl_outl(unsigned int b, unsigned long addr)
+static __inline__ void ctrl_outl(unsigned long b, unsigned long addr)
 {
         *(volatile unsigned long*)addr = b;
 }
index 278f104..a87720b 100644 (file)
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 /*
  * SuS says limits have to be unsigned.
        { RLIM_INFINITY, RLIM_INFINITY },               \
        {             0,             0 },               \
        {      INR_OPEN,     INR_OPEN  },               \
-       { PAGE_SIZE,     PAGE_SIZE     },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
-        { RLIM_INFINITY, RLIM_INFINITY },              \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { MAX_SIGPENDING, MAX_SIGPENDING },             \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX },                 \
 }
 
 #endif /* __KERNEL__ */
index 326c271..a6d15d4 100644 (file)
@@ -468,6 +468,7 @@ type name(atype a, btype b, ctype c, dtype d, etype e, ftype f)                     \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
index a6f5771..42164a6 100644 (file)
@@ -122,6 +122,8 @@ static inline void disable_acpi(void)
 #define FIX_ACPI_PAGES 4
 
 extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq);
+extern int (*platform_rename_gsi)(int ioapic, int gsi);
+
 #ifdef CONFIG_X86_IO_APIC
 extern int skip_ioapic_setup;
 extern int acpi_skip_timer_override;
index cd1bb1c..95cc9c1 100644 (file)
@@ -41,6 +41,8 @@ static __inline__ void apic_wait_icr_idle(void)
        do { } while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY );
 }
 
+int get_physical_broadcast(void);
+
 #ifdef CONFIG_X86_GOOD_APIC
 # define FORCE_READ_AROUND_WRITE 0
 # define apic_read_around(x)
index 2c6a7bb..8fd938f 100644 (file)
@@ -34,7 +34,7 @@
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-static __inline__ void set_bit(int nr, volatile unsigned long * addr)
+static inline void set_bit(int nr, volatile unsigned long * addr)
 {
        __asm__ __volatile__( LOCK_PREFIX
                "btsl %1,%0"
@@ -51,7 +51,7 @@ static __inline__ void set_bit(int nr, volatile unsigned long * addr)
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-static __inline__ void __set_bit(int nr, volatile unsigned long * addr)
+static inline void __set_bit(int nr, volatile unsigned long * addr)
 {
        __asm__(
                "btsl %1,%0"
@@ -69,7 +69,7 @@ static __inline__ void __set_bit(int nr, volatile unsigned long * addr)
  * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  * in order to ensure changes are visible on other processors.
  */
-static __inline__ void clear_bit(int nr, volatile unsigned long * addr)
+static inline void clear_bit(int nr, volatile unsigned long * addr)
 {
        __asm__ __volatile__( LOCK_PREFIX
                "btrl %1,%0"
@@ -77,7 +77,7 @@ static __inline__ void clear_bit(int nr, volatile unsigned long * addr)
                :"Ir" (nr));
 }
 
-static __inline__ void __clear_bit(int nr, volatile unsigned long * addr)
+static inline void __clear_bit(int nr, volatile unsigned long * addr)
 {
        __asm__ __volatile__(
                "btrl %1,%0"
@@ -96,7 +96,7 @@ static __inline__ void __clear_bit(int nr, volatile unsigned long * addr)
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-static __inline__ void __change_bit(int nr, volatile unsigned long * addr)
+static inline void __change_bit(int nr, volatile unsigned long * addr)
 {
        __asm__ __volatile__(
                "btcl %1,%0"
@@ -113,7 +113,7 @@ static __inline__ void __change_bit(int nr, volatile unsigned long * addr)
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-static __inline__ void change_bit(int nr, volatile unsigned long * addr)
+static inline void change_bit(int nr, volatile unsigned long * addr)
 {
        __asm__ __volatile__( LOCK_PREFIX
                "btcl %1,%0"
@@ -129,7 +129,7 @@ static __inline__ void change_bit(int nr, volatile unsigned long * addr)
  * This operation is atomic and cannot be reordered.  
  * It also implies a memory barrier.
  */
-static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr)
+static inline int test_and_set_bit(int nr, volatile unsigned long * addr)
 {
        int oldbit;
 
@@ -149,7 +149,7 @@ static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr)
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * addr)
+static inline int __test_and_set_bit(int nr, volatile unsigned long * addr)
 {
        int oldbit;
 
@@ -168,7 +168,7 @@ static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * addr)
  * This operation is atomic and cannot be reordered.  
  * It also implies a memory barrier.
  */
-static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr)
+static inline int test_and_clear_bit(int nr, volatile unsigned long * addr)
 {
        int oldbit;
 
@@ -188,7 +188,7 @@ static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr)
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
 {
        int oldbit;
 
@@ -200,7 +200,7 @@ static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long *addr)
 }
 
 /* WARNING: non atomic and it can be reordered! */
-static __inline__ int __test_and_change_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
 {
        int oldbit;
 
@@ -219,7 +219,7 @@ static __inline__ int __test_and_change_bit(int nr, volatile unsigned long *addr
  * This operation is atomic and cannot be reordered.  
  * It also implies a memory barrier.
  */
-static __inline__ int test_and_change_bit(int nr, volatile unsigned long* addr)
+static inline int test_and_change_bit(int nr, volatile unsigned long* addr)
 {
        int oldbit;
 
@@ -244,7 +244,7 @@ static inline int constant_test_bit(int nr, const volatile unsigned long *addr)
        return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;
 }
 
-static __inline__ int variable_test_bit(int nr, const volatile unsigned long * addr)
+static inline int variable_test_bit(int nr, const volatile unsigned long * addr)
 {
        int oldbit;
 
@@ -270,7 +270,7 @@ static __inline__ int variable_test_bit(int nr, const volatile unsigned long * a
  * Returns the bit-number of the first zero bit, not the number of the byte
  * containing a bit.
  */
-static __inline__ int find_first_zero_bit(const unsigned long *addr, unsigned size)
+static inline int find_first_zero_bit(const unsigned long *addr, unsigned size)
 {
        int d0, d1, d2;
        int res;
@@ -294,6 +294,14 @@ static __inline__ int find_first_zero_bit(const unsigned long *addr, unsigned si
        return res;
 }
 
+/**
+ * find_next_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
+int find_next_zero_bit(const unsigned long *addr, int size, int offset);
+
 /**
  * find_first_bit - find the first set bit in a memory region
  * @addr: The address to start the search at
@@ -302,7 +310,7 @@ static __inline__ int find_first_zero_bit(const unsigned long *addr, unsigned si
  * Returns the bit-number of the first set bit, not the number of the byte
  * containing a bit.
  */
-static __inline__ int find_first_bit(const unsigned long *addr, unsigned size)
+static inline int find_first_bit(const unsigned long *addr, unsigned size)
 {
        int d0, d1;
        int res;
@@ -322,71 +330,13 @@ static __inline__ int find_first_bit(const unsigned long *addr, unsigned size)
        return res;
 }
 
-/**
- * find_next_zero_bit - find the first zero bit in a memory region
- * @addr: The address to base the search on
- * @offset: The bitnumber to start searching at
- * @size: The maximum size to search
- */
-static __inline__ int find_next_zero_bit(const unsigned long *addr, int size, int offset)
-{
-       unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
-       int set = 0, bit = offset & 31, res;
-       
-       if (bit) {
-               /*
-                * Look for zero in the first 32 bits.
-                */
-               __asm__("bsfl %1,%0\n\t"
-                       "jne 1f\n\t"
-                       "movl $32, %0\n"
-                       "1:"
-                       : "=r" (set)
-                       : "r" (~(*p >> bit)));
-               if (set < (32 - bit))
-                       return set + offset;
-               set = 32 - bit;
-               p++;
-       }
-       /*
-        * No zero yet, search remaining full bytes for a zero
-        */
-       res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
-       return (offset + set + res);
-}
-
 /**
  * find_next_bit - find the first set bit in a memory region
  * @addr: The address to base the search on
  * @offset: The bitnumber to start searching at
  * @size: The maximum size to search
  */
-static __inline__ int find_next_bit(const unsigned long *addr, int size, int offset)
-{
-       const unsigned long *p = addr + (offset >> 5);
-       int set = 0, bit = offset & 31, res;
-
-       if (bit) {
-               /*
-                * Look for nonzero in the first 32 bits:
-                */
-               __asm__("bsfl %1,%0\n\t"
-                       "jne 1f\n\t"
-                       "movl $32, %0\n"
-                       "1:"
-                       : "=r" (set)
-                       : "r" (*p >> bit));
-               if (set < (32 - bit))
-                       return set + offset;
-               set = 32 - bit;
-               p++;
-       }
-       /*
-        * No set bit yet, search remaining full words for a bit
-        */
-       res = find_first_bit (p, size - 32 * (p - addr));
-       return (offset + set + res);
-}
+int find_next_bit(const unsigned long *addr, int size, int offset);
 
 /**
  * ffz - find first zero in word.
@@ -394,7 +344,7 @@ static __inline__ int find_next_bit(const unsigned long *addr, int size, int off
  *
  * Undefined if no zero exists, so code should check against ~0UL first.
  */
-static __inline__ unsigned long ffz(unsigned long word)
+static inline unsigned long ffz(unsigned long word)
 {
        __asm__("bsfl %1,%0"
                :"=r" (word)
@@ -408,7 +358,7 @@ static __inline__ unsigned long ffz(unsigned long word)
  *
  * Undefined if no bit exists, so code should check against 0 first.
  */
-static __inline__ unsigned long __ffs(unsigned long word)
+static inline unsigned long __ffs(unsigned long word)
 {
        __asm__("bsfl %1,%0"
                :"=r" (word)
@@ -451,7 +401,7 @@ static inline int sched_find_first_bit(const unsigned long *b)
  * the libc and compiler builtin ffs routines, therefore
  * differs in spirit from the above ffz (man ffs).
  */
-static __inline__ int ffs(int x)
+static inline int ffs(int x)
 {
        int r;
 
index 59fe7fc..2d434cc 100644 (file)
@@ -177,8 +177,10 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
  *     Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int direct_csum_and_copy_to_user(const char *src, char *dst,
-                                   int len, int sum, int *err_ptr)
+static __inline__ unsigned int direct_csum_and_copy_to_user(const char *src, 
+                                                    char __user *dst,
+                                                    int len, int sum, 
+                                                    int *err_ptr)
 {
        if (access_ok(VERIFY_WRITE, dst, len))
                return direct_csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
@@ -189,7 +191,7 @@ static __inline__ unsigned int direct_csum_and_copy_to_user(const char *src, cha
        return -1; /* invalid checksum */
 }
 
-static __inline__ unsigned int csum_and_copy_to_user(const char *src, char *dst,
+static __inline__ unsigned int csum_and_copy_to_user(const char *src, char __user *dst,
                                    int len, int sum, int *err_ptr)
 {
        if (access_ok(VERIFY_WRITE, dst, len)) {
index 72930c7..456db85 100644 (file)
@@ -16,7 +16,7 @@ extern void __const_udelay(unsigned long usecs);
 extern void __delay(unsigned long loops);
 
 #define udelay(n) (__builtin_constant_p(n) ? \
-       ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c6ul)) : \
+       ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
        __udelay(n))
        
 #define ndelay(n) (__builtin_constant_p(n) ? \
index 410430c..79bfab5 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef _ASM_I386_DMA_MAPPING_H
 #define _ASM_I386_DMA_MAPPING_H
 
+#include <linux/device.h>
+#include <linux/mm.h>
+
 #include <asm/cache.h>
 #include <asm/io.h>
 #include <asm/scatterlist.h>
index 8e420ad..f478228 100644 (file)
@@ -204,7 +204,7 @@ static unsigned long vdma_mem_alloc(unsigned long size)
 static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
 {
        if((unsigned int) addr >= (unsigned int) high_memory)
-               return vfree((void *)addr);
+               vfree((void *)addr);
        else
                free_pages(addr, get_order(size));              
 }
index cf61fde..d62ac25 100644 (file)
@@ -25,7 +25,6 @@ struct genapic {
        cpumask_t (*target_cpus)(void);
        int int_delivery_mode;
        int int_dest_mode; 
-       int apic_broadcast_id; 
        int ESR_DISABLE;
        int apic_destination_logical;
        unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid);
@@ -78,7 +77,6 @@ struct genapic {
        .probe = aprobe, \
        .int_delivery_mode = INT_DELIVERY_MODE, \
        .int_dest_mode = INT_DEST_MODE, \
-       .apic_broadcast_id = APIC_BROADCAST_ID, \
        .no_balance_irq = NO_BALANCE_IRQ, \
        .no_ioapic_check = NO_IOAPIC_CHECK, \
        .ESR_DISABLE = esr_disable, \
index 9382e16..8fd9f40 100644 (file)
 #define HPET_ID_LEGSUP 0x00008000
 #define HPET_ID_NUMBER 0x00001f00
 #define HPET_ID_REV    0x000000ff
+#define        HPET_ID_NUMBER_SHIFT    8
 
 #define HPET_CFG_ENABLE        0x001
 #define HPET_CFG_LEGACY        0x002
+#define        HPET_LEGACY_8254        2
+#define        HPET_LEGACY_RTC         8
 
 #define HPET_TN_ENABLE         0x004
 #define HPET_TN_PERIODIC       0x008
index db66369..6d8a199 100644 (file)
@@ -51,7 +51,7 @@ static inline void __save_init_fpu( struct task_struct *tsk )
 #define __clear_fpu( tsk )                                     \
 do {                                                           \
        if ((tsk)->thread_info->status & TS_USEDFPU) {          \
-               asm volatile("fwait");                          \
+               asm volatile("fnclex ; fwait");                         \
                (tsk)->thread_info->status &= ~TS_USEDFPU;      \
                stts();                                         \
        }                                                       \
index 0409c22..859ebf4 100644 (file)
@@ -28,9 +28,6 @@
 static __inline__ int ide_default_irq(unsigned long base)
 {
        switch (base) {
-#ifdef CONFIG_X86_PC9800
-               case 0x640: return 9;
-#endif
                case 0x1f0: return 14;
                case 0x170: return 15;
                case 0x1e8: return 11;
@@ -45,48 +42,17 @@ static __inline__ int ide_default_irq(unsigned long base)
 static __inline__ unsigned long ide_default_io_base(int index)
 {
        switch (index) {
-#ifdef CONFIG_X86_PC9800
-               case 0:
-               case 1: return 0x640;
-#else
                case 0: return 0x1f0;
                case 1: return 0x170;
                case 2: return 0x1e8;
                case 3: return 0x168;
                case 4: return 0x1e0;
                case 5: return 0x160;
-#endif
                default:
                        return 0;
        }
 }
 
-#ifdef CONFIG_X86_PC9800
-static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
-        unsigned long ctrl_port, int *irq)
-{
-       unsigned long reg = data_port;
-       int i;
-
-       unsigned long increment = data_port == 0x640 ? 2 : 1;
-
-       for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-               hw->io_ports[i] = reg;
-               reg += increment;
-       }
-       if (ctrl_port) {
-               hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
-       } else if (data_port == 0x640) {
-               hw->io_ports[IDE_CONTROL_OFFSET] = 0x74c;
-       } else {
-               hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
-       }
-       if (irq != NULL)
-               *irq = 0;
-       hw->io_ports[IDE_IRQ_OFFSET] = 0;
-}
-#endif
-
 #define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)       ((base) + 0x206) /* obsolete */
 
index 861ecee..37b969f 100644 (file)
@@ -188,15 +188,6 @@ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned
        *(IO_APIC_BASE(apic)+4) = value;
 }
 
-/*
- * Synchronize the IO-APIC and the CPU by doing
- * a dummy read from the IO-APIC
- */
-static inline void io_apic_sync(unsigned int apic)
-{
-       (void) *(IO_APIC_BASE(apic)+4);
-}
-
 /* 1 if "noapic" boot option passed */
 extern int skip_ioapic_setup;
 
index e7b7b2d..ab60c85 100644 (file)
@@ -39,7 +39,6 @@ static inline cpumask_t target_cpus(void)
 #define INT_DELIVERY_MODE dest_Fixed
 #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
 
-#define APIC_BROADCAST_ID     (0xff)
 static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
 {
        return 0;
index cf0b2f6..6b5dadc 100644 (file)
@@ -1,11 +1,6 @@
 #ifndef __ASM_MACH_MPSPEC_H
 #define __ASM_MACH_MPSPEC_H
 
-/*
- * a maximum of 16 APICs with the current APIC ID architecture.
- */
-#define MAX_APICS 16
-
 #define MAX_IRQ_SOURCES 256
 
 #define MAX_MP_BUSSES 32
index 5111b01..87f6887 100644 (file)
@@ -2,6 +2,7 @@
 #define __ASM_MACH_APIC_H
 
 #include <mach_apicdef.h>
+#include <asm/smp.h>
 
 #define APIC_DFR_VALUE (APIC_DFR_FLAT)
 
@@ -23,12 +24,6 @@ static inline cpumask_const_t target_cpus(void)
 #define INT_DELIVERY_MODE dest_LowestPrio
 #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
 
-/*
- * this isn't really broadcast, just a (potentially inaccurate) upper
- * bound for valid physical APIC id's
- */
-#define APIC_BROADCAST_ID      0x0F
-
 static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
 {
        return physid_isset(apicid, bitmap);
@@ -85,7 +80,10 @@ static inline int cpu_to_logical_apicid(int cpu)
 
 static inline int cpu_present_to_apicid(int mps_cpu)
 {
-       return  mps_cpu;
+       if (mps_cpu < get_physical_broadcast())
+               return  mps_cpu;
+       else
+               return BAD_APICID;
 }
 
 static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
index cf0b2f6..6b5dadc 100644 (file)
@@ -1,11 +1,6 @@
 #ifndef __ASM_MACH_MPSPEC_H
 #define __ASM_MACH_MPSPEC_H
 
-/*
- * a maximum of 16 APICs with the current APIC ID architecture.
- */
-#define MAX_APICS 16
-
 #define MAX_IRQ_SOURCES 256
 
 #define MAX_MP_BUSSES 32
index 0405b6b..fd0430c 100644 (file)
@@ -38,7 +38,6 @@ static inline cpumask_t target_cpus(void)
 #define WAKE_SECONDARY_VIA_INIT
 #endif
 
-#define APIC_BROADCAST_ID      (0xff)
 #define NO_IOAPIC_CHECK (1)
 
 static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
index ef10cd2..6b5dadc 100644 (file)
@@ -1,11 +1,6 @@
 #ifndef __ASM_MACH_MPSPEC_H
 #define __ASM_MACH_MPSPEC_H
 
-/*
- * a maximum of 256 APICs with the current APIC ID architecture.
- */
-#define MAX_APICS 256
-
 #define MAX_IRQ_SOURCES 256
 
 #define MAX_MP_BUSSES 32
index a7d6246..ab36d02 100644 (file)
@@ -6,7 +6,6 @@
 #define esr_disable (genapic->ESR_DISABLE)
 #define NO_BALANCE_IRQ (genapic->no_balance_irq)
 #define NO_IOAPIC_CHECK        (genapic->no_ioapic_check)
-#define APIC_BROADCAST_ID (genapic->apic_broadcast_id)
 #define INT_DELIVERY_MODE (genapic->int_delivery_mode)
 #define INT_DEST_MODE (genapic->int_dest_mode)
 #undef APIC_DEST_LOGICAL
index fbb6a40..9ef0b94 100644 (file)
@@ -1,11 +1,6 @@
 #ifndef __ASM_MACH_MPSPEC_H
 #define __ASM_MACH_MPSPEC_H
 
-/*
- * a maximum of 256 APICs with the current APIC ID architecture.
- */
-#define MAX_APICS 256
-
 #define MAX_IRQ_SOURCES 256
 
 /* Summit or generic (i.e. installer) kernels need lots of bus entries. */
index 743bb69..b66e78d 100644 (file)
@@ -22,7 +22,6 @@ static inline cpumask_t target_cpus(void)
 #define INT_DELIVERY_MODE dest_LowestPrio
 #define INT_DEST_MODE 0     /* physical delivery on LOCAL quad */
  
-#define APIC_BROADCAST_ID      0x0F
 #define check_apicid_used(bitmap, apicid) physid_isset(apicid, bitmap)
 #define check_apicid_present(bit) physid_isset(bit, phys_cpu_present_map)
 #define apicid_cluster(apicid) (apicid & 0xF0)
index badb10c..dffb098 100644 (file)
@@ -1,11 +1,6 @@
 #ifndef __ASM_MACH_MPSPEC_H
 #define __ASM_MACH_MPSPEC_H
 
-/*
- * a maximum of 256 APICs with the current APIC ID architecture.
- */
-#define MAX_APICS 256
-
 #define MAX_IRQ_SOURCES 512
 
 #define MAX_MP_BUSSES 32
index accca8f..9ea48a7 100644 (file)
@@ -27,7 +27,6 @@ static inline cpumask_t target_cpus(void)
 #define INT_DELIVERY_MODE (dest_Fixed)
 #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
 
-#define APIC_BROADCAST_ID     (0xFF)
 static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
 {
        return 0;
index bc8f717..bd76552 100644 (file)
@@ -1,11 +1,6 @@
 #ifndef __ASM_MACH_MPSPEC_H
 #define __ASM_MACH_MPSPEC_H
 
-/*
- * a maximum of 256 APICs with the current APIC ID architecture.
- */
-#define MAX_APICS 256
-
 #define MAX_IRQ_SOURCES 256
 
 /* Maximum 256 PCI busses, plus 1 ISA bus in each of 4 cabinets. */
index 3ec402a..4b92eab 100644 (file)
@@ -19,7 +19,6 @@
  #define TARGET_CPUS cpumask_of_cpu(0)
 #endif
 
-#define APIC_BROADCAST_ID      0x0F
 #define check_apicid_used(bitmap, apicid)      physid_isset(apicid, bitmap)
 #define check_apicid_present(bit)              physid_isset(bit, phys_cpu_present_map)
 
@@ -61,7 +60,10 @@ static inline int cpu_to_logical_apicid(int cpu)
 
 static inline int cpu_present_to_apicid(int mps_cpu)
 {
-       return mps_cpu;
+       if (mps_cpu < get_physical_broadcast())
+               return mps_cpu;
+       else
+               return BAD_APICID;
 }
 
 static inline physid_mask_t apicid_to_cpu_present(int apicid)
index b376b09..b2cc2fe 100644 (file)
@@ -33,7 +33,7 @@ extern void mp_register_lapic_address (u64 address);
 extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
 extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
 extern void mp_config_acpi_legacy_irqs (void);
-extern void mp_parse_prt (void);
+extern void mp_register_gsi (u32 gsi, int edge_level, int active_high_low);
 #endif /*CONFIG_ACPI_BOOT*/
 
 #define PHYSID_ARRAY_SIZE      BITS_TO_LONGS(MAX_APICS)
index 0546e45..a961093 100644 (file)
@@ -14,6 +14,7 @@
 #define SMP_MAGIC_IDENT        (('_'<<24)|('P'<<16)|('M'<<8)|'_')
 
 #define MAX_MPC_ENTRY 1024
+#define MAX_APICS      256
 
 struct intel_mp_floating
 {
index e7047ef..b853930 100644 (file)
@@ -16,7 +16,7 @@
 #ifdef CONFIG_SMP
 #define MSI_TARGET_CPU         logical_smp_processor_id()
 #else
-#define MSI_TARGET_CPU         TARGET_CPUS
+#define MSI_TARGET_CPU cpu_to_logical_apicid(first_cpu(cpu_online_map))
 #endif
 
 #endif /* ASM_MSI_H */
index dd0bb8a..dfb5cf4 100644 (file)
@@ -252,8 +252,20 @@ static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte_low |= _PAGE_DIRTY; retur
 static inline pte_t pte_mkyoung(pte_t pte)     { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
 static inline pte_t pte_mkwrite(pte_t pte)     { (pte).pte_low |= _PAGE_RW; return pte; }
 
-static inline  int ptep_test_and_clear_dirty(pte_t *ptep)      { return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); }
-static inline  int ptep_test_and_clear_young(pte_t *ptep)      { return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low); }
+static inline int ptep_test_and_clear_dirty(pte_t *ptep)
+{
+       if (!pte_dirty(*ptep))
+               return 0;
+       return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low);
+}
+
+static inline int ptep_test_and_clear_young(pte_t *ptep)
+{
+       if (!pte_young(*ptep))
+               return 0;
+       return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low);
+}
+
 static inline void ptep_set_wrprotect(pte_t *ptep)             { clear_bit(_PAGE_BIT_RW, &ptep->pte_low); }
 static inline void ptep_mkdirty(pte_t *ptep)                   { set_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); }
 
index efdbf17..befdb04 100644 (file)
@@ -259,14 +259,8 @@ static inline void clear_in_cr4 (unsigned long mask)
 
 /*
  * Bus types (default is ISA, but people can check others with these..)
- * pc98 indicates PC98 systems (CBUS)
  */
 extern int MCA_bus;
-#ifdef CONFIG_X86_PC9800
-#define pc98 1
-#else
-#define pc98 0
-#endif
 
 static inline void __monitor(const void *eax, unsigned long ecx,
                unsigned long edx)
index afa2eec..3e391b2 100644 (file)
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
+
+#define RLIM_NLIMITS   13
 
-#define RLIM_NLIMITS   11
 
 /*
  * SuS says limits have to be unsigned.
        { RLIM_INFINITY, RLIM_INFINITY },               \
        {             0,             0 },               \
        {      INR_OPEN,     INR_OPEN  },               \
-       { PAGE_SIZE,     PAGE_SIZE     },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
-        { RLIM_INFINITY, RLIM_INFINITY },              \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { MAX_SIGPENDING, MAX_SIGPENDING },             \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX },                 \
 }
 
 #endif /* __KERNEL__ */
index 9d67798..21ddecc 100644 (file)
 
 #define C_P(card,port) (((card)<<6|(port)<<3) + 1)
 
-#ifndef CONFIG_X86_PC9800
 #define STD_SERIAL_PORT_DEFNS                  \
        /* UART CLK   PORT IRQ     FLAGS        */                      \
        { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },      /* ttyS0 */     \
        { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },      /* ttyS1 */     \
        { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },      /* ttyS2 */     \
        { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },     /* ttyS3 */
-#else
-#define STD_SERIAL_PORT_DEFNS                  \
-       /* UART CLK   PORT IRQ     FLAGS        */                      \
-       { 0, BASE_BAUD, 0x30, 4, STD_COM_FLAGS },       /* ttyS0 */     \
-       { 0, BASE_BAUD, 0x238, 5, STD_COM_FLAGS },      /* ttyS1 */
-#endif /* CONFIG_X86_PC9800 */
 
 
 #ifdef CONFIG_SERIAL_MANY_PORTS
index a447a99..e737729 100644 (file)
@@ -9,15 +9,11 @@
 #include <linux/config.h>
 #include <asm/msr.h>
 
-#ifdef CONFIG_X86_PC9800
-   extern int CLOCK_TICK_RATE;
-#else
 #ifdef CONFIG_X86_ELAN
 #  define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */
 #else
 #  define CLOCK_TICK_RATE 1193182 /* Underlying HZ */
 #endif
-#endif
 
 #define CLOCK_TICK_FACTOR      20      /* Factor of both 1000000 and CLOCK_TICK_RATE */
 #define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
index b70f8a9..58d12cf 100644 (file)
@@ -408,6 +408,7 @@ __syscall_return(type,__res); \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
index bd39859..c9b8bba 100644 (file)
@@ -11,7 +11,7 @@
 
 #include <linux/compiler.h>
 #include <linux/types.h>
-
+#include <asm/bitops.h>
 #include <asm/intrinsics.h>
 
 /**
@@ -359,93 +359,21 @@ hweight64 (unsigned long x)
 
 #endif /* __KERNEL__ */
 
-/*
- * Find next zero bit in a bitmap reasonably efficiently..
- */
-static inline int
-find_next_zero_bit (void *addr, unsigned long size, unsigned long offset)
-{
-       unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
-       unsigned long result = offset & ~63UL;
-       unsigned long tmp;
-
-       if (offset >= size)
-               return size;
-       size -= result;
-       offset &= 63UL;
-       if (offset) {
-               tmp = *(p++);
-               tmp |= ~0UL >> (64-offset);
-               if (size < 64)
-                       goto found_first;
-               if (~tmp)
-                       goto found_middle;
-               size -= 64;
-               result += 64;
-       }
-       while (size & ~63UL) {
-               if (~(tmp = *(p++)))
-                       goto found_middle;
-               result += 64;
-               size -= 64;
-       }
-       if (!size)
-               return result;
-       tmp = *p;
-found_first:
-       tmp |= ~0UL << size;
-       if (tmp == ~0UL)                /* any bits zero? */
-               return result + size;   /* nope */
-found_middle:
-       return result + ffz(tmp);
-}
+extern int __find_next_zero_bit (void *addr, unsigned long size,
+                       unsigned long offset);
+extern int __find_next_bit(const void *addr, unsigned long size,
+                       unsigned long offset);
+
+#define find_next_zero_bit(addr, size, offset) \
+                       __find_next_zero_bit((addr), (size), (offset))
+#define find_next_bit(addr, size, offset) \
+                       __find_next_bit((addr), (size), (offset))
 
 /*
  * The optimizer actually does good code for this case..
  */
 #define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
 
-/*
- * Find next bit in a bitmap reasonably efficiently..
- */
-static inline int
-find_next_bit(const void *addr, unsigned long size, unsigned long offset)
-{
-       unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
-       unsigned long result = offset & ~63UL;
-       unsigned long tmp;
-
-       if (offset >= size)
-               return size;
-       size -= result;
-       offset &= 63UL;
-       if (offset) {
-               tmp = *(p++);
-               tmp &= ~0UL << offset;
-               if (size < 64)
-                       goto found_first;
-               if (tmp)
-                       goto found_middle;
-               size -= 64;
-               result += 64;
-       }
-       while (size & ~63UL) {
-               if ((tmp = *(p++)))
-                       goto found_middle;
-               result += 64;
-               size -= 64;
-       }
-       if (!size)
-               return result;
-       tmp = *p;
-  found_first:
-       tmp &= ~0UL >> (64-size);
-       if (tmp == 0UL)         /* Are any bits set? */
-               return result + size; /* Nope. */
-  found_middle:
-       return result + __ffs(tmp);
-}
-
 #define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
 
 #ifdef __KERNEL__
index d5bda84..1174e97 100644 (file)
@@ -60,7 +60,6 @@ extern void __init iosapic_init (unsigned long address,
                                    unsigned int gsi_base);
 extern int gsi_to_vector (unsigned int gsi);
 extern int gsi_to_irq (unsigned int gsi);
-extern void __init iosapic_parse_prt (void);
 extern void iosapic_enable_intr (unsigned int vector);
 extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity,
                                  unsigned long trigger);
index 590432c..8d727c6 100644 (file)
@@ -346,6 +346,8 @@ static inline int
 ptep_test_and_clear_young (pte_t *ptep)
 {
 #ifdef CONFIG_SMP
+       if (!pte_young(*ptep))
+               return 0;
        return test_and_clear_bit(_PAGE_A_BIT, ptep);
 #else
        pte_t pte = *ptep;
@@ -360,6 +362,8 @@ static inline int
 ptep_test_and_clear_dirty (pte_t *ptep)
 {
 #ifdef CONFIG_SMP
+       if (!pte_dirty(*ptep))
+               return 0;
        return test_and_clear_bit(_PAGE_D_BIT, ptep);
 #else
        pte_t pte = *ptep;
index eb171fc..76345b5 100644 (file)
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 /*
  * SuS says limits have to be unsigned.
        { RLIM_INFINITY, RLIM_INFINITY },               \
        {             0,             0 },               \
        {      INR_OPEN,     INR_OPEN  },               \
-       { PAGE_SIZE,     PAGE_SIZE     },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { MAX_SIGPENDING, MAX_SIGPENDING },             \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX },                 \
 }
 
 # endif /* __KERNEL__ */
index 2c53f8d..57c7db1 100644 (file)
@@ -239,7 +239,7 @@ extern void ia64_load_extra (struct task_struct *task);
  * the latest fph state from another CPU.  In other words: eager save, lazy restore.
  */
 # define switch_to(prev,next,last) do {                                                \
-       if (ia64_psr(ia64_task_regs(prev))->mfh) {                              \
+       if (ia64_psr(ia64_task_regs(prev))->mfh && ia64_is_local_fpu_owner(prev)) {                             \
                ia64_psr(ia64_task_regs(prev))->mfh = 0;                        \
                (prev)->thread.flags |= IA64_THREAD_FPH_VALID;                  \
                __ia64_save_fpu((prev)->thread.fph);                            \
index 0fb8244..251ecfa 100644 (file)
 #define __NR_mq_notify                 1266
 #define __NR_mq_getsetattr             1267
 #define __NR_kexec_load                        1268
+#define __NR_vserver                   1269
 
 #ifdef __KERNEL__
 
 # define __ARCH_WANT_SYS_SIGPENDING
 # define __ARCH_WANT_SYS_SIGPROCMASK
 #endif
+# define __ARCH_WANT_SYS_RT_SIGACTION
 
 #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
 
index 8b6e74a..8362001 100644 (file)
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 /*
  * SuS says limits have to be unsigned.
        { RLIM_INFINITY, RLIM_INFINITY },               \
        {             0,             0 },               \
        {      INR_OPEN,     INR_OPEN  },               \
-       { PAGE_SIZE,     PAGE_SIZE     },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
-        { RLIM_INFINITY, RLIM_INFINITY },              \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { MAX_SIGPENDING, MAX_SIGPENDING },             \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX },                 \
 }
 
 #endif /* __KERNEL__ */
index 0bf2789..6a10578 100644 (file)
@@ -359,6 +359,7 @@ __syscall_return(type,__res); \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
index 6f35eb2..b10e469 100644 (file)
@@ -394,6 +394,7 @@ type name(atype a, btype b, ctype c, dtype d, etype e)                              \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
index e31681a..0654264 100644 (file)
@@ -41,7 +41,8 @@ unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len,
  * Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static inline unsigned int csum_and_copy_to_user (const char *src, char *dst,
+static inline unsigned int csum_and_copy_to_user (const char *src, 
+                                                 char __user *dst,
                                                  int len, int sum,
                                                  int *err_ptr)
 {
index 4beb215..2453e0d 100644 (file)
 #define RLIMIT_NPROC 8                 /* max number of processes */
 #define RLIMIT_MEMLOCK 9               /* max locked-in-memory address space */
 #define RLIMIT_LOCKS 10                        /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS 11                        /* Number of limit flavors.  */
+#define RLIM_NLIMITS 13                        /* Number of limit flavors.  */
 
 #ifdef __KERNEL__
 
@@ -54,6 +56,8 @@
        { 0,             0             },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
+       { MAX_SIGPENDING, MAX_SIGPENDING },             \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX },                 \
 }
 
 #endif /* __KERNEL__ */
index 22d59d8..4dfc72b 100644 (file)
@@ -1091,6 +1091,7 @@ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 # ifndef __mips64
 #  define __ARCH_WANT_STAT64
 # endif
index 5681db8..2dcadec 100644 (file)
@@ -191,8 +191,10 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
  *     Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user (const char *src, char *dst,
-                                   int len, int sum, int *err_ptr)
+static __inline__ unsigned int csum_and_copy_to_user (const char *src, 
+                                                     char __user *dst,
+                                                     int len, int sum, 
+                                                     int *err_ptr)
 {
        /* code stolen from include/asm-mips64 */
        sum = csum_partial(src, len, sum);
index cadae7f..37da218 100644 (file)
@@ -417,6 +417,8 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 static inline int ptep_test_and_clear_young(pte_t *ptep)
 {
 #ifdef CONFIG_SMP
+       if (!pte_young(*ptep))
+               return 0;
        return test_and_clear_bit(xlate_pabit(_PAGE_ACCESSED_BIT), ptep);
 #else
        pte_t pte = *ptep;
@@ -430,6 +432,8 @@ static inline int ptep_test_and_clear_young(pte_t *ptep)
 static inline int ptep_test_and_clear_dirty(pte_t *ptep)
 {
 #ifdef CONFIG_SMP
+       if (!pte_dirty(*ptep))
+               return 0;
        return test_and_clear_bit(xlate_pabit(_PAGE_DIRTY_BIT), ptep);
 #else
        pte_t pte = *ptep;
index 8b0fab7..59a4465 100644 (file)
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 /*
  * SuS says limits have to be unsigned.
        { RLIM_INFINITY, RLIM_INFINITY },               \
        {             0,             0 },               \
        {      INR_OPEN,     INR_OPEN  },               \
-       { PAGE_SIZE,     PAGE_SIZE     },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { MAX_SIGPENDING, MAX_SIGPENDING },             \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX },                 \
 }
 
 #endif /* __KERNEL__ */
index de710ff..72b457d 100644 (file)
@@ -899,6 +899,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)       \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
 /* mmap & mmap2 take 6 arguments */
index ff3be2d..6b2579d 100644 (file)
@@ -23,26 +23,30 @@ struct bug_entry {
                : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
 } while (0)
 
-#define BUG_ON(x) do {                                         \
-       __asm__ __volatile__(                                   \
-               "1:     twnei %0,0\n"                           \
-               ".section __bug_table,\"a\"\n\t"                \
-               "       .long 1b,%1,%2,%3\n"                    \
-               ".previous"                                     \
-               : : "r" (x), "i" (__LINE__), "i" (__FILE__),    \
-                   "i" (__FUNCTION__));                        \
+#define BUG_ON(x) do {                                                 \
+       if (!__builtin_constant_p(x) || (x)) {                          \
+               __asm__ __volatile__(                                   \
+                       "1:     twnei %0,0\n"                           \
+                       ".section __bug_table,\"a\"\n\t"                \
+                       "       .long 1b,%1,%2,%3\n"                    \
+                       ".previous"                                     \
+                       : : "r" (x), "i" (__LINE__), "i" (__FILE__),    \
+                           "i" (__FUNCTION__));                        \
+       }                                                               \
 } while (0)
 
-#define PAGE_BUG(page) do { BUG(); } while (0)
+#define PAGE_BUG(page) BUG()
 
-#define WARN_ON(x) do {                                                \
-       __asm__ __volatile__(                                   \
-               "1:     twnei %0,0\n"                           \
-               ".section __bug_table,\"a\"\n\t"                \
-               "       .long 1b,%1,%2,%3\n"                    \
-               ".previous"                                     \
-               : : "r" (x), "i" (__LINE__ + BUG_WARNING_TRAP), \
-                   "i" (__FILE__), "i" (__FUNCTION__));        \
+#define WARN_ON(x) do {                                                        \
+       if (!__builtin_constant_p(x) || (x)) {                          \
+               __asm__ __volatile__(                                   \
+                       "1:     twnei %0,0\n"                           \
+                       ".section __bug_table,\"a\"\n\t"                \
+                       "       .long 1b,%1,%2,%3\n"                    \
+                       ".previous"                                     \
+                       : : "r" (x), "i" (__LINE__ + BUG_WARNING_TRAP), \
+                           "i" (__FILE__), "i" (__FUNCTION__));        \
+       }                                                               \
 } while (0)
 
 #endif
index 174fb0c..2c05696 100644 (file)
@@ -52,6 +52,7 @@
 #define ELF_NGREG      48      /* includes nip, msr, lr, etc. */
 #define ELF_NFPREG     33      /* includes fpscr */
 #define ELF_NVRREG     33      /* includes vscr */
+#define ELF_NEVRREG    34      /* includes acc (as 2) */
 
 /*
  * These are used to set parameters in the core dumps.
index 8f4f12a..2531c3b 100644 (file)
@@ -83,11 +83,15 @@ typedef struct {
 
 #ifdef CONFIG_PREEMPT
 # define in_atomic()   ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
+# define preemptible() (preempt_count() == 0 && !irqs_disabled())
 # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
+
 #else
 # define in_atomic()   (preempt_count() != 0)
+# define preemptible() 0
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
+
 #define irq_exit()                                                     \
 do {                                                                   \
        preempt_count() -= IRQ_EXIT_OFFSET;                             \
index 9cc9d5f..e1b84f2 100644 (file)
@@ -30,6 +30,8 @@
 #include <asm/mpc8xx.h>
 #elif defined(CONFIG_8260)
 #include <asm/mpc8260.h>
+#elif defined(CONFIG_85xx)
+#include <asm/mpc85xx.h>
 #elif defined(CONFIG_APUS)
 #define _IO_BASE       0
 #define _ISA_MEM_BASE  0
index 5797fd1..7bf3a4d 100644 (file)
@@ -379,6 +379,74 @@ typedef struct _P601_BAT {
 #define PPC44x_TLB_SW          0x00000002      /* Super write */
 #define PPC44x_TLB_SR          0x00000001      /* Super read */
 
+/* Book-E defined page sizes */
+#define BOOKE_PAGESZ_1K                0
+#define BOOKE_PAGESZ_4K                1
+#define BOOKE_PAGESZ_16K       2
+#define BOOKE_PAGESZ_64K       3
+#define BOOKE_PAGESZ_256K      4
+#define BOOKE_PAGESZ_1M                5
+#define BOOKE_PAGESZ_4M                6
+#define BOOKE_PAGESZ_16M       7
+#define BOOKE_PAGESZ_64M       8
+#define BOOKE_PAGESZ_256M      9
+#define BOOKE_PAGESZ_1GB       10
+#define BOOKE_PAGESZ_4GB       11
+#define BOOKE_PAGESZ_16GB      12
+#define BOOKE_PAGESZ_64GB      13
+#define BOOKE_PAGESZ_256GB     14
+#define BOOKE_PAGESZ_1TB       15
+
+/*
+ * Freescale Book-E MMU support
+ */
+
+#define MAS0_TLBSEL    0x10000000
+#define MAS0_ESEL      0x000F0000
+#define MAS0_NV                0x00000001
+
+#define MAS1_VALID     0x80000000
+#define MAS1_IPROT     0x40000000
+#define MAS1_TID       0x03FF0000
+#define MAS1_TS                0x00001000
+#define MAS1_TSIZE(x)  (x << 8)
+
+#define MAS2_EPN       0xFFFFF000
+#define MAS2_SHAREN    0x00000200
+#define MAS2_X0                0x00000040
+#define MAS2_X1                0x00000020
+#define MAS2_W         0x00000010
+#define MAS2_I         0x00000008
+#define MAS2_M         0x00000004
+#define MAS2_G         0x00000002
+#define MAS2_E         0x00000001
+
+#define MAS3_RPN       0xFFFFF000
+#define MAS3_U0                0x00000200
+#define MAS3_U1                0x00000100
+#define MAS3_U2                0x00000080
+#define MAS3_U3                0x00000040
+#define MAS3_UX                0x00000020
+#define MAS3_SX                0x00000010
+#define MAS3_UW                0x00000008
+#define MAS3_SW                0x00000004
+#define MAS3_UR                0x00000002
+#define MAS3_SR                0x00000001
+
+#define MAS4_TLBSELD   0x10000000
+#define MAS4_TIDDSEL   0x00030000
+#define MAS4_DSHAREN   0x00001000
+#define MAS4_TSIZED(x) (x << 8)
+#define MAS4_X0D       0x00000040
+#define MAS4_X1D       0x00000020
+#define MAS4_WD                0x00000010
+#define MAS4_ID                0x00000008
+#define MAS4_MD                0x00000004
+#define MAS4_GD                0x00000002
+#define MAS4_ED                0x00000001
+
+#define MAS6_SPID      0x00FF0000
+#define MAS6_SAS       0x00000001
 
 #endif /* _PPC_MMU_H_ */
 #endif /* __KERNEL__ */
index ff1883f..1ad441d 100644 (file)
@@ -63,6 +63,11 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 #define LAST_CONTEXT           255
 #define FIRST_CONTEXT          1
 
+#elif CONFIG_E500
+#define NO_CONTEXT             256
+#define LAST_CONTEXT           255
+#define FIRST_CONTEXT          1
+
 #else
 
 /* PPC 6xx, 7xx CPUs */
index ce22207..213b0a7 100644 (file)
 #include <platforms/est8260.h>
 #endif
 
+#ifdef CONFIG_SBC82xx
+#include <platforms/sbc82xx.h>
+#endif
+
 #ifdef CONFIG_SBS8260
 #include <platforms/sbs8260.h>
 #endif
index 3d735b9..5ea44ca 100644 (file)
@@ -202,6 +202,10 @@ static DEVICE_ATTR(name##_##field, S_IRUGO, show_##name##_##field, NULL);
 #include <asm/ibm_ocp.h>
 #endif
 
+#ifdef CONFIG_FSL_OCP
+#include <asm/fsl_ocp.h>
+#endif
+
 #endif                         /* CONFIG_PPC_OCP */
 #endif                         /* __OCP_H__ */
 #endif                         /* __KERNEL__ */
index da5ad07..5d4ad8a 100644 (file)
@@ -45,6 +45,7 @@
 
 /* Memory devices 0x0090 - 0x009F */
 #define OCP_FUNC_MAL           0x0090
+#define OCP_FUNC_DMA           0x0091
 
 /* Display 0x00A0 - 0x00AF */
 
@@ -62,7 +63,7 @@
 
 /* Network 0x0200 - 0x02FF */
 #define OCP_FUNC_EMAC          0x0200
-#define OCP_FUNC_ENET          0x0201  /* TSEC & FEC */
+#define OCP_FUNC_GFAR          0x0201  /* TSEC & FEC */
 
 /* Bridge devices 0xE00 - 0xEFF */
 #define OCP_FUNC_OPB           0x0E00
index 976796d..5effe3d 100644 (file)
@@ -222,6 +222,43 @@ extern unsigned long ioremap_bot, ioremap_base;
 /* ERPN in a PTE never gets cleared, ignore it */
 #define _PTE_NONE_MASK 0xffffffff00000000ULL
 
+#elif defined(CONFIG_E500)
+
+/*
+   MMU Assist Register 3:
+
+   32 33 34 35 36  ... 50 51 52 53 54 55 56 57 58 59 60 61 62 63
+   RPN......................  0  0 U0 U1 U2 U3 UX SX UW SW UR SR
+
+   - PRESENT *must* be in the bottom three bits because swap cache
+     entries use the top 29 bits.
+
+   - FILE *must* be in the bottom three bits because swap cache
+     entries use the top 29 bits.
+*/
+
+/* Definitions for e500 core */
+#define _PAGE_PRESENT  0x001   /* S: PTE contains a translation */
+#define _PAGE_USER     0x002   /* S: User page (maps to UR) */
+#define _PAGE_FILE     0x002   /* S: when !present: nonlinear file mapping */
+#define _PAGE_ACCESSED 0x004   /* S: Page referenced */
+#define _PAGE_HWWRITE  0x008   /* H: Dirty & RW, set in exception */
+#define _PAGE_RW       0x010   /* S: Write permission */
+#define _PAGE_HWEXEC   0x020   /* H: UX permission */
+
+#define _PAGE_ENDIAN   0x040   /* H: E bit */
+#define _PAGE_GUARDED  0x080   /* H: G bit */
+#define _PAGE_COHERENT 0x100   /* H: M bit */
+#define _PAGE_NO_CACHE 0x200   /* H: I bit */
+#define _PAGE_WRITETHRU        0x400   /* H: W bit */
+#define _PAGE_DIRTY    0x800   /* S: Page dirty */
+
+#define _PMD_PRESENT   0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD       (~PAGE_MASK)
+
+#define NUM_TLBCAMS    (16)
+
 #elif defined(CONFIG_8xx)
 /* Definitions for 8xx embedded chips. */
 #define _PAGE_PRESENT  0x0001  /* Page is valid */
@@ -555,8 +592,12 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
                (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW);
        pte_update(ptep, 0, bits);
 }
+
 #define  ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-        __ptep_set_access_flags(__ptep, __entry, __dirty)
+       do {                                                               \
+               __ptep_set_access_flags(__ptep, __entry, __dirty);         \
+               flush_tlb_page_nohash(__vma, __address);                   \
+       } while(0)
 
 /*
  * Macro to mark a page protection value as "uncacheable".
index c8de15c..13fa8e7 100644 (file)
 #define REST_16VR(n,b,base)    REST_8VR(n,b,base); REST_8VR(n+8,b,base)
 #define REST_32VR(n,b,base)    REST_16VR(n,b,base); REST_16VR(n+16,b,base)
 
+#define SAVE_EVR(n,s,base)     evmergehi s,s,n; stw s,THREAD_EVR0+4*(n)(base)
+#define SAVE_2EVR(n,s,base)    SAVE_EVR(n,s,base); SAVE_EVR(n+1,s,base)
+#define SAVE_4EVR(n,s,base)    SAVE_2EVR(n,s,base); SAVE_2EVR(n+2,s,base)
+#define SAVE_8EVR(n,s,base)    SAVE_4EVR(n,s,base); SAVE_4EVR(n+4,s,base)
+#define SAVE_16EVR(n,s,base)   SAVE_8EVR(n,s,base); SAVE_8EVR(n+8,s,base)
+#define SAVE_32EVR(n,s,base)   SAVE_16EVR(n,s,base); SAVE_16EVR(n+16,s,base)
+
+#define REST_EVR(n,s,base)     lwz s,THREAD_EVR0+4*(n)(base); evmergelo n,s,n
+#define REST_2EVR(n,s,base)    REST_EVR(n,s,base); REST_EVR(n+1,s,base)
+#define REST_4EVR(n,s,base)    REST_2EVR(n,s,base); REST_2EVR(n+2,s,base)
+#define REST_8EVR(n,s,base)    REST_4EVR(n,s,base); REST_4EVR(n+4,s,base)
+#define REST_16EVR(n,s,base)   REST_8EVR(n,s,base); REST_8EVR(n+8,s,base)
+#define REST_32EVR(n,s,base)   REST_16EVR(n,s,base); REST_16EVR(n+16,s,base)
+
 #ifdef CONFIG_PPC601_SYNC_FIX
 #define SYNC                           \
 BEGIN_FTR_SECTION                      \
@@ -107,7 +121,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
        bdnz    0b
 #endif
 
-#if !defined(CONFIG_44x)
+#ifdef CONFIG_BOOKE
+#define tophys(rd,rs)                          \
+       addis   rd,rs,0
+
+#define tovirt(rd,rs)                          \
+       addis   rd,rs,0
+
+#else  /* CONFIG_BOOKE */
 /*
  * On APUS (Amiga PowerPC cpu upgrade board), we don't know the
  * physical base address of RAM at compile time.
@@ -125,15 +146,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
        .align  1;                              \
        .long   0b;                             \
        .previous
-#else  /* CONFIG_44x */
-
-#define tophys(rd,rs)                          \
-       mr      rd,rs
-
-#define tovirt(rd,rs)                          \
-       mr      rd,rs
-
-#endif /* CONFIG_44x */
+#endif  /* CONFIG_BOOKE */
 
 /*
  * On 64-bit cpus, we use the rfid instruction instead of rfi, but
@@ -289,6 +302,39 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #define        vr30    30
 #define        vr31    31
 
+#define        evr0    0
+#define        evr1    1
+#define        evr2    2
+#define        evr3    3
+#define        evr4    4
+#define        evr5    5
+#define        evr6    6
+#define        evr7    7
+#define        evr8    8
+#define        evr9    9
+#define        evr10   10
+#define        evr11   11
+#define        evr12   12
+#define        evr13   13
+#define        evr14   14
+#define        evr15   15
+#define        evr16   16
+#define        evr17   17
+#define        evr18   18
+#define        evr19   19
+#define        evr20   20
+#define        evr21   21
+#define        evr22   22
+#define        evr23   23
+#define        evr24   24
+#define        evr25   25
+#define        evr26   26
+#define        evr27   27
+#define        evr28   28
+#define        evr29   29
+#define        evr30   30
+#define        evr31   31
+
 /* some stab codes */
 #define N_FUN  36
 #define N_RSYM 64
index bccb6e3..a9c34bd 100644 (file)
@@ -52,7 +52,7 @@ typedef struct bd_info {
        unsigned long   bi_flashoffset; /* reserved area for startup monitor */
        unsigned long   bi_sramstart;   /* start of SRAM memory */
        unsigned long   bi_sramsize;    /* size  of SRAM memory */
-#if defined(CONFIG_8xx) || defined(CONFIG_8260)
+#if defined(CONFIG_8xx) || defined(CONFIG_8260) || defined(CONFIG_85xx)
        unsigned long   bi_immr_base;   /* base of IMMR register */
 #endif
        unsigned long   bi_bootflags;   /* boot / reboot flag (for LynxOS) */
@@ -79,7 +79,7 @@ typedef struct bd_info {
 #if defined(CONFIG_HYMOD)
        hymod_conf_t    bi_hymod_conf;  /* hymod configuration information */
 #endif
-#if defined(CONFIG_EVB64260)
+#if defined(CONFIG_EVB64260) || defined(CONFIG_85xx)
        /* the board has three onboard ethernet ports */
        unsigned char   bi_enet1addr[6];
        unsigned char   bi_enet2addr[6];
index 0439ec6..fe7a943 100644 (file)
        .globl n;\
 n:
 
+/*
+ * this is the minimum allowable io space due to the location
+ * of the io areas on prep (first one at 0x80000000) but
+ * as soon as I get around to remapping the io areas with the BATs
+ * to match the mac we can raise this. -- Cort
+ */
+#define TASK_SIZE      (CONFIG_TASK_SIZE)
+
 #ifndef __ASSEMBLY__
 #ifdef CONFIG_PPC_MULTIPLATFORM
 extern int _machine;
@@ -79,14 +87,7 @@ extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 /* Lazy FPU handling on uni-processor */
 extern struct task_struct *last_task_used_math;
 extern struct task_struct *last_task_used_altivec;
-
-/*
- * this is the minimum allowable io space due to the location
- * of the io areas on prep (first one at 0x80000000) but
- * as soon as I get around to remapping the io areas with the BATs
- * to match the mac we can raise this. -- Cort
- */
-#define TASK_SIZE      (CONFIG_TASK_SIZE)
+extern struct task_struct *last_task_used_spe;
 
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
@@ -104,7 +105,7 @@ struct thread_struct {
        void            *pgdir;         /* root of page-table tree */
        int             fpexc_mode;     /* floating-point exception mode */
        signed long     last_syscall;
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
        unsigned long   dbcr0;          /* debug control register values */
        unsigned long   dbcr1;
 #endif
@@ -119,6 +120,12 @@ struct thread_struct {
        unsigned long   vrsave;
        int             used_vr;        /* set if process has used altivec */
 #endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+       unsigned long   evr[32];        /* upper 32-bits of SPE regs */
+       u64             acc;            /* Accumulator */
+       unsigned long   spefscr;        /* SPE & eFP status */
+       int             used_spe;       /* set if process has used spe */
+#endif /* CONFIG_SPE */
 };
 
 #define ARCH_MIN_TASKALIGN 16
index f13233e..2576a7f 100644 (file)
@@ -131,4 +131,9 @@ do {                                                                              \
 #define PTRACE_GETVRREGS       18
 #define PTRACE_SETVRREGS       19
 
+/* Get/set all the upper 32-bits of the SPE registers, accumulator, and
+ * spefscr, in one go */
+#define PTRACE_GETEVRREGS      20
+#define PTRACE_SETEVRREGS      21
+
 #endif
index e1defae..f02ec3c 100644 (file)
 #define SPRN_SPRG7     0x117   /* Special Purpose Register General 7 */
 #define SPRN_SRR0      0x01A   /* Save/Restore Register 0 */
 #define SPRN_SRR1      0x01B   /* Save/Restore Register 1 */
+#ifndef SPRN_SVR
+#define SPRN_SVR       0x11E   /* System Version Register */
+#endif
 #define SPRN_THRM1     0x3FC           /* Thermal Management Register 1 */
 /* these bits were defined in inverted endian sense originally, ugh, confusing */
 #define THRM1_TIN      (1 << 31)
 #define SRR1   SPRN_SRR1       /* Save and Restore Register 1 */
 #define SRR2   SPRN_SRR2       /* Save and Restore Register 2 */
 #define SRR3   SPRN_SRR3       /* Save and Restore Register 3 */
+#define SVR    SPRN_SVR        /* System Version Register */
 #define ICTC   SPRN_ICTC       /* Instruction Cache Throttling Control Reg */
 #define THRM1  SPRN_THRM1      /* Thermal Management Register 1 */
 #define THRM2  SPRN_THRM2      /* Thermal Management Register 2 */
 #define PVR_7400       0x000C0000
 #define PVR_7410       0x800C0000
 #define PVR_7450       0x80000000
+#define PVR_8540       0x80200000
+#define PVR_8560       0x80200000
 /*
  * For the 8xx processors, all of them report the same PVR family for
  * the PowerPC core. The various versions of these processors must be
 #define PVR_8245       0x80811014
 #define PVR_8260       PVR_8240
 
+/* System Version Numbers */
+#define SVR_8540       0x80300000
+#define SVR_8541E      0x807A0000
+#define SVR_8555E      0x80790000
+#define SVR_8560       0x80700000
+
 /* Segment Registers */
 #define SR0    0
 #define SR1    1
index 2267f08..474abb8 100644 (file)
 
 #ifndef __ASSEMBLY__
 /* Device Control Registers */
-#define mfdcr(rn) mfdcr_or_dflt(rn, 0)
-#define mfdcr_or_dflt(rn,default_rval)                                 \
-       ({unsigned int rval;                                            \
-       if (rn == 0)                                                    \
-               rval = default_rval;                                    \
-       else                                                            \
-               asm volatile("mfdcr %0," __stringify(rn) : "=r" (rval)); \
+void __mtdcr(int reg, unsigned int val);
+unsigned int __mfdcr(int reg);
+#define mfdcr(rn)                                              \
+       ({unsigned int rval;                                    \
+       if (__builtin_constant_p(rn))                           \
+               asm volatile("mfdcr %0," __stringify(rn)        \
+                             : "=r" (rval));                   \
+       else                                                    \
+               rval = __mfdcr(rn);                             \
        rval;})
 
-#define mtdcr(rn, v)                                                   \
-do {                                                                   \
-       if (rn != 0)                                                    \
-               asm volatile("mtdcr " __stringify(rn) ",%0" : : "r" (v)); \
+#define mtdcr(rn, v)                                           \
+do {                                                           \
+       if (__builtin_constant_p(rn))                           \
+               asm volatile("mtdcr " __stringify(rn) ",%0"     \
+                             : : "r" (v));                     \
+       else                                                    \
+               __mtdcr(rn, v);                                 \
 } while (0)
 
 /* R/W of indirect DCRs make use of standard naming conventions for DCRs */
@@ -38,13 +43,23 @@ do {                                                \
        mtdcr(base ## _CFGADDR, base ## _ ## reg);      \
        mtdcr(base ## _CFGDATA, data);          \
 } while (0)
+
+/* Performance Monitor Registers */
+#define mfpmr(rn)      ({unsigned int rval; \
+                       asm volatile("mfpmr %0," __stringify(rn) \
+                                    : "=r" (rval)); rval;})
+#define mtpmr(rn, v)   asm volatile("mtpmr " __stringify(rn) ",%0" : : "r" (v))
 #endif /* __ASSEMBLY__ */
 
 
 /* Machine State Register (MSR) Fields */
+#define MSR_UCLE       (1<<26) /* User-mode cache lock enable */
+#define MSR_SPE                (1<<25) /* Enable SPE */
 #define MSR_DWE                (1<<10) /* Debug Wait Enable */
+#define MSR_UBLE       (1<<10) /* BTB lock enable (e500) */
 #define MSR_IS         MSR_IR  /* Instruction Space */
 #define MSR_DS         MSR_DR  /* Data Space */
+#define MSR_PMM                (1<<2)  /* Performance monitor mark bit */
 
 /* Default MSR for kernel mode. */
 #if defined (CONFIG_40x)
@@ -86,20 +101,28 @@ do {                                               \
 #define SPRN_IVOR13    0x19D   /* Interrupt Vector Offset Register 13 */
 #define SPRN_IVOR14    0x19E   /* Interrupt Vector Offset Register 14 */
 #define SPRN_IVOR15    0x19F   /* Interrupt Vector Offset Register 15 */
+#define SPRN_SPEFSCR   0x200   /* SPE & Embedded FP Status & Control */
+#define SPRN_BBEAR     0x201   /* Branch Buffer Entry Address Register */
+#define SPRN_BBTAR     0x202   /* Branch Buffer Target Address Register */
+#define SPRN_IVOR32    0x210   /* Interrupt Vector Offset Register 32 */
+#define SPRN_IVOR33    0x211   /* Interrupt Vector Offset Register 33 */
+#define SPRN_IVOR34    0x212   /* Interrupt Vector Offset Register 34 */
+#define SPRN_IVOR35    0x213   /* Interrupt Vector Offset Register 35 */
 #define SPRN_MCSRR0    0x23A   /* Machine Check Save and Restore Register 0 */
 #define SPRN_MCSRR1    0x23B   /* Machine Check Save and Restore Register 1 */
 #define SPRN_MCSR      0x23C   /* Machine Check Status Register */
-#ifdef CONFIG_440A
-#define  MCSR_MCS      0x80000000 /* Machine Check Summary */
-#define  MCSR_IB       0x40000000 /* Instruction PLB Error */
-#define  MCSR_DRB      0x20000000 /* Data Read PLB Error */
-#define  MCSR_DWB      0x10000000 /* Data Write PLB Error */
-#define  MCSR_TLBP     0x08000000 /* TLB Parity Error */
-#define  MCSR_ICP      0x04000000 /* I-Cache Parity Error */
-#define  MCSR_DCSP     0x02000000 /* D-Cache Search Parity Error */
-#define  MCSR_DCFP     0x01000000 /* D-Cache Flush Parity Error */
-#define  MCSR_IMPE     0x00800000 /* Imprecise Machine Check Exception */
-#endif
+#define SPRN_MCAR      0x23D   /* Machine Check Address Register */
+#define SPRN_MAS0      0x270   /* MMU Assist Register 0 */
+#define SPRN_MAS1      0x271   /* MMU Assist Register 1 */
+#define SPRN_MAS2      0x272   /* MMU Assist Register 2 */
+#define SPRN_MAS3      0x273   /* MMU Assist Register 3 */
+#define SPRN_MAS4      0x274   /* MMU Assist Register 4 */
+#define SPRN_MAS5      0x275   /* MMU Assist Register 5 */
+#define SPRN_MAS6      0x276   /* MMU Assist Register 6 */
+#define SPRN_PID1      0x279   /* Process ID Register 1 */
+#define SPRN_PID2      0x27A   /* Process ID Register 2 */
+#define SPRN_TLB0CFG   0x2B0   /* TLB 0 Config Register */
+#define SPRN_TLB1CFG   0x2B1   /* TLB 1 Config Register */
 #define SPRN_ZPR       0x3B0   /* Zone Protection Register (40x) */
 #define SPRN_MMUCR     0x3B2   /* MMU Control Register */
 #define SPRN_CCR0      0x3B3   /* Core Configuration Register */
@@ -110,9 +133,12 @@ do {                                               \
 #define SPRN_DCMP      0x3D1   /* Data TLB Compare Register */
 #define SPRN_ICDBDR    0x3D3   /* Instruction Cache Debug Data Register */
 #define SPRN_EVPR      0x3D6   /* Exception Vector Prefix Register */
+#define SPRN_L1CSR0    0x3F2   /* L1 Cache Control and Status Register 0 */
+#define SPRN_L1CSR1    0x3F3   /* L1 Cache Control and Status Register 1 */
 #define SPRN_PIT       0x3DB   /* Programmable Interval Timer */
 #define SPRN_DCCR      0x3FA   /* Data Cache Cacheability Register */
 #define SPRN_ICCR      0x3FB   /* Instruction Cache Cacheability Register */
+#define SPRN_SVR       0x3FF   /* System Version Register */
 
 /*
  * SPRs which have conflicting definitions on true Book E versus classic,
@@ -120,6 +146,7 @@ do {                                                \
  */
 #ifdef CONFIG_BOOKE
 #define SPRN_PID       0x030   /* Process ID */
+#define SPRN_PID0      SPRN_PID/* Process ID Register 0 */
 #define SPRN_CSRR0     0x03A   /* Critical Save and Restore Register 0 */
 #define SPRN_CSRR1     0x03B   /* Critical Save and Restore Register 1 */
 #define SPRN_DEAR      0x03D   /* Data Error Address Register */
@@ -152,6 +179,34 @@ do {                                               \
 #define SPRN_CSRR1     SPRN_SRR3 /* Critical Save and Restore Register 1 */
 #endif
 
+/* Bit definitions for the MCSR. */
+#ifdef CONFIG_440A
+#define MCSR_MCS       0x80000000 /* Machine Check Summary */
+#define MCSR_IB                0x40000000 /* Instruction PLB Error */
+#define MCSR_DRB       0x20000000 /* Data Read PLB Error */
+#define MCSR_DWB       0x10000000 /* Data Write PLB Error */
+#define MCSR_TLBP      0x08000000 /* TLB Parity Error */
+#define MCSR_ICP       0x04000000 /* I-Cache Parity Error */
+#define MCSR_DCSP      0x02000000 /* D-Cache Search Parity Error */
+#define MCSR_DCFP      0x01000000 /* D-Cache Flush Parity Error */
+#define MCSR_IMPE      0x00800000 /* Imprecise Machine Check Exception */
+#endif
+#ifdef CONFIG_E500
+#define MCSR_MCP       0x80000000UL /* Machine Check Input Pin */
+#define MCSR_ICPERR    0x40000000UL /* I-Cache Parity Error */
+#define MCSR_DCP_PERR  0x20000000UL /* D-Cache Push Parity Error */
+#define MCSR_DCPERR    0x10000000UL /* D-Cache Parity Error */
+#define MCSR_GL_CI     0x00010000UL /* Guarded Load or Cache-Inhibited stwcx. */
+#define MCSR_BUS_IAERR         0x00000080UL /* Instruction Address Error */
+#define MCSR_BUS_RAERR         0x00000040UL /* Read Address Error */
+#define MCSR_BUS_WAERR         0x00000020UL /* Write Address Error */
+#define MCSR_BUS_IBERR         0x00000010UL /* Instruction Data Error */
+#define MCSR_BUS_RBERR         0x00000008UL /* Read Data Bus Error */
+#define MCSR_BUS_WBERR         0x00000004UL /* Write Data Bus Error */
+#define MCSR_BUS_IPERR         0x00000002UL /* Instruction parity Error */
+#define MCSR_BUS_RPERR         0x00000001UL /* Read parity Error */
+#endif
+
 /* Bit definitions for the DBSR. */
 /*
  * DBSR bits which have conflicting definitions on true Book E versus IBM 40x.
@@ -160,11 +215,27 @@ do {                                              \
 #define DBSR_IC                0x08000000      /* Instruction Completion */
 #define DBSR_BT                0x04000000      /* Branch Taken */
 #define DBSR_TIE       0x01000000      /* Trap Instruction Event */
+#define DBSR_IAC1      0x00800000      /* Instr Address Compare 1 Event */
+#define DBSR_IAC2      0x00400000      /* Instr Address Compare 2 Event */
+#define DBSR_IAC3      0x00200000      /* Instr Address Compare 3 Event */
+#define DBSR_IAC4      0x00100000      /* Instr Address Compare 4 Event */
+#define DBSR_DAC1R     0x00080000      /* Data Addr Compare 1 Read Event */
+#define DBSR_DAC1W     0x00040000      /* Data Addr Compare 1 Write Event */
+#define DBSR_DAC2R     0x00020000      /* Data Addr Compare 2 Read Event */
+#define DBSR_DAC2W     0x00010000      /* Data Addr Compare 2 Write Event */
 #endif
 #ifdef CONFIG_40x
 #define DBSR_IC                0x80000000      /* Instruction Completion */
 #define DBSR_BT                0x40000000      /* Branch taken */
 #define DBSR_TIE       0x10000000      /* Trap Instruction debug Event */
+#define DBSR_IAC1      0x00800000      /* Instruction Address Compare 1 Event */
+#define DBSR_IAC2      0x00400000      /* Instruction Address Compare 2 Event */
+#define DBSR_IAC3      0x00200000      /* Instruction Address Compare 3 Event */
+#define DBSR_IAC4      0x00100000      /* Instruction Address Compare 4 Event */
+#define DBSR_DAC1R     0x00080000      /* Data Address Compare 1 Read Event */
+#define DBSR_DAC1W     0x00040000      /* Data Address Compare 1 Write Event */
+#define DBSR_DAC2R     0x00020000      /* Data Address Compare 2 Read Event */
+#define DBSR_DAC2W     0x00010000      /* Data Address Compare 2 Write Event */
 #endif
 
 /* Bit definitions related to the ESR. */
@@ -179,6 +250,9 @@ do {                                                \
 #define ESR_DST                0x00800000      /* Storage Exception - Data miss */
 #define ESR_DIZ                0x00400000      /* Storage Exception - Zone fault */
 #define ESR_ST         0x00800000      /* Store Operation */
+#define ESR_DLK                0x00200000      /* Data Cache Locking */
+#define ESR_ILK                0x00100000      /* Instr. Cache Locking */
+#define ESR_BO         0x00020000      /* Byte Ordering */
 
 /* Bit definitions related to the DBCR0. */
 #define DBCR0_EDM      0x80000000      /* External Debug Mode */
@@ -253,10 +327,49 @@ do {                                              \
 #define ICCR_NOCACHE   0               /* Noncacheable */
 #define ICCR_CACHE     1               /* Cacheable */
 
+/* Bit definitions for L1CSR0. */
+#define L1CSR0_DCFI    0x00000002      /* Data Cache Flash Invalidate */
+#define L1CSR0_DCE     0x00000001      /* Data Cache Enable */
+
+/* Bit definitions for L1CSR0. */
+#define L1CSR1_ICLFR   0x00000100      /* Instr Cache Lock Bits Flash Reset */
+#define L1CSR1_ICFI    0x00000002      /* Instr Cache Flash Invalidate */
+#define L1CSR1_ICE     0x00000001      /* Instr Cache Enable */
+
 /* Bit definitions for SGR. */
 #define SGR_NORMAL     0               /* Speculative fetching allowed. */
 #define SGR_GUARDED    1               /* Speculative fetching disallowed. */
 
+/* Bit definitions for SPEFSCR. */
+#define SPEFSCR_SOVH   0x80000000      /* Summary integer overflow high */
+#define SPEFSCR_OVH    0x40000000      /* Integer overflow high */
+#define SPEFSCR_FGH    0x20000000      /* Embedded FP guard bit high */
+#define SPEFSCR_FXH    0x10000000      /* Embedded FP sticky bit high */
+#define SPEFSCR_FINVH  0x08000000      /* Embedded FP invalid operation high */
+#define SPEFSCR_FDBZH  0x04000000      /* Embedded FP div by zero high */
+#define SPEFSCR_FUNFH  0x02000000      /* Embedded FP underflow high */
+#define SPEFSCR_FOVFH  0x01000000      /* Embedded FP overflow high */
+#define SPEFSCR_FINXS  0x00200000      /* Embedded FP inexact sticky */
+#define SPEFSCR_FINVS  0x00100000      /* Embedded FP invalid op. sticky */
+#define SPEFSCR_FDBZS  0x00080000      /* Embedded FP div by zero sticky */
+#define SPEFSCR_FUNFS  0x00040000      /* Embedded FP underflow sticky */
+#define SPEFSCR_FOVFS  0x00020000      /* Embedded FP overflow sticky */
+#define SPEFSCR_MODE   0x00010000      /* Embedded FP mode */
+#define SPEFSCR_SOV    0x00008000      /* Integer summary overflow */
+#define SPEFSCR_OV     0x00004000      /* Integer overflow */
+#define SPEFSCR_FG     0x00002000      /* Embedded FP guard bit */
+#define SPEFSCR_FX     0x00001000      /* Embedded FP sticky bit */
+#define SPEFSCR_FINV   0x00000800      /* Embedded FP invalid operation */
+#define SPEFSCR_FDBZ   0x00000400      /* Embedded FP div by zero */
+#define SPEFSCR_FUNF   0x00000200      /* Embedded FP underflow */
+#define SPEFSCR_FOVF   0x00000100      /* Embedded FP overflow */
+#define SPEFSCR_FINXE  0x00000040      /* Embedded FP inexact enable */
+#define SPEFSCR_FINVE  0x00000020      /* Embedded FP invalid op. enable */
+#define SPEFSCR_FDBZE  0x00000010      /* Embedded FP div by zero enable */
+#define SPEFSCR_FUNFE  0x00000008      /* Embedded FP underflow enable */
+#define SPEFSCR_FOVFE  0x00000004      /* Embedded FP overflow enable */
+#define SPEFSCR_FRMC   0x00000003      /* Embedded FP rounding mode control */
+
 /* Short-hand for various SPRs. */
 #ifdef CONFIG_BOOKE
 #define CSRR0  SPRN_CSRR0      /* Critical Save and Restore Register 0 */
index 475f309..3d29914 100644 (file)
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit(?) */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 #ifdef __KERNEL__
 
        { RLIM_INFINITY, RLIM_INFINITY },               \
        {             0,             0 },               \
        {      INR_OPEN,     INR_OPEN  },               \
-       { PAGE_SIZE,     PAGE_SIZE     },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { MAX_SIGPENDING, MAX_SIGPENDING },             \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX },                 \
 }
 
 #endif /* __KERNEL__ */
index a9422c2..310206e 100644 (file)
@@ -30,6 +30,8 @@
 #include <platforms/spruce.h>
 #elif defined(CONFIG_4xx)
 #include <asm/ibm4xx.h>
+#elif defined(CONFIG_85xx)
+#include <asm/mpc85xx.h>
 #else
 
 /*
index 3ceaf16..d91ba52 100644 (file)
@@ -65,7 +65,6 @@ static inline void _raw_spin_unlock(spinlock_t *lock)
 extern void _raw_spin_lock(spinlock_t *lock);
 extern void _raw_spin_unlock(spinlock_t *lock);
 extern int _raw_spin_trylock(spinlock_t *lock);
-extern unsigned long __spin_trylock(volatile unsigned long *lock);
 
 #endif
 
@@ -136,6 +135,26 @@ static __inline__ void _raw_read_unlock(rwlock_t *rw)
        : "cr0", "memory");
 }
 
+static __inline__ int _raw_write_trylock(rwlock_t *rw)
+{
+       unsigned int tmp;
+
+       __asm__ __volatile__(
+"2:    lwarx   %0,0,%1         # write_trylock\n\
+       cmpwi   0,%0,0\n\
+       bne-    1f\n"
+       PPC405_ERR77(0,%1)
+"      stwcx.  %2,0,%1\n\
+       bne-    2b\n\
+       isync\n\
+1:"
+       : "=&r"(tmp)
+       : "r"(&rw->lock), "r"(-1)
+       : "cr0", "memory");
+
+       return tmp == 0;
+}
+
 static __inline__ void _raw_write_lock(rwlock_t *rw)
 {
        unsigned int tmp;
@@ -169,6 +188,7 @@ extern void _raw_read_lock(rwlock_t *rw);
 extern void _raw_read_unlock(rwlock_t *rw);
 extern void _raw_write_lock(rwlock_t *rw);
 extern void _raw_write_unlock(rwlock_t *rw);
+extern int _raw_write_trylock(rwlock_t *rw);
 
 #endif
 
index e8c8e88..fdccd73 100644 (file)
@@ -76,6 +76,8 @@ extern void giveup_fpu(struct task_struct *);
 extern void enable_kernel_fp(void);
 extern void giveup_altivec(struct task_struct *);
 extern void load_up_altivec(struct task_struct *);
+extern void giveup_spe(struct task_struct *);
+extern void load_up_spe(struct task_struct *);
 extern int fix_alignment(struct pt_regs *);
 extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
 extern void cvt_df(double *from, float *to, unsigned long *fpscr);
index 7d755b2..9850f53 100644 (file)
@@ -29,6 +29,31 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
 static inline void flush_tlb_page(struct vm_area_struct *vma,
                                unsigned long vmaddr)
        { _tlbie(vmaddr); }
+static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
+                                        unsigned long vmaddr)
+       { _tlbie(vmaddr); }
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+                               unsigned long start, unsigned long end)
+       { __tlbia(); }
+static inline void flush_tlb_kernel_range(unsigned long start,
+                               unsigned long end)
+       { __tlbia(); }
+
+#elif defined(CONFIG_FSL_BOOKE)
+
+/* TODO: determine if flush_tlb_range & flush_tlb_kernel_range
+ * are best implemented as tlbia vs specific tlbie's */
+
+#define __tlbia()      _tlbia()
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+       { __tlbia(); }
+static inline void flush_tlb_page(struct vm_area_struct *vma,
+                               unsigned long vmaddr)
+       { _tlbie(vmaddr); }
+static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
+                                        unsigned long vmaddr)
+       { _tlbie(vmaddr); }
 static inline void flush_tlb_range(struct vm_area_struct *vma,
                                unsigned long start, unsigned long end)
        { __tlbia(); }
@@ -44,6 +69,9 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
 static inline void flush_tlb_page(struct vm_area_struct *vma,
                                unsigned long vmaddr)
        { _tlbie(vmaddr); }
+static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
+                                        unsigned long vmaddr)
+       { _tlbie(vmaddr); }
 static inline void flush_tlb_range(struct mm_struct *mm,
                                unsigned long start, unsigned long end)
        { __tlbia(); }
@@ -56,6 +84,7 @@ struct mm_struct;
 struct vm_area_struct;
 extern void flush_tlb_mm(struct mm_struct *mm);
 extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
+extern void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr);
 extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                            unsigned long end);
 extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
index dd6e92e..57fb02c 100644 (file)
@@ -402,6 +402,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)       \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 
 /*
  * Forking from kernel space will result in the child getting a new,
index 429487d..24ea6e1 100644 (file)
@@ -8,13 +8,11 @@
  * 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.
- *
- * Use r13 for current since the ppc64 ABI reserves it - Anton
  */
 
 #include <asm/thread_info.h>
 
-#define get_current()   ((struct task_struct *)(get_paca()->xCurrent))
+#define get_current()   (get_paca()->xCurrent)
 #define current         get_current()
 
 #endif /* !(_PPC64_CURRENT_H) */
index 9744b7c..e1a2fec 100644 (file)
@@ -82,9 +82,11 @@ typedef struct {
 
 #ifdef CONFIG_PREEMPT
 # define in_atomic()   ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
+# define preemptible() (preempt_count() == 0 && !irqs_disabled())
 # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
 #else
 # define in_atomic()   (preempt_count() != 0)
+# define preemptible() 0
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
 #define irq_exit()                                                     \
index ed81398..f6262ba 100644 (file)
@@ -307,7 +307,7 @@ static inline void out_le32(volatile unsigned *addr, int val)
 
 static inline void out_be32(volatile unsigned *addr, int val)
 {
-       __asm__ __volatile__("stw%U0%X0 %1,%0; eieio"
+       __asm__ __volatile__("stw%U0%X0 %1,%0; sync"
                             : "=m" (*addr) : "r" (val));
 }
 
@@ -356,9 +356,9 @@ static inline void out_le64(volatile unsigned long *addr, unsigned long val)
                             : "=&r" (tmp) , "=&r" (val) : "1" (val) , "b" (addr) , "m" (*addr));
 }
 
-static inline void out_be64(volatile unsigned long *addr, int val)
+static inline void out_be64(volatile unsigned long *addr, unsigned long val)
 {
-       __asm__ __volatile__("std %1,0(%0); sync" : "=m" (*addr) : "r" (val));
+       __asm__ __volatile__("std%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val));
 }
 
 #ifndef CONFIG_PPC_ISERIES 
index 9b60289..218ab71 100644 (file)
@@ -37,6 +37,8 @@ extern struct paca_struct paca[];
 register struct paca_struct *local_paca asm("r13");
 #define get_paca()     local_paca
 
+struct task_struct;
+
 /*============================================================================
  * Name_______:        paca
  *
@@ -59,7 +61,7 @@ struct paca_struct {
  */
        struct ItLpPaca *xLpPacaPtr;    /* Pointer to LpPaca for PLIC           0x00 */
        struct ItLpRegSave *xLpRegSavePtr; /* Pointer to LpRegSave for PLIC     0x08 */
-       u64 xCurrent;                   /* Pointer to current                   0x10 */
+       struct task_struct *xCurrent;   /* Pointer to current                   0x10 */
        /* Note: the spinlock functions in arch/ppc64/lib/locks.c load lock_token and
           xPacaIndex with a single lwz instruction, using the constant offset 24.
           If you move either field, fix the spinlocks and rwlocks. */
@@ -134,23 +136,21 @@ struct paca_struct {
        u8  rsvd6[0x500 - 0x8];
 
 /*=====================================================================================
- * CACHE_LINE_31 0x0F00 - 0x0F7F Exception stack
- *=====================================================================================
- */
-       u8 exception_stack[N_EXC_STACK*EXC_FRAME_SIZE];
-
-/*=====================================================================================
- * CACHE_LINE_32 0x0F80 - 0x0FFF Reserved
+ * CACHE_LINE_31-32 0x0F00 - 0x0FFF Exception register save areas
  *=====================================================================================
  */
-       u8 rsvd7[0x80];                  /* Give the stack some rope ... */
+       u64 exgen[8];           /* used for most interrupts/exceptions */
+       u64 exmc[8];            /* used for machine checks */
+       u64 exslb[8];           /* used for SLB/segment table misses
+                                * on the linear mapping */
+       u64 exdsi[8];           /* used for linear mapping hash table misses */
 
 /*=====================================================================================
- * Page 2 Reserved for guard page.  Also used as a stack early in SMP boots before
- *        relocation is enabled.
+ * Page 2 used as a stack when we detect a bad kernel stack pointer,
+ * and early in SMP boots before relocation is enabled.
  *=====================================================================================
  */
-       u8 guard[0x1000];               /* ... and then hang 'em         */ 
+       u8 guard[0x1000];
 };
 
 #endif /* _PPC64_PACA_H */
index 29b5727..cddaa2f 100644 (file)
@@ -106,33 +106,7 @@ extern void pte_free_submit(struct pte_freelist_batch *batch);
 
 DECLARE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
 
-static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage)
-{
-       /* This is safe as we are holding page_table_lock */
-        cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id());
-       struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
-
-       if (atomic_read(&tlb->mm->mm_users) < 2 ||
-           cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) {
-               pte_free(ptepage);
-               return;
-       }
-
-       if (*batchp == NULL) {
-               *batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC);
-               if (*batchp == NULL) {
-                       pte_free_now(ptepage);
-                       return;
-               }
-               (*batchp)->index = 0;
-       }
-       (*batchp)->pages[(*batchp)->index++] = ptepage;
-       if ((*batchp)->index == PTE_FREELIST_SIZE) {
-               pte_free_submit(*batchp);
-               *batchp = NULL;
-       }
-}
-
+void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage);
 #define __pmd_free_tlb(tlb, pmd)       __pte_free_tlb(tlb, virt_to_page(pmd))
 
 #define check_pgt_cache()      do { } while (0)
index befa845..b1e7f6d 100644 (file)
@@ -428,7 +428,10 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
        :"cc");
 }
 #define  ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-        __ptep_set_access_flags(__ptep, __entry, __dirty)
+       do {                                                               \
+               __ptep_set_access_flags(__ptep, __entry, __dirty);         \
+               flush_tlb_page_nohash(__vma, __address);                   \
+       } while(0)
 
 /*
  * Macro to mark a page protection value as "uncacheable".
index 6ac08bb..9031d8a 100644 (file)
@@ -28,6 +28,9 @@
 #define REST_8GPRS(n, base)    REST_4GPRS(n, base); REST_4GPRS(n+4, base)
 #define REST_10GPRS(n, base)   REST_8GPRS(n, base); REST_2GPRS(n+8, base)
 
+#define SAVE_NVGPRS(base)      SAVE_8GPRS(14, base); SAVE_10GPRS(22, base)
+#define REST_NVGPRS(base)      REST_8GPRS(14, base); REST_10GPRS(22, base)
+
 #define SAVE_FPR(n, base)      stfd    n,THREAD_FPR0+8*(n)(base)
 #define SAVE_2FPRS(n, base)    SAVE_FPR(n, base); SAVE_FPR(n+1, base)
 #define SAVE_4FPRS(n, base)    SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
 #define REST_16VRS(n,b,base)   REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
 #define REST_32VRS(n,b,base)   REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
 
-#define CHECKANYINT(ra,rb)                     \
-       mfspr   rb,SPRG3;               /* Get Paca address */\
-       ld      ra,PACALPPACA+LPPACAANYINT(rb); /* Get pending interrupt flags */\
-       cmpldi  0,ra,0;
-
 /* Macros to adjust thread priority for Iseries hardware multithreading */
 #define HMT_LOW                or 1,1,1
 #define HMT_MEDIUM     or 2,2,2
index 4280809..265ad15 100644 (file)
@@ -543,8 +543,7 @@ struct thread_struct {
        double          fpr[32];        /* Complete floating point set */
        unsigned long   fpscr;          /* Floating point status (plus pad) */
        unsigned long   fpexc_mode;     /* Floating-point exception mode */
-       unsigned long   saved_msr;      /* Save MSR across signal handlers */
-       unsigned long   saved_softe;    /* Ditto for Soft Enable/Disable */
+       unsigned long   pad[3];         /* was saved_msr, saved_softe */
 #ifdef CONFIG_ALTIVEC
        /* Complete AltiVec register set */
        vector128       vr[32] __attribute((aligned(16)));
index c4e809d..2ec5d7b 100644 (file)
@@ -71,6 +71,18 @@ struct pt_regs32 {
 #define instruction_pointer(regs) ((regs)->nip)
 #define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1)
 
+#define force_successful_syscall_return()   \
+               (current_thread_info()->syscall_noerror = 1)
+
+/*
+ * We use the least-significant bit of the trap field to indicate
+ * whether we have saved the full set of registers, or only a
+ * partial set.  A 1 there means the partial set.
+ */
+#define FULL_REGS(regs)                (((regs)->trap & 1) == 0)
+#define TRAP(regs)             ((regs)->trap & ~0xF)
+#define CHECK_FULL_REGS(regs)  BUG_ON(regs->trap & 1)
+
 /*
  * Offsets used by 'ptrace' system call interface.
  */
index 691a3fa..c54e9d6 100644 (file)
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit(?) */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 #ifdef __KERNEL__
 
        { RLIM_INFINITY, RLIM_INFINITY },               \
        {             0,             0 },               \
        {      INR_OPEN,     INR_OPEN  },               \
-       { PAGE_SIZE,     PAGE_SIZE     },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { MAX_SIGPENDING, MAX_SIGPENDING },             \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX },                 \
 }
 
 #endif /* __KERNEL__ */
index bb1ebb2..8d8a6f8 100644 (file)
@@ -111,6 +111,8 @@ extern void flush_instruction_cache(void);
 extern int _get_PVR(void);
 extern void giveup_fpu(struct task_struct *);
 extern void disable_kernel_fp(void);
+extern void flush_fp_to_thread(struct task_struct *);
+extern void flush_altivec_to_thread(struct task_struct *);
 extern void enable_kernel_fp(void);
 extern void giveup_altivec(struct task_struct *);
 extern void disable_kernel_altivec(void);
@@ -277,5 +279,14 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
                                    (unsigned long)_n_, sizeof(*(ptr))); \
   })
 
+/*
+ * We handle most unaligned accesses in hardware. On the other hand 
+ * unaligned DMA can be very expensive on some ppc64 IO chips (it does
+ * powers of 2 writes until it reaches sufficient alignment).
+ *
+ * Based on this we disable the IP header alignment in network drivers.
+ */
+#define NET_IP_ALIGN   0
+
 #endif /* __KERNEL__ */
 #endif
index a467497..04aec3b 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef __ASSEMBLY__
 #include <linux/config.h>
 #include <asm/processor.h>
+#include <asm/page.h>
 #include <linux/stringify.h>
 
 /*
@@ -23,8 +24,10 @@ struct thread_info {
        struct exec_domain *exec_domain;        /* execution domain */
        unsigned long   flags;                  /* low level flags */
        int             cpu;                    /* cpu we're on */
-       int             preempt_count;          /* not used at present */
+       int             preempt_count;
        struct restart_block restart_block;
+       /* set by force_successful_syscall_return */
+       unsigned char   syscall_noerror;
 };
 
 /*
@@ -73,7 +76,7 @@ struct thread_info {
 static inline struct thread_info *current_thread_info(void)
 {
        struct thread_info *ti;
-       __asm__("clrrdi %0,1,14" : "=r"(ti));
+       __asm__("clrrdi %0,1,%1" : "=r"(ti) : "i" (THREAD_SHIFT));
        return ti;
 }
 
index 92aeb57..183bdfb 100644 (file)
@@ -6,6 +6,7 @@
  *
  *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
  *  - flush_tlb_page(vma, vmaddr) flushes one page
+ *  - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
  *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
@@ -39,6 +40,7 @@ static inline void flush_tlb_pending(void)
 
 #define flush_tlb_mm(mm)                       flush_tlb_pending()
 #define flush_tlb_page(vma, addr)              flush_tlb_pending()
+#define flush_tlb_page_nohash(vma, addr)               do { } while (0)
 #define flush_tlb_range(vma, start, end) \
                do { (void)(start); flush_tlb_pending(); } while (0)
 #define flush_tlb_kernel_range(start, end)     flush_tlb_pending()
index 7f38d35..20c4b3a 100644 (file)
@@ -439,6 +439,7 @@ static inline _syscall3(int, execve, __const__ char *, file, char **, argv,
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 
 unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot,
                       unsigned long flags, unsigned long fd, off_t offset);
index 1ef9a27..36fc9f9 100644 (file)
@@ -43,8 +43,6 @@ struct iommu_table;
 
 int vio_register_driver(struct vio_driver *drv);
 void vio_unregister_driver(struct vio_driver *drv);
-const struct vio_device_id * vio_match_device(const struct vio_device_id *ids, 
-                                               const struct vio_dev *dev);
 
 struct vio_dev * __devinit vio_register_device(struct device_node *node_vdev);
 void __devinit vio_unregister_device(struct vio_dev *dev);
@@ -52,7 +50,6 @@ struct vio_dev *vio_find_node(struct device_node *vnode);
 
 const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length);
 int vio_get_irq(struct vio_dev *dev);
-struct iommu_table * vio_build_iommu_table(struct vio_dev *dev);
 int vio_enable_interrupts(struct vio_dev *dev);
 int vio_disable_interrupts(struct vio_dev *dev);
 
@@ -110,8 +107,6 @@ static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
  * The vio_dev structure is used to describe virtual I/O devices.
  */
 struct vio_dev {
-       struct device_node *archdata;   /* Open Firmware node */
-       void *driver_data;              /* data private to the driver */
        struct iommu_table *iommu_table;     /* vio_map_* uses this */
        uint32_t unit_address;  
        unsigned int irq;
index edce414..541b6da 100644 (file)
@@ -145,7 +145,7 @@ static __inline__ long long atomic64_inc_return(volatile atomic64_t * v)
 }
 static __inline__ long long atomic64_inc_and_test(volatile atomic64_t * v)
 {
-       return __CSG_LOOP(v, 1, "agr") != 0;
+       return __CSG_LOOP(v, 1, "agr") == 0;
 }
 static __inline__ void atomic64_dec(volatile atomic64_t * v)
 {
index 468da96..471f2af 100644 (file)
@@ -93,8 +93,8 @@ csum_partial_inline(const unsigned char * buff, int len, unsigned int sum)
  * Copy from userspace and compute checksum.  If we catch an exception
  * then zero the rest of the buffer.
  */
-static inline unsigned int 
-csum_partial_copy_from_user (const char *src, char *dst,
+static inline unsigned int
+csum_partial_copy_from_user(const char __user *src, char *dst,
                                           int len, unsigned int sum,
                                           int *err_ptr)
 {
index 81b21b8..7f8f544 100644 (file)
@@ -123,19 +123,19 @@ typedef u32               compat_sigset_word;
  */
 typedef        u32             compat_uptr_t;
 
-static inline void *compat_ptr(compat_uptr_t uptr)
+static inline void __user *compat_ptr(compat_uptr_t uptr)
 {
-       return (void *)(unsigned long)(uptr & 0x7fffffffUL);
+       return (void __user *)(unsigned long)(uptr & 0x7fffffffUL);
 }
 
-static inline void *compat_alloc_user_space(long len)
+static inline void __user *compat_alloc_user_space(long len)
 {
        unsigned long stack;
 
        stack = KSTK_ESP(current);
        if (test_thread_flag(TIF_31BIT))
                stack &= 0x7fffffffUL;
-       return (void *) (stack - len);
+       return (void __user *) (stack - len);
 }
 
 struct compat_ipc64_perm {
index c266fe9..3148d5b 100644 (file)
@@ -91,7 +91,8 @@ typedef int (debug_prolog_proc_t) (debug_info_t* id,
                                   char* out_buf);
 typedef int (debug_input_proc_t) (debug_info_t* id,
                                  struct debug_view* view,
-                                 struct file* file, const char* user_buf,
+                                 struct file* file,
+                                 const char __user *user_buf,
                                  size_t in_buf_size, loff_t* offset);
 
 int debug_dflt_header_fn(debug_info_t* id, struct debug_view* view,
@@ -234,26 +235,6 @@ int debug_unregister_view(debug_info_t* id, struct debug_view* view);
 #define PRINT_FATAL(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
 #endif                         /* DASD_DEBUG */
 
-#if DASD_DEBUG > 4
-#define INTERNAL_ERROR(x...) PRINT_FATAL ( INTERNAL_ERRMSG ( x ) )
-#elif DASD_DEBUG > 2
-#define INTERNAL_ERROR(x...) PRINT_ERR ( INTERNAL_ERRMSG ( x ) )
-#elif DASD_DEBUG > 0
-#define INTERNAL_ERROR(x...) PRINT_WARN ( INTERNAL_ERRMSG ( x ) )
-#else
-#define INTERNAL_ERROR(x...)
-#endif                         /* DASD_DEBUG */
-
-#if DASD_DEBUG > 5
-#define INTERNAL_CHECK(x...) PRINT_FATAL ( INTERNAL_CHKMSG ( x ) )
-#elif DASD_DEBUG > 3
-#define INTERNAL_CHECK(x...) PRINT_ERR ( INTERNAL_CHKMSG ( x ) )
-#elif DASD_DEBUG > 1
-#define INTERNAL_CHECK(x...) PRINT_WARN ( INTERNAL_CHKMSG ( x ) )
-#else
-#define INTERNAL_CHECK(x...)
-#endif                         /* DASD_DEBUG */
-
 #undef DEBUG_MALLOC
 #ifdef DEBUG_MALLOC
 void *b;
index ad444dc..8f72c9b 100644 (file)
@@ -218,7 +218,7 @@ idal_buffer_set_cda(struct idal_buffer *ib, struct ccw1 *ccw)
  * Copy count bytes from an idal buffer to user memory
  */
 static inline size_t
-idal_buffer_to_user(struct idal_buffer *ib, void *to, size_t count)
+idal_buffer_to_user(struct idal_buffer *ib, void __user *to, size_t count)
 {
        size_t left;
        int i;
@@ -228,7 +228,7 @@ idal_buffer_to_user(struct idal_buffer *ib, void *to, size_t count)
                left = copy_to_user(to, ib->data[i], IDA_BLOCK_SIZE);
                if (left)
                        return left + count - IDA_BLOCK_SIZE;
-               to = (void *) to + IDA_BLOCK_SIZE;
+               to = (void __user *) to + IDA_BLOCK_SIZE;
                count -= IDA_BLOCK_SIZE;
        }
        return copy_to_user(to, ib->data[i], count);
@@ -238,7 +238,7 @@ idal_buffer_to_user(struct idal_buffer *ib, void *to, size_t count)
  * Copy count bytes from user memory to an idal buffer
  */
 static inline size_t
-idal_buffer_from_user(struct idal_buffer *ib, const void *from, size_t count)
+idal_buffer_from_user(struct idal_buffer *ib, const void __user *from, size_t count)
 {
        size_t left;
        int i;
@@ -248,7 +248,7 @@ idal_buffer_from_user(struct idal_buffer *ib, const void *from, size_t count)
                left = copy_from_user(ib->data[i], from, IDA_BLOCK_SIZE);
                if (left)
                        return left + count - IDA_BLOCK_SIZE;
-               from = (void *) from + IDA_BLOCK_SIZE;
+               from = (void __user *) from + IDA_BLOCK_SIZE;
                count -= IDA_BLOCK_SIZE;
        }
        return copy_from_user(ib->data[i], from, count);
index 060060a..d6c041e 100644 (file)
@@ -15,7 +15,7 @@
  * See arch/s390/kernel/sys_s390.c for ugly details..
  */
 struct ipc_kludge {
-       struct msgbuf *msgp;
+       struct msgbuf __user *msgp;
        long msgtyp;
 };
 
index ebd93e4..05ac76f 100644 (file)
@@ -587,6 +587,9 @@ ptep_establish(struct vm_area_struct *vma,
        set_pte(ptep, entry);
 }
 
+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
+       ptep_establish(__vma, __address, __ptep, __entry)
+
 /*
  * Test and clear dirty bit in storage key.
  * We can't clear the changed bit atomically. This is a potential
@@ -651,9 +654,11 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
        __pte;                                                            \
 })
 
-#define arch_set_page_uptodate(__page)                                   \
+#define SetPageUptodate(_page) \
        do {                                                              \
-               asm volatile ("sske %0,%1" : : "d" (0),                   \
+               struct page *__page = (_page);                            \
+               if (!test_and_set_bit(PG_uptodate, &__page->flags))       \
+                       asm volatile ("sske %0,%1" : : "d" (0),           \
                              "a" (__pa((__page-mem_map) << PAGE_SHIFT)));\
        } while (0)
 
@@ -784,6 +789,7 @@ extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
 #define pgtable_cache_init()   do { } while (0)
 
 #define __HAVE_ARCH_PTEP_ESTABLISH
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
index 0b4ef95..fe6e1e3 100644 (file)
@@ -303,6 +303,7 @@ typedef struct
  */
 struct pt_regs 
 {
+       unsigned long args[1];
        psw_t psw;
        unsigned long gprs[NUM_GPRS];
        unsigned long orig_gpr2;
index 5ecbcbc..5f0f2ba 100644 (file)
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
-  
-#define RLIM_NLIMITS   11
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
+
+#define RLIM_NLIMITS   13
 
 /*
  * SuS says limits have to be unsigned.
        { RLIM_INFINITY, RLIM_INFINITY },               \
        {             0,             0 },               \
        { INR_OPEN, INR_OPEN },                         \
-       { PAGE_SIZE,     PAGE_SIZE     },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { MAX_SIGPENDING, MAX_SIGPENDING },             \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX },                 \
 }
 
 #endif /* __KERNEL__ */
index c5b19f0..ba3b351 100644 (file)
@@ -12,6 +12,7 @@
 #define COMMAND_LINE_SIZE      896
 #define RAMDISK_ORIGIN         0x800000
 #define RAMDISK_SIZE           0x800000
+#define MEMORY_CHUNKS          16      /* max 0x7fff */
 
 #ifndef __ASSEMBLY__
 
index c617ab3..bc7a847 100644 (file)
@@ -48,7 +48,7 @@ extern inline void _raw_spin_lock(spinlock_t *lp)
 {
 #ifndef __s390x__
        unsigned int reg1, reg2;
-        __asm__ __volatile("    bras  %0,1f\n"
+        __asm__ __volatile__("    bras  %0,1f\n"
                            "0:  diag  0,0,68\n"
                            "1:  slr   %1,%1\n"
                            "    cs    %1,%0,0(%3)\n"
@@ -58,7 +58,7 @@ extern inline void _raw_spin_lock(spinlock_t *lp)
                           : "cc", "memory" );
 #else /* __s390x__ */
        unsigned long reg1, reg2;
-        __asm__ __volatile("    bras  %1,1f\n"
+        __asm__ __volatile__("    bras  %1,1f\n"
                            "0:  " __DIAG44_INSN " 0,%4\n"
                            "1:  slr   %0,%0\n"
                            "    cs    %0,%1,0(%3)\n"
@@ -74,7 +74,7 @@ extern inline int _raw_spin_trylock(spinlock_t *lp)
        unsigned long reg;
        unsigned int result;
 
-       __asm__ __volatile("    basr  %1,0\n"
+       __asm__ __volatile__("    basr  %1,0\n"
                           "0:  cs    %0,%1,0(%3)"
                           : "=d" (result), "=&d" (reg), "=m" (lp->lock)
                           : "a" (&lp->lock), "m" (lp->lock), "0" (0)
@@ -86,7 +86,7 @@ extern inline void _raw_spin_unlock(spinlock_t *lp)
 {
        unsigned int old;
 
-       __asm__ __volatile("cs %0,%3,0(%4)"
+       __asm__ __volatile__("cs %0,%3,0(%4)"
                           : "=d" (old), "=m" (lp->lock)
                           : "0" (lp->lock), "d" (0), "a" (lp)
                           : "cc", "memory" );
index d8739b6..017872d 100644 (file)
 #include <linux/types.h>
 #endif
 
-#define __HAVE_ARCH_MEMCHR
-#define __HAVE_ARCH_MEMCPY
-#define __HAVE_ARCH_MEMSET
-#define __HAVE_ARCH_STRCAT
-#define __HAVE_ARCH_STRCMP
-#define __HAVE_ARCH_STRCPY
-#define __HAVE_ARCH_STRLEN
-#define __HAVE_ARCH_STRNCPY
+#define __HAVE_ARCH_BCOPY      /* arch function */
+#define __HAVE_ARCH_MEMCHR     /* inline & arch function */
+#define __HAVE_ARCH_MEMCMP     /* arch function */
+#define __HAVE_ARCH_MEMCPY     /* gcc builtin & arch function */
+#define __HAVE_ARCH_MEMSCAN    /* inline & arch function */
+#define __HAVE_ARCH_MEMSET     /* gcc builtin & arch function */
+#define __HAVE_ARCH_STRCAT     /* inline & arch function */
+#define __HAVE_ARCH_STRCMP     /* arch function */
+#define __HAVE_ARCH_STRCPY     /* inline & arch function */
+#define __HAVE_ARCH_STRLCAT    /* arch function */
+#define __HAVE_ARCH_STRLCPY    /* arch function */
+#define __HAVE_ARCH_STRLEN     /* inline & arch function */
+#define __HAVE_ARCH_STRNCAT    /* arch function */
+#define __HAVE_ARCH_STRNCPY    /* arch function */
+#define __HAVE_ARCH_STRNLEN    /* inline & arch function */
+#define __HAVE_ARCH_STRRCHR    /* arch function */
+#define __HAVE_ARCH_STRSTR     /* arch function */
+
+/* Prototypes for non-inlined arch strings functions. */
+extern int memcmp(const void *, const void *, size_t);
+extern void *memcpy(void *, const void *, size_t);
+extern void *memset(void *, int, size_t);
+extern int strcmp(const char *,const char *);
+extern size_t strlcat(char *, const char *, size_t);
+extern size_t strlcpy(char *, const char *, size_t);
+extern char *strncat(char *, const char *, size_t);
+extern char *strncpy(char *, const char *, size_t);
+extern char *strrchr(const char *, int);
+extern char *strstr(const char *, const char *);
 
 #undef __HAVE_ARCH_MEMMOVE
-#undef __HAVE_ARCH_STRNICMP
-#undef __HAVE_ARCH_STRNCAT
-#undef __HAVE_ARCH_STRNCMP
 #undef __HAVE_ARCH_STRCHR
-#undef __HAVE_ARCH_STRRCHR
-#undef __HAVE_ARCH_STRNLEN
-#undef __HAVE_ARCH_STRSPN
+#undef __HAVE_ARCH_STRNCHR
+#undef __HAVE_ARCH_STRNCMP
+#undef __HAVE_ARCH_STRNICMP
 #undef __HAVE_ARCH_STRPBRK
-#undef __HAVE_ARCH_STRTOK
-#undef __HAVE_ARCH_BCOPY
-#undef __HAVE_ARCH_MEMCMP
-#undef __HAVE_ARCH_MEMSCAN
-#undef __HAVE_ARCH_STRSTR
+#undef __HAVE_ARCH_STRSEP
+#undef __HAVE_ARCH_STRSPN
 
-extern void *memset(void *, int, size_t);
-extern void *memcpy(void *, const void *, size_t);
-extern void *memmove(void *, const void *, size_t);
-extern char *strncpy(char *, const char *, size_t);
-extern int strcmp(const char *,const char *);
+#if !defined(IN_ARCH_STRING_C)
 
-static inline void * memchr(const void * cs,int c,size_t count)
+static inline void *memchr(const void * s, int c, size_t n)
 {
-    void *ptr;
-
-    __asm__ __volatile__ (
-#ifndef __s390x__
-                          "   lr    0,%2\n"
-                          "   lr    1,%1\n"
-                          "   la    %0,0(%3,%1)\n"
-                          "0: srst  %0,1\n"
-                          "   jo    0b\n"
-                          "   brc   13,1f\n"
-                          "   slr   %0,%0\n"
-#else /* __s390x__ */
-                          "   lgr   0,%2\n"
-                          "   lgr   1,%1\n"
-                          "   la    %0,0(%3,%1)\n"
-                          "0: srst  %0,1\n"
-                          "   jo    0b\n"
-                          "   brc   13,1f\n"
-                          "   slgr  %0,%0\n"
-#endif /* __s390x__ */
-                          "1:"
-                          : "=&a" (ptr) : "a" (cs), "d" (c), "d" (count)
-                          : "cc", "0", "1" );
-    return ptr;
+       register int r0 asm("0") = (char) c;
+       const void *ret = s + n;
+
+       asm volatile ("0: srst  %0,%1\n"
+                     "   jo    0b\n"
+                     "   jl    1f\n"
+                     "   la    %0,0\n"
+                     "1:"
+                     : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" );
+       return (void *) ret;
 }
 
-static __inline__ char *strcpy(char *dest, const char *src)
+static inline void *memscan(void *s, int c, size_t n)
 {
-    char *tmp = dest;
-
-    __asm__ __volatile__ (
-#ifndef __s390x__
-                          "   sr    0,0\n"
-                          "0: mvst  %0,%1\n"
-                          "   jo    0b"
-#else /* __s390x__ */
-                          "   slgr  0,0\n"
-                          "0: mvst  %0,%1\n"
-                          "   jo    0b"
-#endif /* __s390x__ */
-                          : "+&a" (dest), "+&a" (src) :
-                          : "cc", "memory", "0" );
-    return tmp;
+       register int r0 asm("0") = (char) c;
+       const void *ret = s + n;
+
+       asm volatile ("0: srst  %0,%1\n"
+                     "   jo    0b\n"
+                     : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" );
+       return (void *) ret;
 }
 
-static __inline__ size_t strlen(const char *s)
+static inline char *strcat(char *dst, const char *src)
 {
-    size_t len;
-
-    __asm__ __volatile__ (
-#ifndef __s390x__
-                          "   sr    0,0\n"
-                          "   lr    %0,%1\n"
-                          "0: srst  0,%0\n"
-                          "   jo    0b\n"
-                          "   lr    %0,0\n"
-                          "   sr    %0,%1"
-#else /* __s390x__ */
-                          "   slgr  0,0\n"
-                          "   lgr   %0,%1\n"
-                          "0: srst  0,%0\n"
-                          "   jo    0b\n"
-                          "   lgr   %0,0\n"
-                          "   sgr   %0,%1"
-#endif /* __s390x__ */
-                          : "=&a" (len) : "a" (s) 
-                          : "cc", "0" );
-    return len;
+       register int r0 asm("0") = 0;
+       unsigned long dummy;
+       char *ret = dst;
+
+       asm volatile ("0: srst  %0,%1\n"
+                     "   jo    0b\n"
+                     "1: mvst  %0,%2\n"
+                     "   jo    1b"
+                     : "=&a" (dummy), "+a" (dst), "+a" (src)
+                     : "d" (r0), "0" (0) : "cc", "memory" );
+       return ret;
 }
 
-static __inline__ char *strcat(char *dest, const char *src)
+static inline char *strcpy(char *dst, const char *src)
 {
-    char *tmp = dest;
-
-    __asm__ __volatile__ (
-#ifndef __s390x__
-                          "   sr    0,0\n"
-                          "0: srst  0,%0\n"
-                          "   jo    0b\n"
-                          "   lr    %0,0\n"
-                          "   sr    0,0\n"
-                          "1: mvst  %0,%1\n"
-                          "   jo    1b"
-#else /* __s390x__ */
-                          "   slgr  0,0\n"
-                          "0: srst  0,%0\n"
-                          "   jo    0b\n"
-                          "   lgr   %0,0\n"
-                          "   slgr  0,0\n"
-                          "1: mvst  %0,%1\n"
-                          "   jo    1b"
-#endif /* __s390x__ */
-                          : "+&a" (dest), "+&a" (src) :
-                          : "cc", "memory", "0" );
-    return tmp;
+       register int r0 asm("0") = 0;
+       char *ret = dst;
+
+       asm volatile ("0: mvst  %0,%1\n"
+                     "   jo    0b"
+                     : "+&a" (dst), "+&a" (src) : "d" (r0)
+                     : "cc", "memory" );
+       return ret;
 }
 
-extern void *alloca(size_t);
+static inline size_t strlen(const char *s)
+{
+       register unsigned long r0 asm("0") = 0;
+       const char *tmp = s;
+
+       asm volatile ("0: srst  %0,%1\n"
+                     "   jo    0b"
+                     : "+d" (r0), "+a" (tmp) :  : "cc" );
+       return r0 - (unsigned long) s;
+}
+
+static inline size_t strnlen(const char * s, size_t n)
+{
+       register int r0 asm("0") = 0;
+       const char *tmp = s;
+       const char *end = s + n;
+
+       asm volatile ("0: srst  %0,%1\n"
+                     "   jo    0b"
+                     : "+a" (end), "+a" (tmp) : "d" (r0)  : "cc" );
+       return end - s;
+}
+
+#endif /* !IN_ARCH_STRING_C */
+
 #endif /* __KERNEL__ */
 
 #endif /* __S390_STRING_H_ */
index bb80c86..a2bfdee 100644 (file)
@@ -85,6 +85,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_NEED_RESCHED       3       /* rescheduling necessary */
 #define TIF_RESTART_SVC                4       /* restart svc with new svc number */
 #define TIF_SYSCALL_AUDIT      5       /* syscall auditing active */
+#define TIF_SINGLE_STEP                6       /* single stepped svc */
 #define TIF_USEDFPU            16      /* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG     17      /* true if poll_idle() is polling 
                                           TIF_NEED_RESCHED */
@@ -96,6 +97,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
 #define _TIF_RESTART_SVC       (1<<TIF_RESTART_SVC)
 #define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SINGLE_STEP       (1<<TIF_SINGLE_STEP)
 #define _TIF_USEDFPU           (1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 #define _TIF_31BIT             (1<<TIF_31BIT)
index dd57b3f..3fefd61 100644 (file)
@@ -79,6 +79,8 @@ typedef unsigned  long u64;
 
 typedef u32 dma_addr_t;
 
+typedef unsigned int kmem_bufctl_t;
+
 #ifndef __s390x__
 typedef union {
        unsigned long long pair;
@@ -94,9 +96,6 @@ typedef u64 sector_t;
 #endif
 
 #endif /* ! __s390x__   */
-
-typedef unsigned int kmem_bufctl_t;
-
 #endif /* __ASSEMBLY__  */
 #endif /* __KERNEL__    */
 #endif /* _S390_TYPES_H */
index bf4d2fc..bec57b7 100644 (file)
 
 #define access_ok(type,addr,size) __access_ok(addr,size)
 
-extern inline int verify_area(int type, const void * addr, unsigned long size)
+extern inline int verify_area(int type, const void __user *addr,
+                                               unsigned long size)
 {
-        return access_ok(type,addr,size)?0:-EFAULT;
+       return access_ok(type, addr, size) ? 0 : -EFAULT;
 }
 
 /*
@@ -147,6 +148,7 @@ struct exception_table_entry
 })
 #endif
 
+#ifndef __CHECKER__
 #define __put_user(x, ptr) \
 ({                                                             \
        __typeof__(*(ptr)) __x = (x);                           \
@@ -164,6 +166,14 @@ struct exception_table_entry
         }                                                      \
        __pu_err;                                               \
 })
+#else
+#define __put_user(x, ptr)                     \
+({                                             \
+       void __user *p;                         \
+       p = (ptr);                              \
+       0;                                      \
+})
+#endif
 
 #define put_user(x, ptr)                                       \
 ({                                                             \
@@ -202,6 +212,7 @@ extern int __put_user_bad(void);
 })
 #endif
 
+#ifndef __CHECKER__
 #define __get_user(x, ptr)                                     \
 ({                                                             \
        __typeof__(*(ptr)) __x;                                 \
@@ -221,6 +232,15 @@ extern int __put_user_bad(void);
        (x) = __x;                                              \
        __gu_err;                                               \
 })
+#else
+#define __get_user(x, ptr)                     \
+({                                             \
+       void __user *p;                         \
+       p = (ptr);                              \
+       0;                                      \
+})
+#endif
+
 
 #define get_user(x, ptr)                                       \
 ({                                                             \
@@ -230,7 +250,7 @@ extern int __put_user_bad(void);
 
 extern int __get_user_bad(void);
 
-extern long __copy_to_user_asm(const void *from, long n, void *to);
+extern long __copy_to_user_asm(const void *from, long n, void __user *to);
 
 /**
  * __copy_to_user: - Copy a block of data into user space, with less checking.
@@ -274,7 +294,7 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
        return n;
 }
 
-extern long __copy_from_user_asm(void *to, long n, const void *from);
+extern long __copy_from_user_asm(void *to, long n, const void __user *from);
 
 /**
  * __copy_from_user: - Copy a block of data from user space, with less checking.
@@ -326,12 +346,13 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
        return n;
 }
 
-extern long __copy_in_user_asm(const void *from, long n, void *to);
+extern unsigned long __copy_in_user_asm(const void __user *from, long n,
+                                                       void __user *to);
 
 static inline unsigned long
 __copy_in_user(void __user *to, const void __user *from, unsigned long n)
 {
-       __copy_in_user_asm(from, n, to);
+       return __copy_in_user_asm(from, n, to);
 }
 
 static inline unsigned long
@@ -346,26 +367,27 @@ copy_in_user(void __user *to, const void __user *from, unsigned long n)
 /*
  * Copy a null terminated string from userspace.
  */
-extern long __strncpy_from_user_asm(char *dst, const char *src, long count);
+extern long __strncpy_from_user_asm(long count, char *dst,
+                                       const char __user *src);
 
 static inline long
-strncpy_from_user(char *dst, const char *src, long count)
+strncpy_from_user(char *dst, const char __user *src, long count)
 {
         long res = -EFAULT;
         might_sleep();
         if (access_ok(VERIFY_READ, src, 1))
-                res = __strncpy_from_user_asm(dst, src, count);
+                res = __strncpy_from_user_asm(count, dst, src);
         return res;
 }
 
 
-extern long __strnlen_user_asm(const char *src, long count);
+extern long __strnlen_user_asm(long count, const char __user *src);
 
 static inline unsigned long
-strnlen_user(const char * src, unsigned long n)
+strnlen_user(const char __user * src, unsigned long n)
 {
        might_sleep();
-       return __strnlen_user_asm(src, n);
+       return __strnlen_user_asm(n, src);
 }
 
 /**
@@ -388,16 +410,16 @@ strnlen_user(const char * src, unsigned long n)
  * Zero Userspace
  */
 
-extern long __clear_user_asm(void *to, long n);
+extern long __clear_user_asm(void __user *to, long n);
 
 static inline unsigned long
-__clear_user(void *to, unsigned long n)
+__clear_user(void __user *to, unsigned long n)
 {
        return __clear_user_asm(to, n);
 }
 
 static inline unsigned long
-clear_user(void *to, unsigned long n)
+clear_user(void __user *to, unsigned long n)
 {
        might_sleep();
        if (access_ok(VERIFY_WRITE, to, n))
index 785c764..4d46012 100644 (file)
@@ -530,6 +530,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,    \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 # ifndef CONFIG_ARCH_S390X
 #   define __ARCH_WANT_STAT64
 # endif
index 5b96a77..512ffe6 100644 (file)
@@ -201,8 +201,10 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
  *     Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user (const char *src, char *dst,
-                                   int len, int sum, int *err_ptr)
+static __inline__ unsigned int csum_and_copy_to_user (const char *src, 
+                                                     char __user *dst,
+                                                     int len, int sum,
+                                                     int *err_ptr)
 {
        if (access_ok(VERIFY_WRITE, dst, len))
                return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
index 42faf5b..73e517a 100644 (file)
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 #ifdef __KERNEL__
 
        { RLIM_INFINITY, RLIM_INFINITY },               \
        {             0,             0 },               \
        {      INR_OPEN,     INR_OPEN  },               \
-       { PAGE_SIZE,     PAGE_SIZE     },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
        { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { MAX_SIGPENDING, MAX_SIGPENDING },             \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX },                 \
 }
 
 #endif /* __KERNEL__ */
index 9384ed2..26ad6dd 100644 (file)
@@ -422,6 +422,7 @@ __syscall_return(type,__sc0); \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
index ea48d2e..60c5633 100644 (file)
@@ -91,7 +91,7 @@ csum_partial_copy_from_user(const char *src, char *dst, int len,
   }
   
 static inline unsigned int 
-csum_partial_copy_to_user(const char *src, char *dst, int len, 
+csum_partial_copy_to_user(const char *src, char __user *dst, int len, 
                          unsigned int sum, int *err)
 {
        if (!access_ok (VERIFY_WRITE, dst, len)) {
index 2dc5bb8..08ede04 100644 (file)
@@ -2,6 +2,7 @@
 #define _ASM_SPARC_DMA_MAPPING_H
 
 #include <linux/config.h>
+#include <linux/device.h>
 
 #ifdef CONFIG_PCI
 #include <asm-generic/dma-mapping.h>
index 7ca1a85..95effa1 100644 (file)
@@ -24,7 +24,7 @@
 #include <asm/fixmap.h>
 #include <asm/vaddrs.h>
 #include <asm/kmap_types.h>
-#include <asm/pgtsrmmu.h>
+#include <asm/pgtable.h>
 
 /* declarations for highmem.c */
 extern unsigned long highstart_pfn, highend_pfn;
@@ -43,7 +43,7 @@ extern void kmap_init(void) __init;
  */
 #define LAST_PKMAP 1024
 #define PKMAP_SIZE (LAST_PKMAP << PAGE_SHIFT)
-#define PKMAP_BASE SRMMU_PMD_ALIGN_SOFT(SRMMU_NOCACHE_VADDR + (SRMMU_MAX_NOCACHE_PAGES << PAGE_SHIFT))
+#define PKMAP_BASE PMD_ALIGN(SRMMU_NOCACHE_VADDR + (SRMMU_MAX_NOCACHE_PAGES << PAGE_SHIFT))
 
 #define LAST_PKMAP_MASK (LAST_PKMAP - 1)
 #define PKMAP_NR(virt)  ((virt - PKMAP_BASE) >> PAGE_SHIFT)
index 291f862..fa53736 100644 (file)
@@ -75,29 +75,10 @@ BTFIXUPDEF_CALL(void,  mmu_unmap_dma_area, unsigned long busa, int len)
 #define mmu_unmap_dma_area(ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(ba,len)
 #define mmu_translate_dvma(ba)     BTFIXUP_CALL(mmu_translate_dvma)(ba)
 
-/*
- */
-BTFIXUPDEF_SIMM13(pmd_shift)
-BTFIXUPDEF_SETHI(pmd_size)
-BTFIXUPDEF_SETHI(pmd_mask)
-
-extern unsigned int pmd_align(unsigned int addr) __attribute_const__;
-extern __inline__ unsigned int pmd_align(unsigned int addr)
-{
-       return ((addr + ~BTFIXUP_SETHI(pmd_mask)) & BTFIXUP_SETHI(pmd_mask));
-}
-
 BTFIXUPDEF_SIMM13(pgdir_shift)
 BTFIXUPDEF_SETHI(pgdir_size)
 BTFIXUPDEF_SETHI(pgdir_mask)
 
-extern unsigned int pgdir_align(unsigned int addr) __attribute_const__;
-extern __inline__ unsigned int pgdir_align(unsigned int addr)
-{
-       return ((addr + ~BTFIXUP_SETHI(pgdir_mask)) & BTFIXUP_SETHI(pgdir_mask));
-}
-
-BTFIXUPDEF_SIMM13(ptrs_per_pte)
 BTFIXUPDEF_SIMM13(ptrs_per_pmd)
 BTFIXUPDEF_SIMM13(ptrs_per_pgd)
 BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
@@ -112,19 +93,19 @@ BTFIXUPDEF_INT(page_copy)
 BTFIXUPDEF_INT(page_readonly)
 BTFIXUPDEF_INT(page_kernel)
 
-#define PMD_SHIFT              BTFIXUP_SIMM13(pmd_shift)
-#define PMD_SIZE               BTFIXUP_SETHI(pmd_size)
-#define PMD_MASK               BTFIXUP_SETHI(pmd_mask)
-#define PMD_ALIGN(addr)        pmd_align(addr)
+#define PMD_SHIFT              SUN4C_PMD_SHIFT
+#define PMD_SIZE               (1UL << PMD_SHIFT)
+#define PMD_MASK               (~(PMD_SIZE-1))
+#define PMD_ALIGN(__addr)      (((__addr) + ~PMD_MASK) & PMD_MASK)
 #define PGDIR_SHIFT            BTFIXUP_SIMM13(pgdir_shift)
 #define PGDIR_SIZE             BTFIXUP_SETHI(pgdir_size)
 #define PGDIR_MASK             BTFIXUP_SETHI(pgdir_mask)
-#define PGDIR_ALIGN            pgdir_align(addr)
-#define PTRS_PER_PTE           BTFIXUP_SIMM13(ptrs_per_pte)
+#define PTRS_PER_PTE           1024
 #define PTRS_PER_PMD           BTFIXUP_SIMM13(ptrs_per_pmd)
 #define PTRS_PER_PGD           BTFIXUP_SIMM13(ptrs_per_pgd)
 #define USER_PTRS_PER_PGD      BTFIXUP_SIMM13(user_ptrs_per_pgd)
 #define FIRST_USER_PGD_NR      0
+#define PTE_SIZE               (PTRS_PER_PTE*4)
 
 #define PAGE_NONE      __pgprot(BTFIXUP_INT(page_none))
 #define PAGE_SHARED    __pgprot(BTFIXUP_INT(page_shared))
index e0cc31a..3107339 100644 (file)
 #define SRMMU_MAX_CONTEXTS     65536
 
 /* PMD_SHIFT determines the size of the area a second-level page table entry can map */
-#define SRMMU_PMD_SHIFT         18
-#define SRMMU_PMD_SIZE          (1UL << SRMMU_PMD_SHIFT)
-#define SRMMU_PMD_MASK          (~(SRMMU_PMD_SIZE-1))
-/* #define SRMMU_PMD_ALIGN(addr)   (((addr)+SRMMU_PMD_SIZE-1)&SRMMU_PMD_MASK) */
+#define SRMMU_REAL_PMD_SHIFT           18
+#define SRMMU_REAL_PMD_SIZE            (1UL << SRMMU_REAL_PMD_SHIFT)
+#define SRMMU_REAL_PMD_MASK            (~(SRMMU_REAL_PMD_SIZE-1))
+#define SRMMU_REAL_PMD_ALIGN(__addr)   (((__addr)+SRMMU_REAL_PMD_SIZE-1)&SRMMU_REAL_PMD_MASK)
 
 /* PGDIR_SHIFT determines what a third-level page table entry can map */
 #define SRMMU_PGDIR_SHIFT       24
 #define SRMMU_PGDIR_MASK        (~(SRMMU_PGDIR_SIZE-1))
 #define SRMMU_PGDIR_ALIGN(addr) (((addr)+SRMMU_PGDIR_SIZE-1)&SRMMU_PGDIR_MASK)
 
-#define SRMMU_PTRS_PER_PTE      64
-#define SRMMU_PTRS_PER_PMD      64
-#define SRMMU_PTRS_PER_PGD      256
+#define SRMMU_REAL_PTRS_PER_PTE        64
+#define SRMMU_REAL_PTRS_PER_PMD        64
+#define SRMMU_PTRS_PER_PGD     256
 
-#define SRMMU_PTE_TABLE_SIZE    0x100 /* 64 entries, 4 bytes a piece */
-#define SRMMU_PMD_TABLE_SIZE    0x100 /* 64 entries, 4 bytes a piece */
-#define SRMMU_PGD_TABLE_SIZE    0x400 /* 256 entries, 4 bytes a piece */
+#define SRMMU_REAL_PTE_TABLE_SIZE      (SRMMU_REAL_PTRS_PER_PTE*4)
+#define SRMMU_PMD_TABLE_SIZE           (SRMMU_REAL_PTRS_PER_PMD*4)
+#define SRMMU_PGD_TABLE_SIZE           (SRMMU_PTRS_PER_PGD*4)
 
 /*
  * To support pagetables in highmem, Linux introduces APIs which
  * software tables.
  *
  * PMD_SHIFT determines the size of the area a second-level page table entry
- * can map, and our pmd_t is 16 times larger than normal.
+ * can map, and our pmd_t is 16 times larger than normal.  The values which
+ * were once defined here are now generic for 4c and srmmu, so they're
+ * found in pgtable.h.
  */
-#define SRMMU_PTRS_PER_PTE_SOFT        (PAGE_SIZE/4)   /* 16 hard tables per 4K page */
-#define SRMMU_PTRS_PER_PMD_SOFT        4       /* Each pmd_t contains 16 hard PTPs */
-#define SRMMU_PTE_SZ_SOFT       PAGE_SIZE      /* same as above, in bytes */
-
-#define SRMMU_PMD_SHIFT_SOFT   22
-#define SRMMU_PMD_SIZE_SOFT    (1UL << SRMMU_PMD_SHIFT_SOFT)
-#define SRMMU_PMD_MASK_SOFT    (~(SRMMU_PMD_SIZE_SOFT-1))
-#define SRMMU_PMD_ALIGN_SOFT(addr)  (((addr)+SRMMU_PMD_SIZE_SOFT-1)&SRMMU_PMD_MASK_SOFT)
+#define SRMMU_PTRS_PER_PMD     4
 
 /* Definition of the values in the ET field of PTD's and PTE's */
 #define SRMMU_ET_MASK         0x3
@@ -255,7 +250,7 @@ extern __inline__ void srmmu_flush_tlb_region(unsigned long addr)
 
 extern __inline__ void srmmu_flush_tlb_segment(unsigned long addr)
 {
-       addr &= SRMMU_PMD_MASK;
+       addr &= SRMMU_REAL_PMD_MASK;
        __asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
                             "r" (addr | 0x100), /* Flush TLB segment.. */
                             "i" (ASI_M_FLUSH_PROBE) : "memory");
index 67a7d27..ecd5afc 100644 (file)
@@ -11,9 +11,6 @@
 
 /* PMD_SHIFT determines the size of the area a second-level page table can map */
 #define SUN4C_PMD_SHIFT       23
-#define SUN4C_PMD_SIZE        (1UL << SUN4C_PMD_SHIFT)
-#define SUN4C_PMD_MASK        (~(SUN4C_PMD_SIZE-1))
-#define SUN4C_PMD_ALIGN(addr) (((addr)+SUN4C_PMD_SIZE-1)&SUN4C_PMD_MASK)
 
 /* PGDIR_SHIFT determines what a third-level page table entry can map */
 #define SUN4C_PGDIR_SHIFT       23
index f989d50..f53b6db 100644 (file)
@@ -10,9 +10,6 @@
 
 /* PMD_SHIFT determines the size of the area a second-level page table can map */
 #define SUN4C_PMD_SHIFT       22
-#define SUN4C_PMD_SIZE        (1UL << SUN4C_PMD_SHIFT)
-#define SUN4C_PMD_MASK        (~(SUN4C_PMD_SIZE-1))
-#define SUN4C_PMD_ALIGN(addr) (((addr)+SUN4C_PMD_SIZE-1)&SUN4C_PMD_MASK)
 
 /* PGDIR_SHIFT determines what a third-level page table entry can map */
 #define SUN4C_PGDIR_SHIFT       22
index b6a5aca..58e90f7 100644 (file)
 #define RLIMIT_RSS     5               /* max resident set size */
 #define RLIMIT_NOFILE  6               /* max number of open files */
 #define RLIMIT_NPROC   7               /* max number of processes */
-#define RLIMIT_MEMLOCK  8               /* max locked-in-memory address space */
-#define RLIMIT_AS       9               /* address space limit */
+#define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
+#define RLIMIT_AS      9               /* address space limit */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 /*
  * SuS says limits have to be unsigned.
     {       0, RLIM_INFINITY},         \
     {RLIM_INFINITY, RLIM_INFINITY},    \
     {INR_OPEN, INR_OPEN}, {0, 0},      \
-    {PAGE_SIZE, PAGE_SIZE},    \
     {RLIM_INFINITY, RLIM_INFINITY},    \
-    {RLIM_INFINITY, RLIM_INFINITY}     \
+    {RLIM_INFINITY, RLIM_INFINITY},    \
+    {RLIM_INFINITY, RLIM_INFINITY},    \
+    {MAX_SIGPENDING, MAX_SIGPENDING},  \
+    {MQ_BYTES_MAX, MQ_BYTES_MAX},      \
 }
 
 #endif /* __KERNEL__ */
index 3742cfa..7541da7 100644 (file)
@@ -236,7 +236,7 @@ static inline unsigned long viking_hwprobe(unsigned long vaddr)
                             : "=r" (val)
                             : "r" (vaddr | 0x100), "i" (ASI_M_FLUSH_PROBE));
        if ((val & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
-               vaddr &= ~SRMMU_PMD_MASK;
+               vaddr &= ~SRMMU_REAL_PMD_MASK;
                vaddr >>= PAGE_SHIFT;
                return val | (vaddr << 8);
        }
index 9deee1a..d32c138 100644 (file)
@@ -204,43 +204,7 @@ static __inline__ unsigned int hweight8(unsigned int w)
  * @offset: The bitnumber to start searching at
  * @size: The maximum size to search
  */
-static __inline__ unsigned long find_next_bit(unsigned long *addr, unsigned long size, unsigned long offset)
-{
-       unsigned long *p = addr + (offset >> 6);
-       unsigned long result = offset & ~63UL;
-       unsigned long tmp;
-
-       if (offset >= size)
-               return size;
-       size -= result;
-       offset &= 63UL;
-       if (offset) {
-               tmp = *(p++);
-               tmp &= (~0UL << offset);
-               if (size < 64)
-                       goto found_first;
-               if (tmp)
-                       goto found_middle;
-               size -= 64;
-               result += 64;
-       }
-       while (size & ~63UL) {
-               if ((tmp = *(p++)))
-                       goto found_middle;
-               result += 64;
-               size -= 64;
-       }
-       if (!size)
-               return result;
-       tmp = *p;
-
-found_first:
-       tmp &= (~0UL >> (64 - size));
-       if (tmp == 0UL)        /* Are any bits set? */
-               return result + size; /* Nope. */
-found_middle:
-       return result + __ffs(tmp);
-}
+extern unsigned long find_next_bit(unsigned long *, unsigned long, unsigned long);
 
 /**
  * find_first_bit - find the first set bit in a memory region
@@ -258,43 +222,7 @@ found_middle:
  * on Linus's ALPHA routines, which are pretty portable BTW.
  */
 
-static __inline__ unsigned long find_next_zero_bit(unsigned long *addr, unsigned long size, unsigned long offset)
-{
-       unsigned long *p = addr + (offset >> 6);
-       unsigned long result = offset & ~63UL;
-       unsigned long tmp;
-
-       if (offset >= size)
-               return size;
-       size -= result;
-       offset &= 63UL;
-       if (offset) {
-               tmp = *(p++);
-               tmp |= ~0UL >> (64-offset);
-               if (size < 64)
-                       goto found_first;
-               if (~tmp)
-                       goto found_middle;
-               size -= 64;
-               result += 64;
-       }
-       while (size & ~63UL) {
-               if (~(tmp = *(p++)))
-                       goto found_middle;
-               result += 64;
-               size -= 64;
-       }
-       if (!size)
-               return result;
-       tmp = *p;
-
-found_first:
-       tmp |= ~0UL << size;
-       if (tmp == ~0UL)        /* Are any bits zero? */
-               return result + size; /* Nope. */
-found_middle:
-       return result + ffz(tmp);
-}
+extern unsigned long find_next_zero_bit(unsigned long *, unsigned long, unsigned long);
 
 #define find_first_zero_bit(addr, size) \
         find_next_zero_bit((addr), (size), 0)
@@ -320,42 +248,7 @@ static __inline__ int test_le_bit(int nr, __const__ unsigned long * addr)
 #define find_first_zero_le_bit(addr, size) \
         find_next_zero_le_bit((addr), (size), 0)
 
-static __inline__ unsigned long find_next_zero_le_bit(unsigned long *addr, unsigned long size, unsigned long offset)
-{
-       unsigned long *p = addr + (offset >> 6);
-       unsigned long result = offset & ~63UL;
-       unsigned long tmp;
-
-       if (offset >= size)
-               return size;
-       size -= result;
-       offset &= 63UL;
-       if(offset) {
-               tmp = __swab64p(p++);
-               tmp |= (~0UL >> (64-offset));
-               if(size < 64)
-                       goto found_first;
-               if(~tmp)
-                       goto found_middle;
-               size -= 64;
-               result += 64;
-       }
-       while(size & ~63) {
-               if(~(tmp = __swab64p(p++)))
-                       goto found_middle;
-               result += 64;
-               size -= 64;
-       }
-       if(!size)
-               return result;
-       tmp = __swab64p(p);
-found_first:
-       tmp |= (~0UL << size);
-       if (tmp == ~0UL)        /* Are any bits zero? */
-               return result + size; /* Nope. */
-found_middle:
-       return result + ffz(tmp);
-}
+extern unsigned long find_next_zero_le_bit(unsigned long *, unsigned long, unsigned long);
 
 #ifdef __KERNEL__
 
index a7d31c8..c388e6e 100644 (file)
@@ -66,8 +66,9 @@ csum_partial_copy_from_user(const char *src, char *dst, int len,
  */
 #define HAVE_CSUM_COPY_USER
 extern unsigned int csum_partial_copy_user_sparc64(const char *src, char *dst, int len, unsigned int sum);
+
 static __inline__ unsigned int 
-csum_and_copy_to_user(const char *src, char *dst, int len, 
+csum_and_copy_to_user(const char *src, char __user *dst, int len, 
                      unsigned int sum, int *err)
 {
        __asm__ __volatile__ ("stx      %0, [%%sp + 0x7ff + 128]"
index 0ae54dc..4a77dd6 100644 (file)
 #define RLIMIT_RSS     5               /* max resident set size */
 #define RLIMIT_NOFILE  6               /* max number of open files */
 #define RLIMIT_NPROC   7               /* max number of processes */
-#define RLIMIT_MEMLOCK  8               /* max locked-in-memory address space */
-#define RLIMIT_AS       9               /* address space limit */
+#define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
+#define RLIMIT_AS      9               /* address space limit */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 /*
  * SuS says limits have to be unsigned.
     {       0, RLIM_INFINITY},         \
     {RLIM_INFINITY, RLIM_INFINITY},    \
     {INR_OPEN, INR_OPEN}, {0, 0},      \
-    {PAGE_SIZE,     PAGE_SIZE    },    \
     {RLIM_INFINITY, RLIM_INFINITY},    \
-    {RLIM_INFINITY, RLIM_INFINITY}     \
+    {RLIM_INFINITY, RLIM_INFINITY},    \
+    {RLIM_INFINITY, RLIM_INFINITY},    \
+    {MAX_SIGPENDING, MAX_SIGPENDING},  \
+    {MQ_BYTES_MAX, MQ_BYTES_MAX},      \
 }
 
 #endif /* __KERNEL__ */
index ff7760c..5850620 100644 (file)
@@ -34,6 +34,7 @@ extern int um_execve(const char *file, char *const argv[], char *const env[]);
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
index 0203d2e..9f4ca4a 100644 (file)
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 /*
  * SuS says limits have to be unsigned.
        { RLIM_INFINITY, RLIM_INFINITY },               \
        {             0,             0 },               \
        {      INR_OPEN,     INR_OPEN  },               \
-       { PAGE_SIZE, PAGE_SIZE  },              \
        { RLIM_INFINITY, RLIM_INFINITY },               \
-        { RLIM_INFINITY, RLIM_INFINITY },              \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { MAX_SIGPENDING, MAX_SIGPENDING },             \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX },                 \
 }
 
 #endif /* __KERNEL__ */
index 3a2b2a5..f8163e8 100644 (file)
@@ -408,6 +408,7 @@ type name (atype a, btype b, ctype c, dtype d, etype e, ftype f)          \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
index ae42bca..c91f028 100644 (file)
@@ -337,16 +337,15 @@ static __inline__ int find_first_bit(const unsigned long * addr, unsigned size)
                "repe; scasl\n\t"
                "jz 1f\n\t"
                "leaq -4(%%rdi),%%rdi\n\t"
-               "bsfq (%%rdi),%%rax\n"
-               "1:\tsubl %%ebx,%%edi\n\t"
+               "bsfl (%%rdi),%%eax\n"
+               "1:\tsubq %%rbx,%%rdi\n\t"
                "shll $3,%%edi\n\t"
                "addl %%edi,%%eax"
                :"=a" (res), "=&c" (d0), "=&D" (d1)
-               :"1" ((size + 31) >> 5), "2" (addr), "b" (addr));
+               :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory");
        return res;
 }
 
-
 /**
  * find_next_bit - find the first set bit in a memory region
  * @addr: The address to base the search on
index 3718a8f..abcabbc 100644 (file)
@@ -139,9 +139,9 @@ extern unsigned long csum_partial_copy_generic(const char *src, const char *dst,
                                               int *src_err_ptr, int *dst_err_ptr);
 
 
-extern unsigned int csum_partial_copy_from_user(const char *src, char *dst, 
+extern unsigned int csum_partial_copy_from_user(const char __user *src, char *dst, 
                                       int len, unsigned int isum, int *errp);
-extern unsigned int csum_partial_copy_to_user(const char *src, char *dst, 
+extern unsigned int csum_partial_copy_to_user(const char *src, char __user *dst, 
                                      int len, unsigned int isum, int *errp);
 extern unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len, 
                                              unsigned int sum);
index c4f5209..c1e04aa 100644 (file)
@@ -186,15 +186,15 @@ struct compat_shmid64_ds {
  */
 typedef        u32             compat_uptr_t;
 
-static inline void *compat_ptr(compat_uptr_t uptr)
+static inline void __user *compat_ptr(compat_uptr_t uptr)
 {
-       return (void *)(unsigned long)uptr;
+       return (void __user *)(unsigned long)uptr;
 }
 
-static __inline__ void *compat_alloc_user_space(long len)
+static __inline__ void __user *compat_alloc_user_space(long len)
 {
        struct pt_regs *regs = (void *)current->thread.rsp0 - sizeof(struct pt_regs); 
-       return (void *)regs->rsp - len; 
+       return (void __user *)regs->rsp - len; 
 }
 
 #endif /* _ASM_X86_64_COMPAT_H */
index 9bb2b94..b454364 100644 (file)
@@ -118,7 +118,6 @@ static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned
        d.base1 = PTR_MIDDLE(tss) & 0xFF; 
        d.type = type;
        d.p = 1; 
-       d.g = 1;
        d.limit1 = (size >> 16) & 0xF;
        d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF; 
        d.base3 = PTR_HIGH(tss); 
@@ -135,7 +134,7 @@ static inline void set_tss_desc(unsigned cpu, void *addr)
 static inline void set_ldt_desc(unsigned cpu, void *addr, int size)
 { 
        set_tssldt_descriptor(&cpu_gdt_table[cpu][GDT_ENTRY_LDT], (unsigned long)addr, 
-                             DESC_LDT, size); 
+                             DESC_LDT, size * 8);
 }
 
 static inline void set_seg_base(unsigned cpu, int entry, void *base)
index 2f2df23..bca9b28 100644 (file)
@@ -170,7 +170,7 @@ static unsigned long vdma_mem_alloc(unsigned long size)
 static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
 {
        if((unsigned long) addr >= (unsigned long) high_memory)
-               return vfree((void *)addr);
+               vfree((void *)addr);
        else
                free_pages(addr, get_order(size));              
 }
index 244ffe2..4153db5 100644 (file)
@@ -3,8 +3,8 @@
 
 struct _fpstate_ia32;
 
-int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 *buf, int fsave);
-int save_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 *buf, 
+int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, int fsave);
+int save_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, 
                   struct pt_regs *regs, int fsave);
 
 #endif
index bb5edc3..10638b8 100644 (file)
@@ -23,7 +23,7 @@ extern void fpu_init(void);
 extern unsigned int mxcsr_feature_mask;
 extern void mxcsr_feature_mask_init(void);
 extern void init_fpu(struct task_struct *child);
-extern int save_i387(struct _fpstate *buf);
+extern int save_i387(struct _fpstate __user *buf);
 
 static inline int need_signal_i387(struct task_struct *me) 
 { 
@@ -48,7 +48,7 @@ static inline int need_signal_i387(struct task_struct *me)
 
 #define clear_fpu(tsk) do { \
        if ((tsk)->thread_info->status & TS_USEDFPU) {          \
-               asm volatile("fwait");                          \
+               asm volatile("fnclex ; fwait");                 \
                (tsk)->thread_info->status &= ~TS_USEDFPU;      \
                stts();                                         \
        }                                                       \
@@ -57,10 +57,10 @@ static inline int need_signal_i387(struct task_struct *me)
 /*
  * ptrace request handers...
  */
-extern int get_fpregs(struct user_i387_struct *buf,
+extern int get_fpregs(struct user_i387_struct __user *buf,
                      struct task_struct *tsk);
 extern int set_fpregs(struct task_struct *tsk,
-                     struct user_i387_struct *buf);
+                     struct user_i387_struct __user *buf);
 
 /*
  * i387 state interaction
@@ -93,7 +93,7 @@ static inline int restore_fpu_checking(struct i387_fxsave_struct *fx)
        return err;
 } 
 
-static inline int save_i387_checking(struct i387_fxsave_struct *fx) 
+static inline int save_i387_checking(struct i387_fxsave_struct __user *fx) 
 { 
        int err;
        asm volatile("1:  rex64 ; fxsave (%[fx])\n\t"
@@ -136,7 +136,7 @@ static inline void save_init_fpu( struct task_struct *tsk )
 /* 
  * This restores directly out of user space. Exceptions are handled.
  */
-static inline int restore_i387(struct _fpstate *buf)
+static inline int restore_i387(struct _fpstate __user *buf)
 {
        return restore_fpu_checking((struct i387_fxsave_struct *)buf);
 }
index b29899e..a680d03 100644 (file)
@@ -168,8 +168,8 @@ struct ustat32 {
 #ifdef __KERNEL__
 struct user_desc;
 struct siginfo_t;
-int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info);
-int do_set_thread_area(struct thread_struct *t, struct user_desc *u_info);
+int do_get_thread_area(struct thread_struct *t, struct user_desc __user *info);
+int do_set_thread_area(struct thread_struct *t, struct user_desc __user *info);
 int ia32_child_tls(struct task_struct *p, struct pt_regs *childregs);
 int ia32_copy_siginfo_from_user(siginfo_t *to, siginfo_t32 __user *from);
 int ia32_copy_siginfo_to_user(siginfo_t32 __user *to, siginfo_t *from);
index 5facf56..ff0309c 100644 (file)
 #define __NR_ia32_mq_timedreceive      (__NR_ia32_mq_open+3)
 #define __NR_ia32_mq_notify            (__NR_ia32_mq_open+4)
 #define __NR_ia32_mq_getsetattr        (__NR_ia32_mq_open+5)
+#define __NR_ia32_kexec                283
 
-#define IA32_NR_syscalls 285   /* must be > than biggest syscall! */
+#define IA32_NR_syscalls 287   /* must be > than biggest syscall! */
 
 #endif /* _ASM_X86_64_IA32_UNISTD_H_ */
index 99e1854..4cef0ef 100644 (file)
@@ -1,67 +1 @@
-/*
- *  linux/include/asm-x86_64/ide.h
- *
- *  Copyright (C) 1994-1996  Linus Torvalds & authors
- */
-
-/*
- *  This file contains the x86_64 architecture specific IDE code.
- */
-
-#ifndef __ASMx86_64_IDE_H
-#define __ASMx86_64_IDE_H
-
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-
-#ifndef MAX_HWIFS
-# ifdef CONFIG_BLK_DEV_IDEPCI
-#define MAX_HWIFS      10
-# else
-#define MAX_HWIFS      6
-# endif
-#endif
-
-static __inline__ int ide_default_irq(unsigned long base)
-{
-       switch (base) {
-               case 0x1f0: return 14;
-               case 0x170: return 15;
-               case 0x1e8: return 11;
-               case 0x168: return 10;
-               case 0x1e0: return 8;
-               case 0x160: return 12;
-               default:
-                       return 0;
-       }
-}
-
-static __inline__ unsigned long ide_default_io_base(int index)
-{
-       switch (index) {
-               case 0: return 0x1f0;
-               case 1: return 0x170;
-               case 2: return 0x1e8;
-               case 3: return 0x168;
-               case 4: return 0x1e0;
-               case 5: return 0x160;
-               default:
-                       return 0;
-       }
-}
-
-#define IDE_ARCH_OBSOLETE_INIT
-#define ide_default_io_ctl(base)       ((base) + 0x206) /* obsolete */
-
-#ifdef CONFIG_BLK_DEV_IDEPCI
-#define ide_init_default_irq(base)     (0)
-#else
-#define ide_init_default_irq(base)     ide_default_irq(base)
-#endif
-
-#include <asm-generic/ide_iops.h>
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASMx86_64_IDE_H */
+#include <asm-i386/ide.h>
index b0ce61d..1ddce4b 100644 (file)
@@ -195,8 +195,13 @@ extern void iounmap(void *addr);
 #define __raw_writel writel
 #define __raw_writeq writeq
 
-void *memcpy_fromio(void*,const void*,unsigned); 
-void *memcpy_toio(void*,const void*,unsigned); 
+void *__memcpy_fromio(void*,unsigned long,unsigned);
+void *__memcpy_toio(unsigned long,const void*,unsigned);
+
+#define memcpy_fromio(to,from,len) \
+  __memcpy_fromio((to),(unsigned long)(from),(len))
+#define memcpy_toio(to,from,len) \
+  __memcpy_toio((unsigned long)(to),(from),(len))
 #define memset_io(a,b,c)       memset((void *)(a),(b),(c))
 
 /*
index cbe6058..fd707a6 100644 (file)
@@ -189,7 +189,7 @@ extern void mp_register_lapic_address (u64 address);
 extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
 extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
 extern void mp_config_acpi_legacy_irqs (void);
-extern void mp_parse_prt (void);
+extern void mp_register_gsi (u32 gsi, int edge_level, int active_high_low);
 #endif /*CONFIG_X86_IO_APIC*/
 #endif
 
index 8f0b0f3..c5c2b01 100644 (file)
@@ -65,15 +65,20 @@ extern unsigned long vm_stack_flags, vm_stack_flags32;
 extern unsigned long vm_data_default_flags, vm_data_default_flags32;
 extern unsigned long vm_force_exec32;
 
+#define __START_KERNEL         0xffffffff80100000UL
+#define __START_KERNEL_map     0xffffffff80000000UL
+#define __PAGE_OFFSET           0x0000010000000000UL   /* 1 << 40 */
+
+#else
+#define __START_KERNEL         0xffffffff80100000
+#define __START_KERNEL_map     0xffffffff80000000
+#define __PAGE_OFFSET           0x0000010000000000     /* 1 << 40 */
 #endif /* !__ASSEMBLY__ */
 
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
 /* See Documentation/x86_64/mm.txt for a description of the memory map. */
-#define __START_KERNEL         0xffffffff80100000
-#define __START_KERNEL_map     0xffffffff80000000
-#define __PAGE_OFFSET           0x0000010000000000     /* 1 << 40 */
 #define __PHYSICAL_MASK_SHIFT  40
 #define __PHYSICAL_MASK                ((1UL << __PHYSICAL_MASK_SHIFT) - 1)
 #define __VIRTUAL_MASK_SHIFT   48
index 5555b9c..059ba4a 100644 (file)
@@ -124,13 +124,13 @@ static inline void set_pml4(pml4_t *dst, pml4_t val)
 
 
 #ifndef __ASSEMBLY__
-#define VMALLOC_START    0xffffff0000000000
-#define VMALLOC_END      0xffffff7fffffffff
-#define MODULES_VADDR    0xffffffffa0000000
-#define MODULES_END      0xffffffffafffffff
+#define VMALLOC_START    0xffffff0000000000UL
+#define VMALLOC_END      0xffffff7fffffffffUL
+#define MODULES_VADDR    0xffffffffa0000000UL
+#define MODULES_END      0xffffffffafffffffUL
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 
-#define IOMAP_START      0xfffffe8000000000
+#define IOMAP_START      0xfffffe8000000000UL
 
 #define _PAGE_BIT_PRESENT      0
 #define _PAGE_BIT_RW           1
@@ -262,8 +262,21 @@ extern inline pte_t pte_mkexec(pte_t pte)  { set_pte(&pte, __pte(pte_val(pte) | _
 extern inline pte_t pte_mkdirty(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
 extern inline pte_t pte_mkyoung(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
 extern inline pte_t pte_mkwrite(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
-static inline  int ptep_test_and_clear_dirty(pte_t *ptep)      { return test_and_clear_bit(_PAGE_BIT_DIRTY, ptep); }
-static inline  int ptep_test_and_clear_young(pte_t *ptep)      { return test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep); }
+
+static inline int ptep_test_and_clear_dirty(pte_t *ptep)
+{
+       if (!pte_dirty(*ptep))
+               return 0;
+       return test_and_clear_bit(_PAGE_BIT_DIRTY, ptep);
+}
+
+static inline int ptep_test_and_clear_young(pte_t *ptep)
+{
+       if (!pte_young(*ptep))
+               return 0;
+       return test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep);
+}
+
 static inline void ptep_set_wrprotect(pte_t *ptep)             { clear_bit(_PAGE_BIT_RW, ptep); }
 static inline void ptep_mkdirty(pte_t *ptep)                   { set_bit(_PAGE_BIT_DIRTY, ptep); }
 
@@ -383,6 +396,20 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 
 #define update_mmu_cache(vma,address,pte) do { } while (0)
 
+/* We only update the dirty/accessed state if we set
+ * the dirty bit by hand in the kernel, since the hardware
+ * will do the accessed bit for us, and we don't want to
+ * race with other CPU's that might be updating the dirty
+ * bit at the same time. */
+#define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
+       do {                                                              \
+               if (__dirty) {                                            \
+                       set_pte(__ptep, __entry);                         \
+                       flush_tlb_page(__vma, __address);                 \
+               }                                                         \
+       } while (0)
+
 /* Encode and de-code a swap entry */
 #define __swp_type(x)                  (((x).val >> 1) & 0x3f)
 #define __swp_offset(x)                        ((x).val >> 8)
index 7a253a8..ec696b2 100644 (file)
@@ -166,7 +166,7 @@ static inline void clear_in_cr4 (unsigned long mask)
 /*
  * User space process size: 512GB - 1GB (default).
  */
-#define TASK_SIZE      (0x0000007fc0000000)
+#define TASK_SIZE      (0x0000007fc0000000UL)
 
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
index 3c5c3a4..cbc19a7 100644 (file)
@@ -83,7 +83,7 @@ struct pt_regs {
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__) 
 #define user_mode(regs) (!!((regs)->cs & 3))
 #define instruction_pointer(regs) ((regs)->rip)
-void signal_fault(struct pt_regs *regs, void *frame, char *where);
+void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
 
 enum {
         EF_CF   = 0x00000001,
index f88aee8..9628f77 100644 (file)
 #define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 #define RLIMIT_AS      9               /* address space limit */
 #define RLIMIT_LOCKS   10              /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11           /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12             /* maximum bytes in POSIX mqueues */
 
-#define RLIM_NLIMITS   11
+#define RLIM_NLIMITS   13
 
 /*
  * SuS says limits have to be unsigned.
        { RLIM_INFINITY, RLIM_INFINITY },               \
        {             0,             0 },               \
        {      INR_OPEN,     INR_OPEN  },               \
-       { PAGE_SIZE , PAGE_SIZE  },             \
        { RLIM_INFINITY, RLIM_INFINITY },               \
-        { RLIM_INFINITY, RLIM_INFINITY },              \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { MAX_SIGPENDING, MAX_SIGPENDING },             \
+       { MQ_BYTES_MAX, MQ_BYTES_MAX },                 \
 }
 
 #endif /* __KERNEL__ */
index 5fe2548..2788834 100644 (file)
@@ -47,12 +47,12 @@ struct semaphore {
        atomic_t count;
        int sleepers;
        wait_queue_head_t wait;
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
        long __magic;
 #endif
 };
 
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
 # define __SEM_DEBUG_INIT(name) \
                , (int)&(name).__magic
 #else
@@ -83,7 +83,7 @@ static inline void sema_init (struct semaphore *sem, int val)
        atomic_set(&sem->count, val);
        sem->sleepers = 0;
        init_waitqueue_head(&sem->wait);
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
        sem->__magic = (int)&sem->__magic;
 #endif
 }
@@ -115,7 +115,7 @@ asmlinkage void __up(struct semaphore * sem);
  */
 static inline void down(struct semaphore * sem)
 {
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
        CHECK_MAGIC(sem->__magic);
 #endif
        might_sleep();
@@ -142,7 +142,7 @@ static inline int down_interruptible(struct semaphore * sem)
 {
        int result;
 
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
        CHECK_MAGIC(sem->__magic);
 #endif
        might_sleep();
@@ -171,7 +171,7 @@ static inline int down_trylock(struct semaphore * sem)
 {
        int result;
 
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
        CHECK_MAGIC(sem->__magic);
 #endif
 
@@ -199,7 +199,7 @@ static inline int down_trylock(struct semaphore * sem)
  */
 static inline void up(struct semaphore * sem)
 {
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
        CHECK_MAGIC(sem->__magic);
 #endif
        __asm__ __volatile__(
index 6a62408..b4e4023 100644 (file)
@@ -2,6 +2,7 @@
 #define _ASM_X86_64_SIGCONTEXT_H
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 
 /* FXSAVE frame */
 /* Note: reserved1/2 may someday contain valuable data. Always save/restore
@@ -47,7 +48,7 @@ struct sigcontext {
        unsigned long trapno;
        unsigned long oldmask;
        unsigned long cr2;
-       struct _fpstate *fpstate;       /* zero when no FPU context */
+       struct _fpstate __user *fpstate;        /* zero when no FPU context */
        unsigned long reserved1[8];
 };
 
index 9b4c018..ed4dc1c 100644 (file)
@@ -24,7 +24,7 @@
 
 #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
 
-#define KERNEL_DS      MAKE_MM_SEG(0xFFFFFFFFFFFFFFFF)
+#define KERNEL_DS      MAKE_MM_SEG(0xFFFFFFFFFFFFFFFFUL)
 #define USER_DS                MAKE_MM_SEG(PAGE_OFFSET)
 
 #define get_ds()       (KERNEL_DS)
  */
 #define __range_not_ok(addr,size) ({ \
        unsigned long flag,sum; \
+       __chk_user_ptr(addr); \
        asm("# range_ok\n\r" \
                "addq %3,%1 ; sbbq %0,%0 ; cmpq %1,%4 ; sbbq $0,%0"  \
                :"=&r" (flag), "=r" (sum) \
                :"1" (addr),"g" ((long)(size)),"g" (current_thread_info()->addr_limit.seg)); \
        flag; })
 
-#define access_ok(type,addr,size) (__range_not_ok(addr,size) == 0)
+#define access_ok(type, addr, size) (__range_not_ok(addr,size) == 0)
 
-extern inline int verify_area(int type, const void * addr, unsigned long size)
+extern inline int verify_area(int type, const void __user * addr, unsigned long size)
 {
        return access_ok(type,addr,size) ? 0 : -EFAULT;
 }
@@ -103,6 +104,7 @@ extern void __get_user_8(void);
 #define get_user(x,ptr)                                                        \
 ({     long __val_gu;                                                  \
        int __ret_gu;                                                   \
+       __chk_user_ptr(ptr);                                            \
        switch(sizeof (*(ptr))) {                                       \
        case 1:  __get_user_x(1,__ret_gu,__val_gu,ptr); break;          \
        case 2:  __get_user_x(2,__ret_gu,__val_gu,ptr); break;          \
@@ -155,6 +157,7 @@ extern void __put_user_bad(void);
 #define __put_user_size(x,ptr,size,retval)                             \
 do {                                                                   \
        retval = 0;                                                     \
+       __chk_user_ptr(ptr);                                            \
        switch (size) {                                                 \
          case 1: __put_user_asm(x,ptr,retval,"b","b","iq",-EFAULT); break;\
          case 2: __put_user_asm(x,ptr,retval,"w","w","ir",-EFAULT); break;\
@@ -203,6 +206,7 @@ extern int __get_user_bad(void);
 #define __get_user_size(x,ptr,size,retval)                             \
 do {                                                                   \
        retval = 0;                                                     \
+       __chk_user_ptr(ptr);                                            \
        switch (size) {                                                 \
          case 1: __get_user_asm(x,ptr,retval,"b","b","=q",-EFAULT); break;\
          case 2: __get_user_asm(x,ptr,retval,"w","w","=r",-EFAULT); break;\
@@ -235,116 +239,116 @@ do {                                                                    \
 /* Handles exceptions in both to and from, but doesn't do access_ok */
 extern unsigned long copy_user_generic(void *to, const void *from, unsigned len); 
 
-extern unsigned long copy_to_user(void *to, const void *from, unsigned len); 
-extern unsigned long copy_from_user(void *to, const void *from, unsigned len); 
-extern unsigned long copy_in_user(void *to, const void *from, unsigned len); 
+extern unsigned long copy_to_user(void __user *to, const void *from, unsigned len); 
+extern unsigned long copy_from_user(void *to, const void __user *from, unsigned len); 
+extern unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len); 
 
-static inline int __copy_from_user(void *dst, const void *src, unsigned size) 
+static inline int __copy_from_user(void *dst, const void __user *src, unsigned size) 
 { 
        int ret = 0;
        if (!__builtin_constant_p(size))
-               return copy_user_generic(dst,src,size);
+               return copy_user_generic(dst,(__force void *)src,size);
        switch (size) { 
-       case 1:__get_user_asm(*(u8*)dst,(u8 *)src,ret,"b","b","=q",1); 
+       case 1:__get_user_asm(*(u8*)dst,(u8 __user *)src,ret,"b","b","=q",1); 
                return ret;
-       case 2:__get_user_asm(*(u16*)dst,(u16*)src,ret,"w","w","=r",2);
+       case 2:__get_user_asm(*(u16*)dst,(u16 __user *)src,ret,"w","w","=r",2);
                return ret;
-       case 4:__get_user_asm(*(u32*)dst,(u32*)src,ret,"l","k","=r",4);
+       case 4:__get_user_asm(*(u32*)dst,(u32 __user *)src,ret,"l","k","=r",4);
                return ret;
-       case 8:__get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",8);
+       case 8:__get_user_asm(*(u64*)dst,(u64 __user *)src,ret,"q","","=r",8);
                return ret; 
        case 10:
-               __get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",16);
+               __get_user_asm(*(u64*)dst,(u64 __user *)src,ret,"q","","=r",16);
                if (unlikely(ret)) return ret;
-               __get_user_asm(*(u16*)(8+(char*)dst),(u16*)(8+(char*)src),ret,"w","w","=r",2);
+               __get_user_asm(*(u16*)(8+(char*)dst),(u16 __user *)(8+(char __user *)src),ret,"w","w","=r",2);
                return ret; 
        case 16:
-               __get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",16);
+               __get_user_asm(*(u64*)dst,(u64 __user *)src,ret,"q","","=r",16);
                if (unlikely(ret)) return ret;
-               __get_user_asm(*(u64*)(8+(char*)dst),(u64*)(8+(char*)src),ret,"q","","=r",8);
+               __get_user_asm(*(u64*)(8+(char*)dst),(u64 __user *)(8+(char __user *)src),ret,"q","","=r",8);
                return ret; 
        default:
-               return copy_user_generic(dst,src,size); 
+               return copy_user_generic(dst,(__force void *)src,size); 
        }
 }      
 
-static inline int __copy_to_user(void *dst, const void *src, unsigned size) 
+static inline int __copy_to_user(void __user *dst, const void *src, unsigned size) 
 { 
        int ret = 0;
        if (!__builtin_constant_p(size))
-               return copy_user_generic(dst,src,size);
+               return copy_user_generic((__force void *)dst,src,size);
        switch (size) { 
-       case 1:__put_user_asm(*(u8*)src,(u8 *)dst,ret,"b","b","iq",1); 
+       case 1:__put_user_asm(*(u8*)src,(u8 __user *)dst,ret,"b","b","iq",1); 
                return ret;
-       case 2:__put_user_asm(*(u16*)src,(u16*)dst,ret,"w","w","ir",2);
+       case 2:__put_user_asm(*(u16*)src,(u16 __user *)dst,ret,"w","w","ir",2);
                return ret;
-       case 4:__put_user_asm(*(u32*)src,(u32*)dst,ret,"l","k","ir",4);
+       case 4:__put_user_asm(*(u32*)src,(u32 __user *)dst,ret,"l","k","ir",4);
                return ret;
-       case 8:__put_user_asm(*(u64*)src,(u64*)dst,ret,"q","","ir",8);
+       case 8:__put_user_asm(*(u64*)src,(u64 __user *)dst,ret,"q","","ir",8);
                return ret; 
        case 10:
-               __put_user_asm(*(u64*)src,(u64*)dst,ret,"q","","ir",10);
+               __put_user_asm(*(u64*)src,(u64 __user *)dst,ret,"q","","ir",10);
                if (unlikely(ret)) return ret;
                asm("":::"memory");
-               __put_user_asm(4[(u16*)src],4+(u16*)dst,ret,"w","w","ir",2);
+               __put_user_asm(4[(u16*)src],4+(u16 __user *)dst,ret,"w","w","ir",2);
                return ret; 
        case 16:
-               __put_user_asm(*(u64*)src,(u64*)dst,ret,"q","","ir",16);
+               __put_user_asm(*(u64*)src,(u64 __user *)dst,ret,"q","","ir",16);
                if (unlikely(ret)) return ret;
                asm("":::"memory");
-               __put_user_asm(1[(u64*)src],1+(u64*)dst,ret,"q","","ir",8);
+               __put_user_asm(1[(u64*)src],1+(u64 __user *)dst,ret,"q","","ir",8);
                return ret; 
        default:
-               return copy_user_generic(dst,src,size); 
+               return copy_user_generic((__force void *)dst,src,size); 
        }
 }      
 
 
-static inline int __copy_in_user(void *dst, const void *src, unsigned size) 
+static inline int __copy_in_user(void __user *dst, const void __user *src, unsigned size) 
 { 
        int ret = 0;
        if (!__builtin_constant_p(size))
-               return copy_user_generic(dst,src,size);
+               return copy_user_generic((__force void *)dst,(__force void *)src,size);
        switch (size) { 
        case 1: { 
                u8 tmp;
-               __get_user_asm(tmp,(u8 *)src,ret,"b","b","=q",1); 
+               __get_user_asm(tmp,(u8 __user *)src,ret,"b","b","=q",1); 
                if (likely(!ret))
-                       __put_user_asm(tmp,(u8 *)dst,ret,"b","b","iq",1); 
+                       __put_user_asm(tmp,(u8 __user *)dst,ret,"b","b","iq",1); 
                return ret;
        }
        case 2: { 
                u16 tmp;
-               __get_user_asm(tmp,(u16 *)src,ret,"w","w","=r",2); 
+               __get_user_asm(tmp,(u16 __user *)src,ret,"w","w","=r",2); 
                if (likely(!ret))
-                       __put_user_asm(tmp,(u16 *)dst,ret,"w","w","ir",2); 
+                       __put_user_asm(tmp,(u16 __user *)dst,ret,"w","w","ir",2); 
                return ret;
        }
 
        case 4: { 
                u32 tmp;
-               __get_user_asm(tmp,(u32 *)src,ret,"l","k","=r",4); 
+               __get_user_asm(tmp,(u32 __user *)src,ret,"l","k","=r",4); 
                if (likely(!ret))
-                       __put_user_asm(tmp,(u32 *)dst,ret,"l","k","ir",4); 
+                       __put_user_asm(tmp,(u32 __user *)dst,ret,"l","k","ir",4); 
                return ret;
        }
        case 8: { 
                u64 tmp;
-               __get_user_asm(tmp,(u64 *)src,ret,"q","","=r",8); 
+               __get_user_asm(tmp,(u64 __user *)src,ret,"q","","=r",8); 
                if (likely(!ret))
-                       __put_user_asm(tmp,(u64 *)dst,ret,"q","","ir",8); 
+                       __put_user_asm(tmp,(u64 __user *)dst,ret,"q","","ir",8); 
                return ret;
        }
        default:
-               return copy_user_generic(dst,src,size); 
+               return copy_user_generic((__force void *)dst,(__force void *)src,size); 
        }
 }      
 
-long strncpy_from_user(char *dst, const char *src, long count);
-long __strncpy_from_user(char *dst, const char *src, long count);
-long strnlen_user(const char *str, long n);
-long strlen_user(const char *str);
-unsigned long clear_user(void *mem, unsigned long len);
-unsigned long __clear_user(void *mem, unsigned long len);
+long strncpy_from_user(char *dst, const char __user *src, long count);
+long __strncpy_from_user(char *dst, const char __user *src, long count);
+long strnlen_user(const char __user *str, long n);
+long strlen_user(const char __user *str);
+unsigned long clear_user(void __user *mem, unsigned long len);
+unsigned long __clear_user(void __user *mem, unsigned long len);
 
 #endif /* __X86_64_UACCESS_H */
index 2ea0cb4..26e0aa3 100644 (file)
@@ -591,6 +591,7 @@ do { \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
 #ifndef __KERNEL_SYSCALLS__
index 69389c4..6c2bd56 100644 (file)
 #define _LINUX_ACCT_H
 
 #include <linux/types.h>
+#include <asm/param.h>
 
 /* 
  *  comp_t is a 16-bit "floating" point number with a 3-bit base 8
- *  exponent and a 13-bit fraction. See linux/kernel/acct.c for the
- *  specific encoding system used.
+ *  exponent and a 13-bit fraction.
+ *  comp2_t is 24-bit with 5-bit base 2 exponent and 20 bit fraction
+ *  (leading 1 not stored).
+ *  See linux/kernel/acct.c for the specific encoding systems used.
  */
 
 typedef __u16  comp_t;
+typedef __u32  comp2_t;
 
 /*
  *   accounting file record
@@ -36,27 +40,59 @@ typedef __u16       comp_t;
 
 struct acct
 {
-       char            ac_flag;                /* Accounting Flags */
-/*
- *     No binary format break with 2.0 - but when we hit 32bit uid we'll
- *     have to bite one
- */
-       __u16           ac_uid;                 /* Accounting Real User ID */
-       __u16           ac_gid;                 /* Accounting Real Group ID */
-       __u16           ac_tty;                 /* Accounting Control Terminal */
-       __u32           ac_btime;               /* Accounting Process Creation Time */
-       comp_t          ac_utime;               /* Accounting User Time */
-       comp_t          ac_stime;               /* Accounting System Time */
-       comp_t          ac_etime;               /* Accounting Elapsed Time */
-       comp_t          ac_mem;                 /* Accounting Average Memory Usage */
-       comp_t          ac_io;                  /* Accounting Chars Transferred */
-       comp_t          ac_rw;                  /* Accounting Blocks Read or Written */
-       comp_t          ac_minflt;              /* Accounting Minor Pagefaults */
-       comp_t          ac_majflt;              /* Accounting Major Pagefaults */
-       comp_t          ac_swaps;               /* Accounting Number of Swaps */
-       __u32           ac_exitcode;            /* Accounting Exitcode */
-       char            ac_comm[ACCT_COMM + 1]; /* Accounting Command Name */
-       char            ac_pad[10];             /* Accounting Padding Bytes */
+       char            ac_flag;                /* Flags */
+       char            ac_version;             /* Always set to ACCT_VERSION */
+       /* for binary compatibility back until 2.0 */
+       __u16           ac_uid16;               /* LSB of Real User ID */
+       __u16           ac_gid16;               /* LSB of Real Group ID */
+       __u16           ac_tty;                 /* Control Terminal */
+       __u32           ac_btime;               /* Process Creation Time */
+       comp_t          ac_utime;               /* User Time */
+       comp_t          ac_stime;               /* System Time */
+       comp_t          ac_etime;               /* Elapsed Time */
+       comp_t          ac_mem;                 /* Average Memory Usage */
+       comp_t          ac_io;                  /* Chars Transferred */
+       comp_t          ac_rw;                  /* Blocks Read or Written */
+       comp_t          ac_minflt;              /* Minor Pagefaults */
+       comp_t          ac_majflt;              /* Major Pagefaults */
+       comp_t          ac_swaps;               /* Number of Swaps */
+/* m68k had no padding here. */
+#if !defined(CONFIG_M68K) || !defined(__KERNEL__)
+       __u16           ac_ahz;                 /* AHZ */
+#endif
+       __u32           ac_exitcode;            /* Exitcode */
+       char            ac_comm[ACCT_COMM + 1]; /* Command Name */
+       __u8            ac_etime_hi;            /* Elapsed Time MSB */
+       __u16           ac_etime_lo;            /* Elapsed Time LSB */
+       __u32           ac_uid;                 /* Real User ID */
+       __u32           ac_gid;                 /* Real Group ID */
+};
+
+struct acct_v3
+{
+       char            ac_flag;                /* Flags */
+       char            ac_version;             /* Always set to ACCT_VERSION */
+       __u16           ac_tty;                 /* Control Terminal */
+       __u32           ac_exitcode;            /* Exitcode */
+       __u32           ac_uid;                 /* Real User ID */
+       __u32           ac_gid;                 /* Real Group ID */
+       __u32           ac_pid;                 /* Process ID */
+       __u32           ac_ppid;                /* Parent Process ID */
+       __u32           ac_btime;               /* Process Creation Time */
+#ifdef __KERNEL__
+       __u32           ac_etime;               /* Elapsed Time */
+#else
+       float           ac_etime;               /* Elapsed Time */
+#endif
+       comp_t          ac_utime;               /* User Time */
+       comp_t          ac_stime;               /* System Time */
+       comp_t          ac_mem;                 /* Average Memory Usage */
+       comp_t          ac_io;                  /* Chars Transferred */
+       comp_t          ac_rw;                  /* Blocks Read or Written */
+       comp_t          ac_minflt;              /* Minor Pagefaults */
+       comp_t          ac_majflt;              /* Major Pagefaults */
+       comp_t          ac_swaps;               /* Number of Swaps */
+       char            ac_comm[ACCT_COMM];     /* Command Name */
 };
 
 /*
@@ -68,8 +104,7 @@ struct acct
 #define ACOMPAT                0x04    /* ... used compatibility mode (VAX only not used) */
 #define ACORE          0x08    /* ... dumped core */
 #define AXSIG          0x10    /* ... was killed by a signal */
-
-#define AHZ            100
+#define ABYTESEX       0x80    /* always set, allows to detect byteorder */
 
 #ifdef __KERNEL__
 
@@ -84,6 +119,66 @@ extern void acct_process(long exitcode);
 #define acct_process(x)                do { } while (0)
 #endif
 
+/*
+ * ACCT_VERSION numbers as yet defined:
+ * 0: old format (until 2.6.7) with 16 bit uid/gid
+ * 1: extended variant (binary compatible on M68K)
+ * 2: extended variant (binary compatible on everything except M68K)
+ * 3: new binary incompatible format (64 bytes)
+ * 4: new binary incompatible format (128 bytes)
+ * 5: new binary incompatible format (128 bytes, second half)
+ *
+ */
+
+#ifdef CONFIG_BSD_PROCESS_ACCT_V3
+#define ACCT_VERSION   3
+#define AHZ            100
+typedef struct acct_v3 acct_t;
+#else
+#ifdef CONFIG_M68K
+#define ACCT_VERSION   1
+#else
+#define ACCT_VERSION   2
+#endif
+#define AHZ            (USER_HZ)
+typedef struct acct acct_t;
+#endif
+
+#else
+#define ACCT_VERSION   2
+#define AHZ            (HZ)
 #endif /* __KERNEL */
 
+#ifdef __KERNEL__
+/*
+ * Yet another set of HZ to *HZ helper functions.
+ * See <linux/times.h> for the original.
+ */
+
+static inline u32 jiffies_to_AHZ(unsigned long x)
+{
+#if (TICK_NSEC % (NSEC_PER_SEC / AHZ)) == 0
+       return x / (HZ / USER_HZ);
+#else
+        u64 tmp = (u64)x * TICK_NSEC;
+        do_div(tmp, (NSEC_PER_SEC / AHZ));
+        return (long)tmp;
+#endif
+}
+
+static inline u64 jiffies_64_to_AHZ(u64 x)
+{
+#if (TICK_NSEC % (NSEC_PER_SEC / AHZ)) == 0
+#if HZ != AHZ
+       do_div(x, HZ / AHZ);
+#endif
+#else
+       x *= TICK_NSEC;
+       do_div(x, (NSEC_PER_SEC / AHZ));
+#endif
+       return x;
+}
+
+#endif  /* __KERNEL */
+
 #endif /* _LINUX_ACCT_H */
index d56069b..f82aa67 100644 (file)
@@ -413,6 +413,8 @@ static inline int acpi_boot_init(void)
 
 #endif         /*!CONFIG_ACPI_BOOT*/
 
+unsigned int acpi_register_gsi (u32 gsi, int edge_level, int active_high_low);
+int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 
 #ifdef CONFIG_ACPI_PCI
 
@@ -437,8 +439,6 @@ extern struct acpi_prt_list acpi_prt;
 struct pci_dev;
 
 int acpi_pci_irq_enable (struct pci_dev *dev);
-int acpi_pci_irq_init (void);
-int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 
 struct acpi_pci_driver {
        struct acpi_pci_driver *next;
index b03ebea..93fe788 100644 (file)
@@ -59,7 +59,10 @@ struct kiocb {
        struct list_head        ki_list;        /* the aio core uses this
                                                 * for cancellation */
 
-       void __user             *ki_user_obj;   /* pointer to userland's iocb */
+       union {
+               void __user             *user;
+               struct task_struct      *tsk;
+       } ki_obj;
        __u64                   ki_user_data;   /* user's data for completion */
        loff_t                  ki_pos;
 
@@ -76,7 +79,7 @@ struct kiocb {
                (x)->ki_filp = (filp);                  \
                (x)->ki_ctx = &tsk->active_mm->default_kioctx;  \
                (x)->ki_cancel = NULL;                  \
-               (x)->ki_user_obj = tsk;                 \
+               (x)->ki_obj.tsk = tsk;                  \
        } while (0)
 
 #define AIO_RING_MAGIC                 0xa10a10a1
@@ -149,11 +152,11 @@ struct mm_struct;
 extern void FASTCALL(exit_aio(struct mm_struct *mm));
 extern struct kioctx *lookup_ioctx(unsigned long ctx_id);
 extern int FASTCALL(io_submit_one(struct kioctx *ctx,
-                       struct iocb *user_iocb, struct iocb *iocb));
+                       struct iocb __user *user_iocb, struct iocb *iocb));
 
 /* semi private, but used by the 32bit emulations: */
 struct kioctx *lookup_ioctx(unsigned long ctx_id);
-int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb *user_iocb,
+int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
                                  struct iocb *iocb));
 
 #define get_ioctx(kioctx)      do { if (unlikely(atomic_read(&(kioctx)->users) <= 0)) BUG(); atomic_inc(&(kioctx)->users); } while (0)
index 0380156..7aec49c 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/socket.h>
 #include <linux/types.h>
 #endif
+#include <linux/compiler.h>
 #include <linux/atmapi.h>
 #include <linux/atmsap.h>
 #include <linux/atmioc.h>
@@ -232,7 +233,7 @@ static __inline__ int atmpvc_addr_in_use(struct sockaddr_atmpvc addr)
 struct atmif_sioc {
     int number;
     int length;
-    void *arg;
+    void __user *arg;
 };
 
 typedef unsigned short atm_backend_t;
index 9242c9c..b19303d 100644 (file)
@@ -351,11 +351,11 @@ struct atmdev_ops { /* only send is required */
        void (*dev_close)(struct atm_dev *dev);
        int (*open)(struct atm_vcc *vcc);
        void (*close)(struct atm_vcc *vcc);
-       int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void *arg);
+       int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void __user *arg);
        int (*getsockopt)(struct atm_vcc *vcc,int level,int optname,
-           void *optval,int optlen);
+           void __user *optval,int optlen);
        int (*setsockopt)(struct atm_vcc *vcc,int level,int optname,
-           void *optval,int optlen);
+           void __user *optval,int optlen);
        int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
        int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
        void (*phy_put)(struct atm_dev *dev,unsigned char value,
@@ -368,7 +368,7 @@ struct atmdev_ops { /* only send is required */
 
 struct atmphy_ops {
        int (*start)(struct atm_dev *dev);
-       int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void *arg);
+       int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void __user *arg);
        void (*interrupt)(struct atm_dev *dev);
        int (*stop)(struct atm_dev *dev);
 };
index 546d521..7917742 100644 (file)
@@ -13,6 +13,7 @@
 #define CONFIG_EXPERIMENTAL 1
 #define CONFIG_CLEAN_COMPILE 1
 #define CONFIG_STANDALONE 1
+#define CONFIG_BROKEN_ON_SMP 1
 
 /*
  * General setup
 #define CONFIG_SYSVIPC 1
 #define CONFIG_POSIX_MQUEUE 1
 #define CONFIG_BSD_PROCESS_ACCT 1
+#undef CONFIG_BSD_PROCESS_ACCT_V3
 #define CONFIG_SYSCTL 1
-#undef CONFIG_AUDIT
+#define CONFIG_AUDIT 1
+#define CONFIG_AUDITSYSCALL 1
 #define CONFIG_LOG_BUF_SHIFT 17
 #define CONFIG_HOTPLUG 1
 #undef CONFIG_IKCONFIG
 #define CONFIG_OBSOLETE_MODPARM 1
 #undef CONFIG_MODVERSIONS
 #define CONFIG_KMOD 1
-#define CONFIG_STOP_MACHINE 1
 
 /*
  * Processor type and features
  */
-#undef CONFIG_X86_PC
+#define CONFIG_X86_PC 1
 #undef CONFIG_X86_ELAN
 #undef CONFIG_X86_VOYAGER
 #undef CONFIG_X86_NUMAQ
 #undef CONFIG_X86_SUMMIT
 #undef CONFIG_X86_BIGSMP
 #undef CONFIG_X86_VISWS
-#define CONFIG_X86_GENERICARCH 1
+#undef CONFIG_X86_GENERICARCH
 #undef CONFIG_X86_ES7000
-#define CONFIG_X86_CYCLONE_TIMER 1
 #undef CONFIG_M386
 #undef CONFIG_M486
 #undef CONFIG_M586
 #define CONFIG_X86_HIGH_ENTRY 1
 #define CONFIG_HPET_TIMER 1
 #define CONFIG_HPET_EMULATE_RTC 1
-#define CONFIG_SMP 1
-#define CONFIG_NR_CPUS 32
-#define CONFIG_SCHED_SMT 1
+#undef CONFIG_SMP
 #undef CONFIG_PREEMPT
-#define CONFIG_X86_LOCAL_APIC 1
-#define CONFIG_X86_IO_APIC 1
+#undef CONFIG_X86_UP_APIC
 #define CONFIG_X86_TSC 1
 #define CONFIG_X86_MCE 1
 #undef CONFIG_X86_MCE_NONFATAL
-#define CONFIG_X86_MCE_P4THERMAL 1
 #define CONFIG_TOSHIBA_MODULE 1
 #define CONFIG_I8K_MODULE 1
 #define CONFIG_MICROCODE_MODULE 1
  */
 #define CONFIG_EDD_MODULE 1
 #undef CONFIG_NOHIGHMEM
-#undef CONFIG_HIGHMEM4G
-#define CONFIG_HIGHMEM64G 1
+#define CONFIG_HIGHMEM4G 1
+#undef CONFIG_HIGHMEM64G
 #define CONFIG_HIGHMEM 1
-#define CONFIG_X86_PAE 1
-#undef CONFIG_NUMA
 #define CONFIG_HIGHPTE 1
 #undef CONFIG_MATH_EMULATION
 #define CONFIG_MTRR 1
 #undef CONFIG_EFI
-#undef CONFIG_IRQBALANCE
-#define CONFIG_HAVE_DEC_LOCK 1
 #define CONFIG_REGPARM 1
 
 /*
 #define CONFIG_PCI_BIOS 1
 #define CONFIG_PCI_DIRECT 1
 #define CONFIG_PCI_MMCONFIG 1
-#define CONFIG_PCI_USE_VECTOR 1
 #define CONFIG_PCI_LEGACY_PROC 1
 #undef CONFIG_PCI_NAMES
 #define CONFIG_ISA 1
 #undef CONFIG_HOTPLUG_PCI_FAKE
 #define CONFIG_HOTPLUG_PCI_COMPAQ_MODULE 1
 #undef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM
-#define CONFIG_HOTPLUG_PCI_IBM_MODULE 1
 #undef CONFIG_HOTPLUG_PCI_ACPI
 #undef CONFIG_HOTPLUG_PCI_CPCI
 #define CONFIG_HOTPLUG_PCI_PCIE_MODULE 1
  */
 #define CONFIG_BINFMT_ELF 1
 #undef CONFIG_BINFMT_AOUT
-#define CONFIG_BINFMT_MISC_MODULE 1
+#define CONFIG_BINFMT_MISC 1
 
 /*
  * Device Drivers
 #undef CONFIG_BLK_DEV_HD_IDE
 #define CONFIG_BLK_DEV_IDEDISK 1
 #define CONFIG_IDEDISK_MULTI_MODE 1
-#undef CONFIG_IDEDISK_STROKE
 #define CONFIG_BLK_DEV_IDECS_MODULE 1
 #define CONFIG_BLK_DEV_IDECD 1
 #define CONFIG_BLK_DEV_IDETAPE_MODULE 1
  * SCSI low-level drivers
  */
 #define CONFIG_BLK_DEV_3W_XXXX_RAID_MODULE 1
+#define CONFIG_SCSI_3W_9XXX_MODULE 1
 #undef CONFIG_SCSI_7000FASST
 #define CONFIG_SCSI_ACARD_MODULE 1
 #define CONFIG_SCSI_AHA152X_MODULE 1
 #define CONFIG_SCSI_SATA_VITESSE_MODULE 1
 #define CONFIG_SCSI_BUSLOGIC_MODULE 1
 #undef CONFIG_SCSI_OMIT_FLASHPOINT
-#undef CONFIG_SCSI_CPQFCTS
 #undef CONFIG_SCSI_DMX3191D
 #undef CONFIG_SCSI_DTC3280
 #undef CONFIG_SCSI_EATA
 #define CONFIG_MD_MULTIPATH_MODULE 1
 #define CONFIG_BLK_DEV_DM_MODULE 1
 #define CONFIG_DM_CRYPT_MODULE 1
+#define CONFIG_DM_SNAPSHOT_MODULE 1
+#define CONFIG_DM_MIRROR_MODULE 1
+#define CONFIG_DM_ZERO_MODULE 1
 
 /*
  * Fusion MPT device support
 /*
  * Old SIR device drivers
  */
+#define CONFIG_IRPORT_SIR_MODULE 1
 
 /*
  * Old Serial dongle support
  */
+#undef CONFIG_DONGLE_OLD
 
 /*
  * FIR device drivers
 #define CONFIG_ULTRA_MODULE 1
 #define CONFIG_SMC9194_MODULE 1
 #define CONFIG_NET_VENDOR_RACAL 1
+#undef CONFIG_NI5010
 #define CONFIG_NI52_MODULE 1
 #define CONFIG_NI65_MODULE 1
 
 #define CONFIG_WINBOND_840_MODULE 1
 #define CONFIG_DM9102_MODULE 1
 #define CONFIG_PCMCIA_XIRCOM_MODULE 1
+#undef CONFIG_PCMCIA_XIRTULIP
 #undef CONFIG_AT1700
 #define CONFIG_DEPCA_MODULE 1
 #define CONFIG_HP100_MODULE 1
 #define CONFIG_TLAN_MODULE 1
 #define CONFIG_VIA_RHINE_MODULE 1
 #define CONFIG_VIA_RHINE_MMIO 1
+#define CONFIG_VIA_VELOCITY_MODULE 1
 #define CONFIG_NET_POCKET 1
 #define CONFIG_ATP_MODULE 1
 #define CONFIG_DE600_MODULE 1
 #define CONFIG_DE620_MODULE 1
 
 /*
- * Gigabit Ethernet (1000/10000 Mbit)
+ * Ethernet (1000 Mbit)
  */
-#define CONFIG_NET_GIGE 1
 #define CONFIG_ACENIC_MODULE 1
 #undef CONFIG_ACENIC_OMIT_TIGON_I
 #define CONFIG_DL2K_MODULE 1
 #define CONFIG_R8169_MODULE 1
 #define CONFIG_SK98LIN_MODULE 1
 #define CONFIG_TIGON3_MODULE 1
+
+/*
+ * Ethernet (10000 Mbit)
+ */
 #define CONFIG_IXGB_MODULE 1
 #define CONFIG_IXGB_NAPI 1
 #define CONFIG_S2IO_MODULE 1
 /*
  * ISDN feature submodules
  */
+#define CONFIG_ISDN_DRV_LOOP_MODULE 1
 
 /*
  * ISDN4Linux hardware drivers
 #define CONFIG_ISDN_DRV_SC_MODULE 1
 #define CONFIG_ISDN_DRV_ACT2000_MODULE 1
 #define CONFIG_ISDN_DRV_TPAM_MODULE 1
+#define CONFIG_HYSDN_MODULE 1
+#define CONFIG_HYSDN_CAPI 1
 
 /*
  * CAPI subsystem
  * Active AVM cards
  */
 #define CONFIG_CAPI_AVM 1
+#define CONFIG_ISDN_DRV_AVMB1_B1ISA_MODULE 1
+#define CONFIG_ISDN_DRV_AVMB1_B1PCI_MODULE 1
+#define CONFIG_ISDN_DRV_AVMB1_B1PCIV4 1
+#define CONFIG_ISDN_DRV_AVMB1_T1ISA_MODULE 1
+#define CONFIG_ISDN_DRV_AVMB1_B1PCMCIA_MODULE 1
+#define CONFIG_ISDN_DRV_AVMB1_AVM_CS_MODULE 1
+#define CONFIG_ISDN_DRV_AVMB1_T1PCI_MODULE 1
+#define CONFIG_ISDN_DRV_AVMB1_C4_MODULE 1
 
 /*
  * Active Eicon DIVA Server cards
 #define CONFIG_VT_CONSOLE 1
 #define CONFIG_HW_CONSOLE 1
 #define CONFIG_SERIAL_NONSTANDARD 1
+#undef CONFIG_COMPUTONE
 #define CONFIG_ROCKETPORT_MODULE 1
 #undef CONFIG_CYCLADES
+#undef CONFIG_DIGIEPCA
+#undef CONFIG_DIGI
+#undef CONFIG_ESPSERIAL
+#undef CONFIG_MOXA_INTELLIO
+#undef CONFIG_MOXA_SMARTIO
+#undef CONFIG_ISI
 #define CONFIG_SYNCLINK_MODULE 1
 #define CONFIG_SYNCLINKMP_MODULE 1
 #define CONFIG_N_HDLC_MODULE 1
+#undef CONFIG_RISCOM8
+#undef CONFIG_SPECIALIX
+#undef CONFIG_SX
+#undef CONFIG_RIO
 #define CONFIG_STALDRV 1
+#undef CONFIG_STALLION
+#undef CONFIG_ISTALLION
 
 /*
  * Serial drivers
 /*
  * Ftape, the floppy tape device driver
  */
+#undef CONFIG_FTAPE
 #define CONFIG_AGP 1
 #define CONFIG_AGP_ALI 1
 #define CONFIG_AGP_ATI 1
 #define CONFIG_SYNCLINK_CS_MODULE 1
 #define CONFIG_MWAVE_MODULE 1
 #undef CONFIG_RAW_DRIVER
+#undef CONFIG_HPET
 #define CONFIG_HANGCHECK_TIMER_MODULE 1
 
 /*
 #define CONFIG_I2C_ALI15X3_MODULE 1
 #define CONFIG_I2C_AMD756_MODULE 1
 #define CONFIG_I2C_AMD8111_MODULE 1
+#undef CONFIG_I2C_ELEKTOR
 #define CONFIG_I2C_I801_MODULE 1
 #define CONFIG_I2C_I810_MODULE 1
 #define CONFIG_I2C_ISA_MODULE 1
 #define CONFIG_VIDEO_ZORAN_DC30_MODULE 1
 #define CONFIG_VIDEO_ZORAN_LML33_MODULE 1
 #define CONFIG_VIDEO_ZORAN_LML33R10_MODULE 1
+#define CONFIG_VIDEO_MEYE_MODULE 1
 #define CONFIG_VIDEO_SAA7134_MODULE 1
 #define CONFIG_VIDEO_MXB_MODULE 1
 #define CONFIG_VIDEO_DPC_MODULE 1
 /*
  * Digital Video Broadcasting Devices
  */
-#undef CONFIG_DVB
+#define CONFIG_DVB 1
+#define CONFIG_DVB_CORE_MODULE 1
+
+/*
+ * Supported Frontend Modules
+ */
+#define CONFIG_DVB_TWINHAN_DST_MODULE 1
+#define CONFIG_DVB_STV0299_MODULE 1
+#undef CONFIG_DVB_SP887X
+#undef CONFIG_DVB_ALPS_TDLB7
+#define CONFIG_DVB_ALPS_TDMB7_MODULE 1
+#define CONFIG_DVB_ATMEL_AT76C651_MODULE 1
+#define CONFIG_DVB_CX24110_MODULE 1
+#define CONFIG_DVB_GRUNDIG_29504_491_MODULE 1
+#define CONFIG_DVB_GRUNDIG_29504_401_MODULE 1
+#define CONFIG_DVB_MT312_MODULE 1
+#define CONFIG_DVB_VES1820_MODULE 1
+#define CONFIG_DVB_VES1X93_MODULE 1
+#undef CONFIG_DVB_TDA1004X
+#define CONFIG_DVB_NXT6000_MODULE 1
+
+/*
+ * Supported SAA7146 based PCI Adapters
+ */
+#define CONFIG_DVB_AV7110_MODULE 1
+#define CONFIG_DVB_AV7110_OSD 1
+#define CONFIG_DVB_BUDGET_MODULE 1
+#define CONFIG_DVB_BUDGET_CI_MODULE 1
+#define CONFIG_DVB_BUDGET_AV_MODULE 1
+#define CONFIG_DVB_BUDGET_PATCH_MODULE 1
+
+/*
+ * Supported USB Adapters
+ */
+#define CONFIG_DVB_TTUSB_BUDGET_MODULE 1
+#define CONFIG_DVB_TTUSB_DEC_MODULE 1
+
+/*
+ * Supported FlexCopII (B2C2) Adapters
+ */
+#define CONFIG_DVB_B2C2_SKYSTAR_MODULE 1
+
+/*
+ * Supported BT878 Adapters
+ */
+#define CONFIG_DVB_BT8XX_MODULE 1
 #define CONFIG_VIDEO_SAA7146_MODULE 1
 #define CONFIG_VIDEO_SAA7146_VV_MODULE 1
 #define CONFIG_VIDEO_VIDEOBUF_MODULE 1
 #define CONFIG_FB_HGA_MODULE 1
 #define CONFIG_FB_HGA_ACCEL 1
 #define CONFIG_FB_RIVA_MODULE 1
+#undef CONFIG_FB_RIVA_I2C
 #define CONFIG_FB_I810_MODULE 1
 #define CONFIG_FB_I810_GTF 1
 #define CONFIG_FB_MATROX_MODULE 1
 #define CONFIG_USB_PRINTER_MODULE 1
 #define CONFIG_USB_STORAGE_MODULE 1
 #undef CONFIG_USB_STORAGE_DEBUG
+#define CONFIG_USB_STORAGE_RW_DETECT 1
 #define CONFIG_USB_STORAGE_DATAFAB 1
 #define CONFIG_USB_STORAGE_FREECOM 1
 #define CONFIG_USB_STORAGE_ISD200 1
 #define CONFIG_USB_SERIAL_MODULE 1
 #define CONFIG_USB_SERIAL_GENERIC 1
 #define CONFIG_USB_SERIAL_BELKIN_MODULE 1
+#define CONFIG_USB_SERIAL_WHITEHEAT_MODULE 1
 #define CONFIG_USB_SERIAL_DIGI_ACCELEPORT_MODULE 1
 #define CONFIG_USB_SERIAL_EMPEG_MODULE 1
 #define CONFIG_USB_SERIAL_FTDI_SIO_MODULE 1
 #define CONFIG_SOLARIS_X86_PARTITION 1
 #define CONFIG_UNIXWARE_DISKLABEL 1
 #undef CONFIG_LDM_PARTITION
-#undef CONFIG_NEC98_PARTITION
 #define CONFIG_SGI_PARTITION 1
 #undef CONFIG_ULTRIX_PARTITION
 #define CONFIG_SUN_PARTITION 1
 /*
  * Profiling support
  */
-#define CONFIG_PROFILING 1
-#define CONFIG_OPROFILE_MODULE 1
+#undef CONFIG_PROFILING
 
 /*
  * Kernel hacking
 #define CONFIG_DEBUG_INFO 1
 #define CONFIG_DEBUG_SPINLOCK_SLEEP 1
 #undef CONFIG_FRAME_POINTER
-#define CONFIG_X86_FIND_SMP_CONFIG 1
-#define CONFIG_X86_MPPARSE 1
 
 /*
  * Security options
 #define CONFIG_LIBCRC32C_MODULE 1
 #define CONFIG_ZLIB_INFLATE 1
 #define CONFIG_ZLIB_DEFLATE_MODULE 1
-#define CONFIG_X86_SMP 1
-#define CONFIG_X86_HT 1
 #define CONFIG_X86_BIOS_REBOOT 1
-#define CONFIG_X86_TRAMPOLINE 1
-#define CONFIG_X86_STD_RESOURCES 1
 #define CONFIG_PC 1
index 60726b2..b59bacd 100644 (file)
@@ -35,9 +35,13 @@ struct linux_binprm{
        char * interp;          /* Name of the binary really executed. Most
                                   of the time same as filename, but could be
                                   different for binfmt_{misc,script} */
+       unsigned long interp_flags;
        unsigned long loader, exec;
 };
 
+#define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
+#define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT)
+
 /*
  * This structure defines the functions that are used to load the binary formats that
  * linux accepts.
index fae1c4d..15cf6aa 100644 (file)
@@ -592,6 +592,7 @@ extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bd
 extern int blk_rq_map_sg(request_queue_t *, struct request *, struct scatterlist *);
 extern void blk_dump_rq_flags(struct request *, char *);
 extern void generic_unplug_device(request_queue_t *);
+extern inline void __generic_unplug_device(request_queue_t *);
 extern long nr_blockdev_pages(void);
 
 int blk_get_queue(request_queue_t *);
index a00a63e..ee0c6e8 100644 (file)
@@ -167,7 +167,7 @@ typedef struct _IOCTL_Command_struct {
   RequestBlock_struct      Request;
   ErrorInfo_struct        error_info; 
   WORD                    buf_size;  /* size in bytes of the buf */
-  BYTE                    *buf;
+  BYTE                    __user *buf;
 } IOCTL_Command_struct;
 
 typedef struct _BIG_IOCTL_Command_struct {
@@ -177,7 +177,7 @@ typedef struct _BIG_IOCTL_Command_struct {
   DWORD                           malloc_size; /* < MAX_KMALLOC_SIZE in cciss.c */
   DWORD                           buf_size;    /* size in bytes of the buf */
                                        /* < malloc_size * MAXSGENTRIES */
-  BYTE                    *buf;
+  BYTE                    __user *buf;
 } BIG_IOCTL_Command_struct;
 
 typedef struct _LogvolInfo_struct{
@@ -206,7 +206,35 @@ typedef struct _LogvolInfo_struct{
 #define CCISS_REGNEWDISK  _IOW(CCISS_IOC_MAGIC, 13, int)
 
 #define CCISS_REGNEWD     _IO(CCISS_IOC_MAGIC, 14)
+#define CCISS_RESCANDISK   _IO(CCISS_IOC_MAGIC, 16)
 #define CCISS_GETLUNINFO   _IOR(CCISS_IOC_MAGIC, 17, LogvolInfo_struct)
 #define CCISS_BIG_PASSTHRU _IOWR(CCISS_IOC_MAGIC, 18, BIG_IOCTL_Command_struct)
 
+#ifdef __KERNEL__
+#ifdef CONFIG_COMPAT
+
+/* 32 bit compatible ioctl structs */
+typedef struct _IOCTL32_Command_struct {
+  LUNAddr_struct          LUN_info;
+  RequestBlock_struct      Request;
+  ErrorInfo_struct        error_info;
+  WORD                    buf_size;  /* size in bytes of the buf */
+  __u32                           buf; /* 32 bit pointer to data buffer */
+} IOCTL32_Command_struct;
+
+typedef struct _BIG_IOCTL32_Command_struct {
+  LUNAddr_struct          LUN_info;
+  RequestBlock_struct      Request;
+  ErrorInfo_struct        error_info;
+  DWORD                           malloc_size; /* < MAX_KMALLOC_SIZE in cciss.c */
+  DWORD                           buf_size;    /* size in bytes of the buf */
+                                       /* < malloc_size * MAXSGENTRIES */
+  __u32                buf;    /* 32 bit pointer to data buffer */
+} BIG_IOCTL32_Command_struct;
+
+#define CCISS_PASSTHRU32   _IOWR(CCISS_IOC_MAGIC, 11, IOCTL32_Command_struct)
+#define CCISS_BIG_PASSTHRU32 _IOWR(CCISS_IOC_MAGIC, 18, BIG_IOCTL32_Command_struct)
+
+#endif /* CONFIG_COMPAT */
+#endif /* __KERNEL__ */
 #endif  
index a1727a0..282e9b7 100644 (file)
@@ -237,9 +237,9 @@ struct cdrom_read
 struct cdrom_read_audio
 {
        union cdrom_addr addr; /* frame address */
-       __u8 addr_format;    /* CDROM_LBA or CDROM_MSF */
+       __u8 addr_format;      /* CDROM_LBA or CDROM_MSF */
        int nframes;           /* number of 2352-byte-frames to read at once */
-       __u8 *buf;           /* frame buffer (size: nframes*2352 bytes) */
+       __u8 __user *buf;      /* frame buffer (size: nframes*2352 bytes) */
 };
 
 /* This struct is used with the CDROMMULTISESSION ioctl */
index 3743f5e..eb921d6 100644 (file)
@@ -759,13 +759,14 @@ union coda_downcalls {
 
 #define PIOCPARM_MASK 0x0000ffff
 struct ViceIoctl {
-        caddr_t in, out;        /* Data to be transferred in, or out */
+        void __user *in;        /* Data to be transferred in */
+        void __user *out;       /* Data to be transferred out */
         short in_size;          /* Size of input buffer <= 2K */
         short out_size;         /* Maximum size of output buffer, <= 2K */
 };
 
 struct PioctlData {
-        const char *path;
+        const char __user *path;
         int follow;
         struct ViceIoctl vi;
 };
index 26faac1..5bf7521 100644 (file)
@@ -82,9 +82,9 @@ void reset_coda_cache_inv_stats( void );
  * data structure for /proc/sys/... files 
  */
 int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
-                            void * buffer, size_t * lenp );
+                            void __user * buffer, size_t * lenp );
 int do_reset_coda_cache_inv_stats( ctl_table * table, int write, 
-                                  struct file * filp, void * buffer, 
+                                  struct file * filp, void __user * buffer, 
                                   size_t * lenp );
 
 /* these functions are called to form the content of /proc/fs/coda/... files */
index 1e2850e..356590d 100644 (file)
@@ -125,6 +125,7 @@ COMPATIBLE_IOCTL(STOP_ARRAY_RO)
 COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
 /* DM */
 COMPATIBLE_IOCTL(DM_VERSION_32)
+COMPATIBLE_IOCTL(DM_REMOVE_ALL_32)
 COMPATIBLE_IOCTL(DM_LIST_DEVICES_32)
 COMPATIBLE_IOCTL(DM_DEV_CREATE_32)
 COMPATIBLE_IOCTL(DM_DEV_REMOVE_32)
index 7ca3f48..5925e83 100644 (file)
@@ -27,6 +27,7 @@
 
 struct cpu {
        int node_id;            /* The node which contains the CPU */
+       int no_control;         /* Should the sysfs control file be created? */
        struct sys_device sysdev;
 };
 
@@ -60,7 +61,8 @@ extern struct semaphore cpucontrol;
 #define unlock_cpu_hotplug()   up(&cpucontrol)
 #define lock_cpu_hotplug_interruptible() down_interruptible(&cpucontrol)
 #define hotcpu_notifier(fn, pri) {                             \
-       static struct notifier_block fn##_nb = { fn, pri };     \
+       static struct notifier_block fn##_nb =                  \
+               { .notifier_call = fn, .priority = pri };       \
        register_cpu_notifier(&fn##_nb);                        \
 }
 int cpu_down(unsigned int cpu);
index ee77380..4293a46 100644 (file)
@@ -41,6 +41,7 @@ extern cpumask_t cpu_present_map;
 #define cpu_possible(cpu)              ({ BUG_ON((cpu) != 0); 1; })
 #define cpu_present(cpu)               ({ BUG_ON((cpu) != 0); 1; })
 
+#define for_each_cpu_mask(cpu, mask) for (cpu = 0; cpu < 1; cpu++)
 #define for_each_cpu(cpu) for (cpu = 0; cpu < 1; cpu++)
 #define for_each_online_cpu(cpu) for (cpu = 0; cpu < 1; cpu++)
 #define for_each_present_cpu(cpu) for (cpu = 0; cpu < 1; cpu++)
index 70cc9a3..b3b36e2 100644 (file)
@@ -166,9 +166,9 @@ struct edd_info {
        u8 device;
        u8 version;
        u16 interface_support;
-       u16 legacy_cylinders;
-       u8 legacy_heads;
-       u8 legacy_sectors;
+       u16 legacy_max_cylinder;
+       u8 legacy_max_head;
+       u8 legacy_sectors_per_track;
        struct edd_device_params params;
 } __attribute__ ((packed));
 
index 536b828..b6b470e 100644 (file)
@@ -370,11 +370,4 @@ struct efi_generic_dev_path {
        u16 length;
 } __attribute ((packed));
 
-/*
- * efi_dir is allocated in arch/ia64/kernel/efi.c.
- */
-#ifdef CONFIG_PROC_FS
-extern struct proc_dir_entry *efi_dir;
-#endif
-
 #endif /* _LINUX_EFI_H */
index 8d4d0e3..c85b210 100644 (file)
@@ -351,6 +351,8 @@ struct ethtool_ops {
        int     (*phys_id)(struct net_device *, u32);
        int     (*get_stats_count)(struct net_device *);
        void    (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *);
+       int     (*begin)(struct net_device *);
+       void    (*complete)(struct net_device *);
 };
 
 /* CMDs currently supported */
index a4440a9..0814515 100644 (file)
@@ -33,10 +33,11 @@ struct statfs;
 #undef EXT3FS_DEBUG
 
 /*
- * Define EXT3_RESERVATION to reserve data blocks for expanding files
+ * Define EXT3_PREALLOCATE to preallocate data blocks for expanding files
  */
-#define EXT3_DEFAULT_RESERVE_BLOCKS     8
-#define EXT3_MAX_RESERVE_BLOCKS         1024
+#undef  EXT3_PREALLOCATE /* @@@ Fix this! */
+#define EXT3_DEFAULT_PREALLOC_BLOCKS   8
+
 /*
  * Always enable hashed directories
  */
@@ -194,32 +195,6 @@ struct ext3_group_desc
  */
 #define EXT3_STATE_JDATA               0x00000001 /* journaled data exists */
 #define EXT3_STATE_NEW                 0x00000002 /* inode is newly created */
-#define EXT3_STATE_RESIZE              0x00000004 /* fake inode for resizing */
-
-
-/* Used to pass group descriptor data when online resize is done */
-struct ext3_new_group_input {
-       __u32 group;            /* Group number for this data */
-       __u32 block_bitmap;     /* Absolute block number of block bitmap */
-       __u32 inode_bitmap;     /* Absolute block number of inode bitmap */
-       __u32 inode_table;      /* Absolute block number of inode table start */
-       __u32 blocks_count;     /* Total number of blocks in this group */
-       __u16 reserved_blocks;  /* Number of reserved blocks in this group */
-       __u16 unused;
-};
-
-/* The struct ext3_new_group_input in kernel space, with free_blocks_count */
-struct ext3_new_group_data {
-       __u32 group;
-       __u32 block_bitmap;
-       __u32 inode_bitmap;
-       __u32 inode_table;
-       __u32 blocks_count;
-       __u16 reserved_blocks;
-       __u16 unused;
-       __u32 free_blocks_count;
-};
-
 
 /*
  * ioctl commands
@@ -228,15 +203,11 @@ struct ext3_new_group_data {
 #define        EXT3_IOC_SETFLAGS               _IOW('f', 2, long)
 #define        EXT3_IOC_GETVERSION             _IOR('f', 3, long)
 #define        EXT3_IOC_SETVERSION             _IOW('f', 4, long)
-#define EXT3_IOC_GROUP_EXTEND          _IOW('f', 7, unsigned long)
-#define EXT3_IOC_GROUP_ADD             _IOW('f', 8,struct ext3_new_group_input)
 #define        EXT3_IOC_GETVERSION_OLD         _IOR('v', 1, long)
 #define        EXT3_IOC_SETVERSION_OLD         _IOW('v', 2, long)
 #ifdef CONFIG_JBD_DEBUG
 #define EXT3_IOC_WAIT_FOR_READONLY     _IOR('f', 99, long)
 #endif
-#define EXT3_IOC_GETRSVSZ              _IOR('r', 1, long)
-#define EXT3_IOC_SETRSVSZ              _IOW('r', 2, long)
 
 /*
  * Structure of an inode on the disk
@@ -335,25 +306,24 @@ struct ext3_inode {
 /*
  * Mount flags
  */
-#define EXT3_MOUNT_CHECK               0x00001 /* Do mount-time checks */
-#define EXT3_MOUNT_OLDALLOC            0x00002  /* Don't use the new Orlov allocator */
-#define EXT3_MOUNT_GRPID               0x00004 /* Create files with directory's group */
-#define EXT3_MOUNT_DEBUG               0x00008 /* Some debugging messages */
-#define EXT3_MOUNT_ERRORS_CONT         0x00010 /* Continue on errors */
-#define EXT3_MOUNT_ERRORS_RO           0x00020 /* Remount fs ro on errors */
-#define EXT3_MOUNT_ERRORS_PANIC                0x00040 /* Panic on errors */
-#define EXT3_MOUNT_MINIX_DF            0x00080 /* Mimics the Minix statfs */
-#define EXT3_MOUNT_NOLOAD              0x00100 /* Don't use existing journal*/
-#define EXT3_MOUNT_ABORT               0x00200 /* Fatal error detected */
-#define EXT3_MOUNT_DATA_FLAGS          0x00C00 /* Mode for data writes: */
-#define EXT3_MOUNT_JOURNAL_DATA                0x00400 /* Write data to journal */
-#define EXT3_MOUNT_ORDERED_DATA                0x00800 /* Flush data before commit */
-#define EXT3_MOUNT_WRITEBACK_DATA      0x00C00 /* No data ordering */
-#define EXT3_MOUNT_UPDATE_JOURNAL      0x01000 /* Update the journal format */
-#define EXT3_MOUNT_NO_UID32            0x02000  /* Disable 32-bit UIDs */
-#define EXT3_MOUNT_XATTR_USER          0x04000 /* Extended user attributes */
-#define EXT3_MOUNT_POSIX_ACL           0x08000 /* POSIX Access Control Lists */
-#define EXT3_MOUNT_RESERVATION         0x10000 /* Preallocation */
+#define EXT3_MOUNT_CHECK               0x0001  /* Do mount-time checks */
+#define EXT3_MOUNT_OLDALLOC            0x0002  /* Don't use the new Orlov allocator */
+#define EXT3_MOUNT_GRPID               0x0004  /* Create files with directory's group */
+#define EXT3_MOUNT_DEBUG               0x0008  /* Some debugging messages */
+#define EXT3_MOUNT_ERRORS_CONT         0x0010  /* Continue on errors */
+#define EXT3_MOUNT_ERRORS_RO           0x0020  /* Remount fs ro on errors */
+#define EXT3_MOUNT_ERRORS_PANIC                0x0040  /* Panic on errors */
+#define EXT3_MOUNT_MINIX_DF            0x0080  /* Mimics the Minix statfs */
+#define EXT3_MOUNT_NOLOAD              0x0100  /* Don't use existing journal*/
+#define EXT3_MOUNT_ABORT               0x0200  /* Fatal error detected */
+#define EXT3_MOUNT_DATA_FLAGS          0x0C00  /* Mode for data writes: */
+  #define EXT3_MOUNT_JOURNAL_DATA      0x0400  /* Write data to journal */
+  #define EXT3_MOUNT_ORDERED_DATA      0x0800  /* Flush data before commit */
+  #define EXT3_MOUNT_WRITEBACK_DATA    0x0C00  /* No data ordering */
+#define EXT3_MOUNT_UPDATE_JOURNAL      0x1000  /* Update the journal format */
+#define EXT3_MOUNT_NO_UID32            0x2000  /* Disable 32-bit UIDs */
+#define EXT3_MOUNT_XATTR_USER          0x4000  /* Extended user attributes */
+#define EXT3_MOUNT_POSIX_ACL           0x8000  /* POSIX Access Control Lists */
 
 /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
 #ifndef _LINUX_EXT2_FS_H
@@ -447,7 +417,7 @@ struct ext3_super_block {
         */
        __u8    s_prealloc_blocks;      /* Nr of blocks to try to preallocate*/
        __u8    s_prealloc_dir_blocks;  /* Nr to preallocate for dirs */
-       __u16   s_reserved_gdt_blocks;  /* Per group desc for online growth */  
+       __u16   s_padding1;
        /*
         * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set.
         */
@@ -710,7 +680,8 @@ struct dir_private_info {
 /* balloc.c */
 extern int ext3_bg_has_super(struct super_block *sb, int group);
 extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group);
-extern int ext3_new_block (handle_t *, struct inode *, unsigned long, int *);
+extern int ext3_new_block (handle_t *, struct inode *, unsigned long,
+                                           __u32 *, __u32 *, int *);
 extern void ext3_free_blocks (handle_t *, struct inode *, unsigned long,
                              unsigned long);
 extern unsigned long ext3_count_free_blocks (struct super_block *);
@@ -758,7 +729,6 @@ extern void ext3_put_inode (struct inode *);
 extern void ext3_delete_inode (struct inode *);
 extern int  ext3_sync_inode (handle_t *, struct inode *);
 extern void ext3_discard_prealloc (struct inode *);
-extern void ext3_discard_reservation (struct inode *);
 extern void ext3_dirty_inode(struct inode *);
 extern int ext3_change_inode_journal_flag(struct inode *, int);
 extern void ext3_truncate (struct inode *);
@@ -774,13 +744,6 @@ extern int ext3_orphan_add(handle_t *, struct inode *);
 extern int ext3_orphan_del(handle_t *, struct inode *);
 extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
                                __u32 start_minor_hash, __u32 *next_hash);
-                               
-/* resize.c */                         
-extern int ext3_group_add(struct super_block *sb,
-                               struct ext3_new_group_data *input);
-extern int ext3_group_extend(struct super_block *sb,
-                               struct ext3_super_block *es,
-                               unsigned long n_blocks_count);                          
 
 /* super.c */
 extern void ext3_error (struct super_block *, const char *, const char *, ...)
index 422fd51..7451cdc 100644 (file)
 
 #include <linux/rwsem.h>
 
-struct reserve_window {
-       struct list_head        rsv_list;
-       __u32                   rsv_start;
-       __u32                   rsv_end;
-       atomic_t                rsv_goal_size;
-       __u32                   rsv_alloc_hit;
-};
-
 /*
- * third extended file system inode data in memory
+ * second extended file system inode data in memory
  */
 struct ext3_inode_info {
        __u32   i_data[15];
@@ -65,9 +57,10 @@ struct ext3_inode_info {
         * allocation when we detect linearly ascending requests.
         */
        __u32   i_next_alloc_goal;
-       /* block reservation window */
-       struct reserve_window i_rsv_window;
-
+#ifdef EXT3_PREALLOCATE
+       __u32   i_prealloc_block;
+       __u32   i_prealloc_count;
+#endif
        __u32   i_dir_start_lookup;
 #ifdef CONFIG_EXT3_FS_XATTR
        /*
index 1c3294d..8ed3cf7 100644 (file)
@@ -59,10 +59,6 @@ struct ext3_sb_info {
        struct percpu_counter s_dirs_counter;
        struct blockgroup_lock s_blockgroup_lock;
 
-       /* head of the per fs reservation window tree */
-       spinlock_t s_rsv_window_lock;
-       struct reserve_window s_rsv_window_head;
-
        /* Journaling */
        struct inode * s_journal_inode;
        struct journal_s * s_journal;
index 84f0fe1..cc7f14f 100644 (file)
@@ -125,7 +125,8 @@ struct fb_fix_screeninfo {
        unsigned long mmio_start;       /* Start of Memory Mapped I/O   */
                                        /* (physical address) */
        __u32 mmio_len;                 /* Length of Memory Mapped I/O  */
-       __u32 accel;                    /* Type of acceleration available */
+       __u32 accel;                    /* Indicate to driver which     */
+                                       /*  specific chip/card we have  */
        __u16 reserved[3];              /* Reserved for future compatibility */
 };
 
@@ -154,7 +155,7 @@ struct fb_bitfield {
 #define FB_ACTIVATE_ALL               64       /* change all VCs on this fb    */
 #define FB_ACTIVATE_FORCE     128      /* force apply even when no change*/
 
-#define FB_ACCELF_TEXT         1       /* text mode acceleration */
+#define FB_ACCELF_TEXT         1       /* (OBSOLETE) see fb_info.flags and vc_mode */
 
 #define FB_SYNC_HOR_HIGH_ACT   1       /* horizontal sync high active  */
 #define FB_SYNC_VERT_HIGH_ACT  2       /* vertical sync high active    */
@@ -200,7 +201,7 @@ struct fb_var_screeninfo {
        __u32 height;                   /* height of picture in mm    */
        __u32 width;                    /* width of picture in mm     */
 
-       __u32 accel_flags;              /* acceleration flags (hints)   */
+       __u32 accel_flags;              /* (OBSOLETE) see fb_info.flags */
 
        /* Timing: All values in pixclocks, except pixclock (of course) */
        __u32 pixclock;                 /* pixel clock in ps (pico seconds) */
@@ -375,7 +376,7 @@ struct fb_cursor {
        __u16 set;              /* what to set */
        __u16 enable;           /* cursor on/off */
        __u16 rop;              /* bitop operation */
-       char *mask;             /* cursor mask bits */
+       const char *mask;       /* cursor mask bits */
        struct fbcurpos hot;    /* cursor hot spot */
        struct fb_image image;  /* Cursor image */
 };
@@ -458,8 +459,8 @@ struct fb_ops {
        /* For framebuffers with strange non linear layouts or that do not
         * work with normal memory mapped access
         */
-       ssize_t (*fb_read)(struct file *file, char *buf, size_t count, loff_t *ppos);
-       ssize_t (*fb_write)(struct file *file, const char *buf, size_t count, loff_t *ppos);
+       ssize_t (*fb_read)(struct file *file, char __user *buf, size_t count, loff_t *ppos);
+       ssize_t (*fb_write)(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
 
        /* checks var and eventually tweaks it to something supported,
         * DO NOT MODIFY PAR */
@@ -502,10 +503,37 @@ struct fb_ops {
        int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
 };
 
+/* FBINFO_* = fb_info.flags bit flags */
+#define FBINFO_MODULE          0x0001  /* Low-level driver is a module */
+#define FBINFO_HWACCEL_DISABLED        0x0002
+       /* When FBINFO_HWACCEL_DISABLED is set:
+        *  Hardware acceleration is turned off.  Software implementations
+        *  of required functions (copyarea(), fillrect(), and imageblit())
+        *  takes over; acceleration engine should be in a quiescent state */
+
+/* hints */
+#define FBINFO_PARTIAL_PAN_OK  0x0040 /* otw use pan only for double-buffering */
+#define FBINFO_READS_FAST      0x0080 /* soft-copy faster than rendering */
+
+/* hardware supported ops */
+/*  semantics: when a bit is set, it indicates that the operation is
+ *   accelerated by hardware.
+ *  required functions will still work even if the bit is not set.
+ *  optional functions may not even exist if the flag bit is not set.
+ */
+#define FBINFO_HWACCEL_NONE            0x0000
+#define FBINFO_HWACCEL_COPYAREA                0x0100 /* required */
+#define FBINFO_HWACCEL_FILLRECT                0x0200 /* required */
+#define FBINFO_HWACCEL_IMAGEBLIT       0x0400 /* required */
+#define FBINFO_HWACCEL_ROTATE          0x0800 /* optional */
+#define FBINFO_HWACCEL_XPAN            0x1000 /* optional */
+#define FBINFO_HWACCEL_YPAN            0x2000 /* optional */
+#define FBINFO_HWACCEL_YWRAP           0x4000 /* optional */
+
+
 struct fb_info {
        int node;
        int flags;
-#define FBINFO_FLAG_MODULE     1       /* Low-level driver is a module */
        struct fb_var_screeninfo var;   /* Current var */
        struct fb_fix_screeninfo fix;   /* Current fix */
        struct fb_monspecs monspecs;    /* Current Monitor specs */
@@ -527,11 +555,23 @@ struct fb_info {
 };
 
 #ifdef MODULE
-#define FBINFO_FLAG_DEFAULT    FBINFO_FLAG_MODULE
+#define FBINFO_DEFAULT FBINFO_MODULE
 #else
-#define FBINFO_FLAG_DEFAULT    0
+#define FBINFO_DEFAULT 0
 #endif
 
+// This will go away
+#define FBINFO_FLAG_MODULE     FBINFO_MODULE
+#define FBINFO_FLAG_DEFAULT    FBINFO_DEFAULT
+
+/* This will go away
+ * fbset currently hacks in FB_ACCELF_TEXT into var.accel_flags
+ * when it wants to turn the acceleration engine on.  This is
+ * really a separate operation, and should be modified via sysfs.
+ *  But for now, we leave it broken with the following define
+ */
+#define STUPID_ACCELF_TEXT_SHIT
+
 // This will go away
 #if defined(__sparc__)
 
index cbbd0f8..7ce5f01 100644 (file)
@@ -339,7 +339,7 @@ struct floppy_raw_cmd {
 #define FD_RAW_FAILURE 0x10000 /* command sent to fdc, fdc returned error */
 #define FD_RAW_HARDFAILURE 0x20000 /* fdc had to be reset, or timed out */
 
-       void *data;
+       void __user *data;
        char *kernel_data; /* location of data buffer in the kernel */
        struct floppy_raw_cmd *next; /* used for chaining of raw cmd's 
                                      * within the kernel */
index bfbb745..e5234d8 100644 (file)
@@ -5,6 +5,8 @@
 #ifndef __LINUX_FILTER_H__
 #define __LINUX_FILTER_H__
 
+#include <linux/compiler.h>
+
 /*
  * Current version of the filter code architecture.
  */
@@ -27,7 +29,7 @@ struct sock_filter    /* Filter block */
 struct sock_fprog      /* Required for SO_ATTACH_FILTER. */
 {
        unsigned short          len;    /* Number of filter blocks */
-       struct sock_filter      *filter;
+       struct sock_filter __user *filter;
 };
 
 #ifdef __KERNEL__
index 3098500..ae45deb 100644 (file)
@@ -12,7 +12,7 @@ static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
        return vma->vm_flags & VM_HUGETLB;
 }
 
-int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void *, size_t *);
+int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *);
 int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
 int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int);
 void zap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
index 2390365..9104dd4 100644 (file)
@@ -99,6 +99,7 @@ struct i2o_controller
        int             irq;
        int             short_req:1;    /* Use small block sizes        */
        int             dpt:1;          /* Don't quiesce                */
+       int             raptor:1;       /* split bar                    */
        int             promise:1;      /* Promise controller           */
 #ifdef CONFIG_MTRR
        int             mtrr_reg0;
@@ -109,9 +110,9 @@ struct i2o_controller
        atomic_t users;
        struct i2o_device *devices;             /* I2O device chain */
        struct i2o_controller *next;            /* Controller chain */
-       unsigned long post_port;                /* Inbout port address */
-       unsigned long reply_port;               /* Outbound port address */
-       unsigned long irq_mask;                 /* Interrupt register address */
+       void *post_port;                        /* Inbout port address */
+       void *reply_port;                       /* Outbound port address */
+       void *irq_mask;                         /* Interrupt register address */
 
        /* Dynamic LCT related data */
        struct semaphore lct_sem;
@@ -128,8 +129,11 @@ struct i2o_controller
        dma_addr_t hrt_phys;
        u32 hrt_len;
 
-       unsigned long mem_offset;               /* MFA offset */
-       unsigned long mem_phys;                 /* MFA physical */
+       void *base_virt;                        /* base virtual address */
+       unsigned long base_phys;                /* base physical address */
+
+       void *msg_virt;                         /* messages virtual address */
+       unsigned long msg_phys;                 /* messages physical address */
 
        int battery:1;                          /* Has a battery backup */
        int io_alloc:1;                         /* An I/O resource was allocated */
index 8a773de..5ae1656 100644 (file)
@@ -255,7 +255,7 @@ typedef enum {      ide_unknown,    ide_generic,    ide_pci,
                ide_pdc4030,    ide_rz1000,     ide_trm290,
                ide_cmd646,     ide_cy82c693,   ide_4drives,
                ide_pmac,       ide_etrax100,   ide_acorn,
-               ide_pc9800,     ide_forced
+               ide_forced
 } hwif_chipset_t;
 
 /*
@@ -690,7 +690,6 @@ typedef union {
 typedef enum {
        ide_stopped,    /* no drive operation was started */
        ide_started,    /* a drive operation was started, handler was set */
-       ide_released,   /* as ide_started, but bus also released */
 } ide_startstop_t;
 
 struct ide_driver_s;
@@ -724,7 +723,6 @@ typedef struct ide_drive_s {
        u8      keep_settings;          /* restore settings after drive reset */
        u8      autodma;                /* device can safely use dma on host */
        u8      using_dma;              /* disk is using dma for read/write */
-       u8      using_tcq;              /* disk is using queueing */
        u8      retry_pio;              /* retrying dma capable host in pio */
        u8      state;                  /* retry state */
        u8      waiting_for_dma;        /* dma currently in progress */
@@ -751,6 +749,7 @@ typedef struct ide_drive_s {
        unsigned remap_0_to_1   : 1;    /* 0=noremap, 1=remap 0->1 (for EZDrive) */
        unsigned blocked        : 1;    /* 1=powermanagment told us not to do anything, so sleep nicely */
        unsigned vdma           : 1;    /* 1=doing PIO over DMA 0=doing normal DMA */
+       unsigned stroke         : 1;    /* from:  hdx=stroke */
        unsigned addressing;            /*      : 3;
                                         *  0=28-bit
                                         *  1=48-bit
@@ -781,7 +780,6 @@ typedef struct ide_drive_s {
        u8      sect;           /* "real" sectors per track */
        u8      bios_head;      /* BIOS/fdisk/LILO number of heads */
        u8      bios_sect;      /* BIOS/fdisk/LILO sectors per track */
-       u8      queue_depth;    /* max queue depth */
 
        unsigned int    bios_cyl;       /* BIOS/fdisk/LILO number of cyls */
        unsigned int    cyl;            /* "real" number of cyls */
@@ -1095,7 +1093,6 @@ typedef struct ide_settings_s {
 
 extern struct semaphore ide_setting_sem;
 extern int ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set);
-extern void ide_remove_setting(ide_drive_t *drive, char *name);
 extern ide_settings_t *ide_find_setting_by_name(ide_drive_t *drive, char *name);
 extern int ide_read_setting(ide_drive_t *t, ide_settings_t *setting);
 extern int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int val);
@@ -1116,7 +1113,6 @@ extern struct proc_dir_entry *proc_ide_root;
 
 extern void proc_ide_create(void);
 extern void proc_ide_destroy(void);
-extern void destroy_proc_ide_device(ide_hwif_t *, ide_drive_t *);
 extern void destroy_proc_ide_drives(ide_hwif_t *);
 extern void create_proc_ide_interfaces(void);
 extern void ide_add_proc_entries(struct proc_dir_entry *, ide_proc_entry_t *, void *);
@@ -1359,6 +1355,8 @@ extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t);
  */
 extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
 
+extern void try_to_flush_leftover_data(ide_drive_t *);
+
 /*
  * Issue ATA command and wait for completion.
  * Use for implementing commands in kernel
@@ -1622,14 +1620,6 @@ extern int __ide_dma_lostirq(ide_drive_t *);
 extern int __ide_dma_timeout(ide_drive_t *);
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-extern int __ide_dma_queued_on(ide_drive_t *drive);
-extern int __ide_dma_queued_off(ide_drive_t *drive);
-extern ide_startstop_t __ide_dma_queued_read(ide_drive_t *drive);
-extern ide_startstop_t __ide_dma_queued_write(ide_drive_t *drive);
-extern ide_startstop_t __ide_dma_queued_start(ide_drive_t *drive);
-#endif
-
 #else
 static inline int __ide_dma_off(ide_drive_t *drive) { return 0; }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
@@ -1698,28 +1688,6 @@ extern struct semaphore ide_cfg_sem;
 
 #define local_irq_set(flags)   do { local_save_flags((flags)); local_irq_enable(); } while (0)
 
-#define IDE_MAX_TAG    32
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-static inline int ata_pending_commands(ide_drive_t *drive)
-{
-       if (drive->using_tcq)
-               return blk_queue_tag_depth(drive->queue);
-
-       return 0;
-}
-
-static inline int ata_can_queue(ide_drive_t *drive)
-{
-       if (drive->using_tcq)
-               return blk_queue_tag_queue(drive->queue);
-
-       return 1;
-}
-#else
-#define ata_pending_commands(drive)    (0)
-#define ata_can_queue(drive)           (1)
-#endif
-
 extern struct bus_type ide_bus_type;
 
 #endif /* _IDE_H */
index 81439bf..8e2618e 100644 (file)
 #include <linux/types.h>
 #include <asm/bitops.h>
 
-#define RESERVED_ID_BITS 8
-
 #if BITS_PER_LONG == 32
 # define IDR_BITS 5
 # define IDR_FULL 0xfffffffful
+/* We can only use two of the bits in the top level because there is
+   only one possible bit in the top level (5 bits * 7 levels = 35
+   bits, but you only use 31 bits in the id). */
+# define TOP_LEVEL_FULL (IDR_FULL >> 30)
 #elif BITS_PER_LONG == 64
 # define IDR_BITS 6
 # define IDR_FULL 0xfffffffffffffffful
+/* We can only use two of the bits in the top level because there is
+   only one possible bit in the top level (6 bits * 6 levels = 36
+   bits, but you only use 31 bits in the id). */
+# define TOP_LEVEL_FULL (IDR_FULL >> 62)
 #else
 # error "BITS_PER_LONG is not 32 or 64"
 #endif
 #define IDR_SIZE (1 << IDR_BITS)
 #define IDR_MASK ((1 << IDR_BITS)-1)
 
-/* Define the size of the id's */
-#define BITS_PER_INT (sizeof(int)*8)
-
-#define MAX_ID_SHIFT (BITS_PER_INT - RESERVED_ID_BITS)
-#define MAX_ID_BIT (1 << MAX_ID_SHIFT)
+#define MAX_ID_SHIFT (sizeof(int)*8 - 1)
+#define MAX_ID_BIT (1U << MAX_ID_SHIFT)
 #define MAX_ID_MASK (MAX_ID_BIT - 1)
 
 /* Leave the possibility of an incomplete final layer */
 #define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL
 
 struct idr_layer {
-       unsigned long            bitmap;        /* A zero bit means "space here" */
+       unsigned long            bitmap; /* A zero bit means "space here" */
        struct idr_layer        *ary[1<<IDR_BITS];
-       int                      count;         /* When zero, we can release it */
+       int                      count;  /* When zero, we can release it */
 };
 
 struct idr {
        struct idr_layer *top;
        struct idr_layer *id_free;
-       long              count;
        int               layers;
        int               id_free_cnt;
        spinlock_t        lock;
 };
 
-#define IDR_INIT(name) \
+#define IDR_INIT(name)                                         \
 {                                                              \
        .top            = NULL,                                 \
        .id_free        = NULL,                                 \
-       .count          = 0,                                    \
        .layers         = 0,                                    \
        .id_free_cnt    = 0,                                    \
        .lock           = SPIN_LOCK_UNLOCKED,                   \
@@ -71,9 +72,9 @@ struct idr {
 
 void *idr_find(struct idr *idp, int id);
 int idr_pre_get(struct idr *idp, unsigned gfp_mask);
-int idr_get_new(struct idr *idp, void *ptr);
+int idr_get_new(struct idr *idp, void *ptr, int *id);
+int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
 void idr_remove(struct idr *idp, int id);
 void idr_init(struct idr *idp);
 
 extern kmem_cache_t *idr_layer_cache;
-
index fbe0106..296a6c2 100644 (file)
@@ -147,7 +147,7 @@ struct ifreq
                struct  ifmap ifru_map;
                char    ifru_slave[IFNAMSIZ];   /* Just fits the size */
                char    ifru_newname[IFNAMSIZ];
-               char __user *   ifru_data;
+               void __user *   ifru_data;
                struct  if_settings ifru_settings;
        } ifr_ifru;
 };
@@ -182,8 +182,8 @@ struct ifconf
        int     ifc_len;                        /* size of buffer       */
        union 
        {
-               char *                  ifcu_buf;
-               struct  ifreq           *ifcu_req;
+               char __user *ifcu_buf;
+               struct ifreq __user *ifcu_req;
        } ifc_ifcu;
 };
 #define        ifc_buf ifc_ifcu.ifcu_buf               /* buffer address       */
index 7d06a31..bbf49bc 100644 (file)
@@ -86,6 +86,7 @@
 #define ARPHRD_IEEE80211_PRISM 802     /* IEEE 802.11 + Prism2 header  */
 
 #define ARPHRD_VOID      0xFFFF        /* Void type, nothing is known */
+#define ARPHRD_NONE      0xFFFE        /* zero header length */
 
 /* ARP protocol opcodes. */
 #define        ARPOP_REQUEST   1               /* ARP request                  */
index 6af157c..58d6e60 100644 (file)
@@ -104,7 +104,7 @@ struct __fdb_entry
 
 #include <linux/netdevice.h>
 
-extern void brioctl_set(int (*ioctl_hook)(unsigned int, unsigned long));
+extern void brioctl_set(int (*ioctl_hook)(unsigned int, void __user *));
 extern int (*br_handle_frame_hook)(struct sk_buff *skb);
 extern int (*br_should_route_hook)(struct sk_buff **pskb);
 
index 5059003..3c94b17 100644 (file)
@@ -191,7 +191,7 @@ struct frad_local
    int               buffer;           /* current buffer for S508 firmware */
 };
 
-extern void dlci_ioctl_set(int (*hook)(unsigned int, void *));
+extern void dlci_ioctl_set(int (*hook)(unsigned int, void __user *));
 
 #endif /* __KERNEL__ */
 
index 104df18..46d246b 100644 (file)
@@ -55,7 +55,7 @@ struct vlan_hdr {
 #define VLAN_VID_MASK  0xfff
 
 /* found in socket.c */
-extern void vlan_ioctl_set(int (*hook)(unsigned long));
+extern void vlan_ioctl_set(int (*hook)(void __user *));
 
 #define VLAN_NAME "vlan"
 
index 77ba731..b7a30bb 100644 (file)
@@ -655,7 +655,7 @@ struct ff_periodic_effect {
        struct ff_envelope envelope;
 
 /* Only used if waveform == FF_CUSTOM */
-       __u32 custom_len;       /* Number of samples  */        
+       __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 */
@@ -749,8 +749,6 @@ struct ff_effect {
 #define INPUT_KEYCODE(dev, scancode) ((dev->keycodesize == 1) ? ((u8*)dev->keycode)[scancode] : \
        ((dev->keycodesize == 2) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode])))
 
-#define init_input_dev(dev)    do { INIT_LIST_HEAD(&((dev)->h_list)); INIT_LIST_HEAD(&((dev)->node)); } while (0)
-
 #define SET_INPUT_KEYCODE(dev, scancode, val)                  \
                ({      unsigned __old;                         \
                switch (dev->keycodesize) {                     \
@@ -915,6 +913,12 @@ 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);
+}
+
 void input_register_device(struct input_dev *);
 void input_unregister_device(struct input_dev *);
 
@@ -932,14 +936,51 @@ int input_flush_device(struct input_handle* handle, struct file* file);
 
 void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
 
-#define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c))
-#define input_report_rel(a,b,c) input_event(a, EV_REL, b, c)
-#define input_report_abs(a,b,c) input_event(a, EV_ABS, b, c)
-#define input_report_ff(a,b,c) input_event(a, EV_FF, b, c)
-#define input_report_ff_status(a,b,c)  input_event(a, EV_FF_STATUS, b, c)
-
-#define input_regs(a,b)                do { (a)->regs = (b); } while (0)
-#define input_sync(a)          do { input_event(a, EV_SYN, SYN_REPORT, 0); (a)->regs = NULL; } while (0)
+static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
+{
+       input_event(dev, EV_KEY, code, !!value);
+}
+
+static inline void input_report_rel(struct input_dev *dev, unsigned int code, int value)
+{
+       input_event(dev, EV_REL, code, value);
+}
+
+static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)
+{
+       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);
+}
+
+static inline void input_regs(struct input_dev *dev, struct pt_regs *regs)
+{
+       dev->regs = regs;
+}
+
+static inline void input_sync(struct input_dev *dev)
+{
+       input_event(dev, EV_SYN, SYN_REPORT, 0);
+       dev->regs = NULL;
+}
+
+static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat)
+{
+       dev->absmin[axis] = min;
+       dev->absmax[axis] = max;
+       dev->absfuzz[axis] = fuzz;
+       dev->absflat[axis] = flat;
+
+       dev->absbit[LONG(axis)] |= BIT(axis);
+}
 
 extern struct class_simple *input_class;
 
index 75311f2..91e49f8 100644 (file)
@@ -372,6 +372,16 @@ int ipmi_request_supply_msgs(ipmi_user_t          user,
                             struct ipmi_recv_msg *supplied_recv,
                             int                  priority);
 
+/*
+ * Do polling on the IPMI interface the user is attached to.  This
+ * causes the IPMI code to do an immediate check for information from
+ * the driver and handle anything that is immediately pending.  This
+ * will not block in anyway.  This is useful if you need to implement
+ * polling from the user like you need to send periodic watchdog pings
+ * from a crash dump, or something like that.
+ */
+void ipmi_poll_interface(ipmi_user_t user);
+
 /*
  * When commands come in to the SMS, the user can register to receive
  * them.  Only one user can be listening on a specific netfn/cmd pair
@@ -488,7 +498,7 @@ int ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2);
 /* Messages sent to the interface are this format. */
 struct ipmi_req
 {
-       unsigned char *addr; /* Address to send the message to. */
+       unsigned char __user *addr; /* Address to send the message to. */
        unsigned int  addr_len;
 
        long    msgid; /* The sequence number for the message.  This
@@ -539,7 +549,7 @@ struct ipmi_recv
        int     recv_type; /* Is this a command, response or an
                              asyncronous event. */
 
-       unsigned char *addr;    /* Address the message was from is put
+       unsigned char __user *addr;    /* Address the message was from is put
                                   here.  The caller must supply the
                                   memory. */
        unsigned int  addr_len; /* The size of the address buffer.
index 40ed591..03e05d5 100644 (file)
@@ -71,6 +71,7 @@
 
 #define IPMI_CC_NO_ERROR               0x00
 #define IPMI_NODE_BUSY_ERR             0xc0
+#define IPMI_INVALID_COMMAND_ERR       0xc1
 #define IPMI_ERR_MSG_TRUNCATED         0xc6
 #define IPMI_LOST_ARBITRATION_ERR      0x81
 #define IPMI_ERR_UNSPECIFIED           0xff
index 6b42943..88dd374 100644 (file)
@@ -100,6 +100,10 @@ struct ipmi_smi_handlers
           out and that none are pending, and any new requests are run
           to completion immediately. */
        void (*set_run_to_completion)(void *send_info, int run_to_completion);
+
+       /* Called to poll for work to do.  This is so upper layers can
+          poll for operations during things like crash dumps. */
+       void (*poll)(void *send_info);
 };
 
 /* Add a low-level interface to the IPMI driver. */
index e98637f..ccc084d 100644 (file)
@@ -192,6 +192,8 @@ struct inet6_skb_parm
        __u16                   dst1;
 };
 
+#define IP6CB(skb)     ((struct inet6_skb_parm*)((skb)->cb))
+
 struct ipv6_pinfo {
        struct in6_addr         saddr;
        struct in6_addr         rcv_saddr;
index 223f161..15b07d3 100644 (file)
@@ -231,9 +231,69 @@ extern struct dentry *isofs_lookup(struct inode *, struct dentry *, struct namei
 extern struct buffer_head *isofs_bread(struct inode *, sector_t);
 extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long);
 
+extern struct inode *isofs_iget(struct super_block *sb,
+                                unsigned long block,
+                                unsigned long offset);
+
+/* Because the inode number is no longer relevant to finding the
+ * underlying meta-data for an inode, we are free to choose a more
+ * convenient 32-bit number as the inode number.  The inode numbering
+ * scheme was recommended by Sergey Vlasov and Eric Lammerts. */
+static inline unsigned long isofs_get_ino(unsigned long block,
+                                         unsigned long offset,
+                                         unsigned long bufbits)
+{
+       return (block << (bufbits - 5)) | (offset >> 5);
+}
+
+/* Every directory can have many redundant directory entries scattered
+ * throughout the directory tree.  First there is the directory entry
+ * with the name of the directory stored in the parent directory.
+ * Then, there is the "." directory entry stored in the directory
+ * itself.  Finally, there are possibly many ".." directory entries
+ * stored in all the subdirectories.
+ *
+ * In order for the NFS get_parent() method to work and for the
+ * general consistency of the dcache, we need to make sure the
+ * "i_iget5_block" and "i_iget5_offset" all point to exactly one of
+ * the many redundant entries for each directory.  We normalize the
+ * block and offset by always making them point to the "."  directory.
+ *
+ * Notice that we do not use the entry for the directory with the name
+ * that is located in the parent directory.  Even though choosing this
+ * first directory is more natural, it is much easier to find the "."
+ * entry in the NFS get_parent() method because it is implicitly
+ * encoded in the "extent + ext_attr_length" fields of _all_ the
+ * redundant entries for the directory.  Thus, it can always be
+ * reached regardless of which directory entry you have in hand.
+ *
+ * This works because the "." entry is simply the first directory
+ * record when you start reading the file that holds all the directory
+ * records, and this file starts at "extent + ext_attr_length" blocks.
+ * Because the "." entry is always the first entry listed in the
+ * directories file, the normalized "offset" value is always 0.
+ *
+ * You should pass the directory entry in "de".  On return, "block"
+ * and "offset" will hold normalized values.  Only directories are
+ * affected making it safe to call even for non-directory file
+ * types. */
+static void inline
+isofs_normalize_block_and_offset(struct iso_directory_record* de,
+                                unsigned long *block,
+                                unsigned long *offset)
+{
+       /* Only directories are normalized. */
+       if (de->flags[0] & 2) {
+               *offset = 0;
+               *block = (unsigned long)isonum_733(de->extent)
+                       + (unsigned long)isonum_711(de->ext_attr_length);
+       }
+}
+
 extern struct inode_operations isofs_dir_inode_operations;
 extern struct file_operations isofs_dir_operations;
 extern struct address_space_operations isofs_symlink_aops;
+extern struct export_operations isofs_export_ops;
 
 /* The following macros are used to check for memory leaks. */
 #ifdef LEAK_CHECK
index 01a1ae2..59065e9 100644 (file)
@@ -13,10 +13,13 @@ enum isofs_file_format {
  * iso fs inode data in memory
  */
 struct iso_inode_info {
+       unsigned long i_iget5_block;
+       unsigned long i_iget5_offset;
        unsigned int i_first_extent;
        unsigned char i_file_format;
        unsigned char i_format_parm[3];
-       unsigned long i_next_section_ino;
+       unsigned long i_next_section_block;
+       unsigned long i_next_section_offset;
        off_t i_section_size;
        struct inode vfs_inode;
 };
index 81e314d..8812116 100644 (file)
@@ -350,7 +350,7 @@ typedef enum {
 typedef struct {
        int elements_used;
        IXJ_CADENCE_TERM termination;
-       IXJ_CADENCE_ELEMENT *ce;
+       IXJ_CADENCE_ELEMENT __user *ce;
 } IXJ_CADENCE;
 
 #define IXJCTL_TONE_CADENCE            _IOW ('q', 0xCA, IXJ_CADENCE *)
index 7c5af18..a484f52 100644 (file)
@@ -23,6 +23,8 @@
 #include <linux/errno.h>
 #include <linux/compiler.h>
 
+#define KMOD_PATH_LEN 256
+
 #ifdef CONFIG_KMOD
 /* modprobe exit status on success, -ve on error.  Return value
  * usually useless though. */
index 554bbcf..a80124c 100644 (file)
@@ -12,7 +12,9 @@
 #include <linux/device.h>
 
 /* get the platform specific defines */
+#ifdef CONFIG_MCA
 #include <asm/mca.h>
+#endif
 
 /* The detection of MCA bus is done in the real mode (using BIOS).
  * The information is exported to the protected code, where this
index 2aeecaf..775c415 100644 (file)
@@ -153,6 +153,9 @@ void mpol_free_shared_policy(struct shared_policy *p);
 struct mempolicy *mpol_shared_policy_lookup(struct shared_policy *sp,
                                            unsigned long idx);
 
+extern void numa_default_policy(void);
+extern void numa_policy_init(void);
+
 #else
 
 struct mempolicy {};
@@ -215,6 +218,14 @@ mpol_shared_policy_lookup(struct shared_policy *sp, unsigned long idx)
 #define vma_policy(vma) NULL
 #define vma_set_policy(vma, pol) do {} while(0)
 
+static inline void numa_policy_init(void)
+{
+}
+
+static inline void numa_default_policy(void)
+{
+}
+
 #endif /* CONFIG_NUMA */
 #endif /* __KERNEL__ */
 
index 9a57996..c87b17f 100644 (file)
@@ -9,6 +9,7 @@
 #define __LINUX_MII_H__
 
 #include <linux/types.h>
+#include <linux/if.h>
 
 /* Generic MII registers. */
 
@@ -144,6 +145,12 @@ struct mii_ioctl_data {
 };
 
 
+static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
+{
+       return (struct mii_ioctl_data *) &rq->ifr_ifru;
+}
+
+
 /**
  * mii_nway_result
  * @negotiated: value of MII ANAR and'd with ANLPAR
index fe5dae1..647bed4 100644 (file)
@@ -33,6 +33,7 @@
 #define SGI_STREAMS_KEYBOARD 150
 /* drivers/sgi/char/usema.c */
 #define SGI_USEMACLONE      151
+#define        HPET_MINOR           152
 
 #define TUN_MINOR           200
 
index cf78dd6..016cb78 100644 (file)
@@ -495,19 +495,9 @@ int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *new);
 struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
                                        unsigned long addr);
 struct file *shmem_file_setup(char * name, loff_t size, unsigned long flags);
-int shmem_lock(struct file * file, int lock);
+void shmem_lock(struct file * file, int lock);
 int shmem_zero_setup(struct vm_area_struct *);
 
-static inline int can_do_mlock(void)
-{
-       if (capable(CAP_IPC_LOCK))
-               return 1;
-       if (current->rlim[RLIMIT_MEMLOCK].rlim_cur != 0)
-               return 1;
-       return 0;
-}
-
-
 /*
  * Parameter block passed down to zap_pte_range in exceptional cases.
  */
index fc40b77..8db9d75 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/types.h>
 
 #define MQ_PRIO_MAX    32768
+/* per-uid limit of kernel memory used by mqueue, in bytes */
+#define MQ_BYTES_MAX   819200
 
 struct mq_attr {
        long    mq_flags;       /* message queue flags                  */
index e11cd45..e05d54a 100644 (file)
@@ -130,7 +130,7 @@ struct igmpmsg
 
 extern int ip_mroute_setsockopt(struct sock *, int, char __user *, int);
 extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
-extern int ipmr_ioctl(struct sock *sk, int cmd, unsigned long arg);
+extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
 extern void ip_mr_init(void);
 
 
index d2c25ff..a55f97a 100644 (file)
@@ -943,7 +943,7 @@ extern int          weight_p;
 extern unsigned long   netdev_fc_xoff;
 extern atomic_t netdev_dropping;
 extern int             netdev_set_master(struct net_device *dev, struct net_device *master);
-extern struct sk_buff * skb_checksum_help(struct sk_buff *skb);
+extern int skb_checksum_help(struct sk_buff **pskb, int inward);
 #ifdef CONFIG_NET_FASTROUTE
 extern int             netdev_fastroute;
 extern int             netdev_fastroute_obstacles;
index 1de5c77..b20c792 100644 (file)
@@ -171,6 +171,12 @@ extern void nf_reinject(struct sk_buff *skb,
                        struct nf_info *info,
                        unsigned int verdict);
 
+extern inline struct ipt_target *
+ipt_find_target_lock(const char *name, int *error, struct semaphore *mutex);
+extern inline struct ip6t_target *
+ip6t_find_target_lock(const char *name, int *error, struct semaphore *mutex);
+extern inline struct arpt_target *
+arpt_find_target_lock(const char *name, int *error, struct semaphore *mutex);
 extern void (*ip_ct_attach)(struct sk_buff *, struct nf_ct_info *);
 
 #ifdef CONFIG_NETFILTER_DEBUG
index d951537..78c4f71 100644 (file)
@@ -205,7 +205,7 @@ struct arpt_replace
        /* Number of counters (must be equal to current number of entries). */
        unsigned int num_counters;
        /* The old entries' counters. */
-       struct arpt_counters *counters;
+       struct arpt_counters __user *counters;
 
        /* The entries (hang off end: not really an array). */
        struct arpt_entry entries[0];
index fb557e4..f43f1dd 100644 (file)
@@ -252,7 +252,7 @@ struct ipt_replace
        /* Number of counters (must be equal to current number of entries). */
        unsigned int num_counters;
        /* The old entries' counters. */
-       struct ipt_counters *counters;
+       struct ipt_counters __user *counters;
 
        /* The entries (hang off end: not really an array). */
        struct ipt_entry entries[0];
@@ -283,6 +283,8 @@ struct ipt_get_entries
        struct ipt_entry entrytable[0];
 };
 
+extern struct semaphore ipt_mutex;
+
 /* Standard return verdict, or do jump. */
 #define IPT_STANDARD_TARGET ""
 /* Error verdict. */
@@ -334,6 +336,7 @@ ipt_get_target(struct ipt_entry *e)
 /*
  *     Main firewall chains definitions and global var's definitions.
  */
+static DECLARE_MUTEX(ipt_mutex);
 #ifdef __KERNEL__
 
 #include <linux/init.h>
@@ -406,6 +409,11 @@ struct ipt_target
        struct module *me;
 };
 
+extern struct ipt_target *
+ipt_find_target_lock(const char *name, int *error, struct semaphore *mutex);
+extern struct arpt_target *
+arpt_find_target_lock(const char *name, int *error, struct semaphore *mutex);
+
 extern int ipt_register_target(struct ipt_target *target);
 extern void ipt_unregister_target(struct ipt_target *target);
 
index 3b6ac20..a099527 100644 (file)
@@ -106,6 +106,8 @@ struct ip6t_counters
        u_int64_t pcnt, bcnt;                   /* Packet and byte counters */
 };
 
+static DECLARE_MUTEX(ip6t_mutex);
+
 /* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */
 #define IP6T_F_PROTO           0x01    /* Set if rule cares about upper 
                                           protocols */
@@ -258,7 +260,7 @@ struct ip6t_replace
        /* Number of counters (must be equal to current number of entries). */
        unsigned int num_counters;
        /* The old entries' counters. */
-       struct ip6t_counters *counters;
+       struct ip6t_counters __user *counters;
 
        /* The entries (hang off end: not really an array). */
        struct ip6t_entry entries[0];
index 9a782c2..26b4c83 100644 (file)
@@ -20,7 +20,7 @@
 
 struct nfs_string {
        unsigned int len;
-       const char* data;
+       const char __user * data;
 };
 
 struct nfs4_mount_data {
@@ -45,14 +45,14 @@ struct nfs4_mount_data {
        struct nfs_string hostname;             /* 1 */
        /* Server IP address */
        unsigned int host_addrlen;              /* 1 */
-       struct sockaddr* host_addr;             /* 1 */
+       struct sockaddr __user * host_addr;     /* 1 */
 
        /* Transport protocol to use */
        int proto;                              /* 1 */
 
        /* Pseudo-flavours to use for authentication. See RFC2623 */
        int auth_flavourlen;                    /* 1 */
-       int *auth_flavours;                     /* 1 */
+       int __user *auth_flavours;              /* 1 */
 };
 
 /* bits in the flags field */
index 6246101..0fd3f81 100644 (file)
@@ -306,7 +306,7 @@ nfs_file_cred(struct file *file)
  */
 extern ssize_t nfs_direct_IO(int, struct kiocb *, const struct iovec *, loff_t,
                        unsigned long);
-extern ssize_t nfs_file_direct_read(struct kiocb *iocb, char *buf,
+extern ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf,
                        size_t count, loff_t pos);
 extern ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf,
                        size_t count, loff_t pos);
index b1a6f23..6bad476 100644 (file)
@@ -124,8 +124,7 @@ exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv,
                int err;
                exp_get(exp);
                expkey_put(&ek->h, &svc_expkey_cache);
-               if (exp &&
-                   (err = cache_check(&svc_export_cache, &exp->h, reqp)))
+               if ((err = cache_check(&svc_export_cache, &exp->h, reqp)))
                        exp = ERR_PTR(err);
                return exp;
        } else
index 2997e23..e181852 100644 (file)
@@ -281,7 +281,7 @@ static inline int is_fsid(struct svc_fh *fh, struct knfsd_fh *reffh)
  | FATTR4_WORD1_OWNER          | FATTR4_WORD1_OWNER_GROUP  | FATTR4_WORD1_RAWDEV           \
  | FATTR4_WORD1_SPACE_AVAIL     | FATTR4_WORD1_SPACE_FREE   | FATTR4_WORD1_SPACE_TOTAL      \
  | FATTR4_WORD1_SPACE_USED      | FATTR4_WORD1_TIME_ACCESS  | FATTR4_WORD1_TIME_ACCESS_SET  \
- | FATTR4_WORD1_TIME_CREATE     | FATTR4_WORD1_TIME_DELTA   | FATTR4_WORD1_TIME_METADATA    \
+ | FATTR4_WORD1_TIME_DELTA   | FATTR4_WORD1_TIME_METADATA    \
  | FATTR4_WORD1_TIME_MODIFY     | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_MOUNTED_ON_FILEID)
 
 /* These will return ERR_INVAL if specified in GETATTR or READDIR. */
index 1240afe..13afff3 100644 (file)
@@ -170,6 +170,7 @@ struct nfsd3_readdirres {
        u32 *                   buffer;
        int                     buflen;
        u32 *                   offset;
+       u32 *                   offset1;
        struct svc_rqst *       rqstp;
 
 };
index 40028bc..c6f5063 100644 (file)
@@ -133,12 +133,16 @@ struct page_state {
        unsigned long allocstall;       /* direct reclaim calls */
 
        unsigned long pgrotated;        /* pages rotated to tail of the LRU */
-} ____cacheline_aligned;
+};
 
 DECLARE_PER_CPU(struct page_state, page_states);
 
 extern void get_page_state(struct page_state *ret);
 extern void get_full_page_state(struct page_state *ret);
+extern unsigned long __read_page_state(unsigned offset);
+
+#define read_page_state(member) \
+       __read_page_state(offsetof(struct page_state, member))
 
 #define mod_page_state(member, delta)                                  \
        do {                                                            \
@@ -190,16 +194,10 @@ extern void get_full_page_state(struct page_state *ret);
 #define ClearPageReferenced(page)      clear_bit(PG_referenced, &(page)->flags)
 #define TestClearPageReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags)
 
-#ifndef arch_set_page_uptodate
-#define arch_set_page_uptodate(page) do { } while (0)
-#endif
-
 #define PageUptodate(page)     test_bit(PG_uptodate, &(page)->flags)
-#define SetPageUptodate(page) \
-       do {                                                            \
-               arch_set_page_uptodate(page);                           \
-               set_bit(PG_uptodate, &(page)->flags);                   \
-       } while (0)
+#ifndef SetPageUptodate
+#define SetPageUptodate(page)  set_bit(PG_uptodate, &(page)->flags)
+#endif
 #define ClearPageUptodate(page)        clear_bit(PG_uptodate, &(page)->flags)
 
 #define PageDirty(page)                test_bit(PG_dirty, &(page)->flags)
index b43a7f8..45d805d 100644 (file)
 #define PCI_DEVICE_ID_TI_1410          0xac50
 #define PCI_DEVICE_ID_TI_1420          0xac51
 #define PCI_DEVICE_ID_TI_1451A         0xac52
+#define PCI_DEVICE_ID_TI_1620          0xac54
 #define PCI_DEVICE_ID_TI_1520          0xac55
 #define PCI_DEVICE_ID_TI_1510          0xac56
 
 
 #define PCI_VENDOR_ID_3WARE            0x13C1
 #define PCI_DEVICE_ID_3WARE_1000       0x1000
+#define PCI_DEVICE_ID_3WARE_7000       0x1001
+#define PCI_DEVICE_ID_3WARE_9000       0x1002
 
 #define PCI_VENDOR_ID_IOMEGA           0x13ca
 #define PCI_DEVICE_ID_IOMEGA_BUZ       0x4231
 #define PCI_DEVICE_ID_TIGON3_5750      0x1676
 #define PCI_DEVICE_ID_TIGON3_5751      0x1677
 #define PCI_DEVICE_ID_TIGON3_5750M     0x167c
+#define PCI_DEVICE_ID_TIGON3_5751M     0x167d
+#define PCI_DEVICE_ID_TIGON3_5751F     0x167e
 #define PCI_DEVICE_ID_TIGON3_5782      0x1696
 #define PCI_DEVICE_ID_TIGON3_5788      0x169c
+#define PCI_DEVICE_ID_TIGON3_5789      0x169d
 #define PCI_DEVICE_ID_TIGON3_5702X     0x16a6
 #define PCI_DEVICE_ID_TIGON3_5703X     0x16a7
 #define PCI_DEVICE_ID_TIGON3_5704S     0x16a8
index a3d6b59..ef350df 100644 (file)
@@ -437,5 +437,6 @@ struct tc_dly_qopt
 {
        __u32   latency;
        __u32   limit;
-};     
+       __u32   loss;
+};
 #endif
index f9bfac9..c8b6967 100644 (file)
 /* Get/set floating-point exception mode (if meaningful) */
 #define PR_GET_FPEXC   11
 #define PR_SET_FPEXC   12
+# define PR_FP_EXC_SW_ENABLE   0x80    /* Use FPEXC for FP exception enables */
+# define PR_FP_EXC_DIV         0x010000        /* floating point divide by zero */
+# define PR_FP_EXC_OVF         0x020000        /* floating point overflow */
+# define PR_FP_EXC_UND         0x040000        /* floating point underflow */
+# define PR_FP_EXC_RES         0x080000        /* floating point inexact result */
+# define PR_FP_EXC_INV         0x100000        /* floating point invalid operation */
 # define PR_FP_EXC_DISABLED    0       /* FP exceptions disabled */
 # define PR_FP_EXC_NONRECOV    1       /* async non-recoverable exc. mode */
 # define PR_FP_EXC_ASYNC       2       /* async recoverable exception mode */
index 0b6b5e6..faa400c 100644 (file)
@@ -255,6 +255,14 @@ struct mddev_s
        struct list_head                all_mddevs;
 };
 
+
+static inline void rdev_dec_pending(mdk_rdev_t *rdev, mddev_t *mddev)
+{
+       int faulty = rdev->faulty;
+       if (atomic_dec_and_test(&rdev->nr_pending) && faulty)
+               set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+}
+
 struct mdk_personality_s
 {
        char *name;
@@ -271,6 +279,8 @@ struct mdk_personality_s
        int (*hot_remove_disk) (mddev_t *mddev, int number);
        int (*spare_active) (mddev_t *mddev);
        int (*sync_request)(mddev_t *mddev, sector_t sector_nr, int go_faster);
+       int (*resize) (mddev_t *mddev, sector_t sectors);
+       int (*reshape) (mddev_t *mddev, int raid_disks);
 };
 
 
index 96abcad..50965d9 100644 (file)
@@ -10,6 +10,20 @@ struct mirror_info {
        sector_t        head_position;
 };
 
+/*
+ * memory pools need a pointer to the mddev, so they can force an unplug
+ * when memory is tight, and a count of the number of drives that the
+ * pool was allocated for, so they know how much to allocate and free.
+ * mddev->raid_disks cannot be used, as it can change while a pool is active
+ * These two datums are stored in a kmalloced struct.
+ */
+
+struct pool_info {
+       mddev_t *mddev;
+       int     raid_disks;
+};
+
+
 typedef struct r1bio_s r1bio_t;
 
 struct r1_private_data_s {
@@ -31,6 +45,8 @@ struct r1_private_data_s {
        wait_queue_head_t       wait_idle;
        wait_queue_head_t       wait_resume;
 
+       struct pool_info        *poolinfo;
+
        mempool_t *r1bio_pool;
        mempool_t *r1buf_pool;
 };
index 8132a6e..813868e 100644 (file)
@@ -1238,8 +1238,12 @@ excessive effort to avoid disturbing the precious VFS code.:-( The
 gods only know how we are going to SMP the code that uses them.
 znodes are the way! */
 
+#define PATH_READA     0x1 /* do read ahead */
+#define PATH_READA_BACK 0x2 /* read backwards */
+
 struct  path {
   int                   path_length;                           /* Length of the array above.   */
+  int                  reada;
   struct  path_element  path_elements[EXTENDED_MAX_HEIGHT];    /* Array of the path elements.  */
   int                  pos_in_item;
 };
@@ -1247,7 +1251,7 @@ struct  path {
 #define pos_in_item(path) ((path)->pos_in_item)
 
 #define INITIALIZE_PATH(var) \
-struct path var = {ILLEGAL_PATH_ELEMENT_OFFSET, }
+struct path var = {.path_length = ILLEGAL_PATH_ELEMENT_OFFSET, .reada = 0,}
 
 /* Get path element by path and path position. */
 #define PATH_OFFSET_PELEMENT(p_s_path,n_offset)  ((p_s_path)->path_elements +(n_offset))
@@ -1748,6 +1752,14 @@ int reiserfs_add_tail_list(struct inode *inode, struct buffer_head *bh);
 int reiserfs_add_ordered_list(struct inode *inode, struct buffer_head *bh);
 int journal_mark_dirty(struct reiserfs_transaction_handle *, struct super_block *, struct buffer_head *bh) ;
 
+static inline int
+reiserfs_file_data_log(struct inode *inode) {
+    if (reiserfs_data_log(inode->i_sb) ||
+       (REISERFS_I(inode)->i_flags & i_data_log))
+        return 1 ;
+    return 0 ;
+}
+
 static inline int reiserfs_transaction_running(struct super_block *s) {
     struct reiserfs_transaction_handle *th = current->journal_info ;
     if (th && th->t_super == s)
@@ -2149,6 +2161,15 @@ struct buffer_head * get_FEB (struct tree_balance *);
 typedef struct __reiserfs_blocknr_hint reiserfs_blocknr_hint_t;
 
 int reiserfs_parse_alloc_options (struct super_block *, char *);
+void reiserfs_init_alloc_options (struct super_block *s);
+
+/*
+ * given a directory, this will tell you what packing locality
+ * to use for a new object underneat it.  The locality is returned
+ * in disk byte order (le).
+ */
+u32 reiserfs_choose_packing(struct inode *dir);
+
 int is_reusable (struct super_block * s, b_blocknr_t block, int bit_value);
 void reiserfs_free_block (struct reiserfs_transaction_handle *th, struct inode *, b_blocknr_t, int for_unformatted);
 int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *, b_blocknr_t * , int, int);
index 57eeaf7..adc71cd 100644 (file)
@@ -25,6 +25,7 @@ typedef enum {
     i_link_saved_truncate_mask =  0x0020,
     i_priv_object              =  0x0080,
     i_has_xattr_dir            =  0x0100,
+    i_data_log                =  0x0200,
 } reiserfs_inode_flags;
 
 
index b82de21..b811c58 100644 (file)
@@ -171,8 +171,6 @@ long io_schedule_timeout(long timeout);
 extern void cpu_init (void);
 extern void trap_init(void);
 extern void update_process_times(int user);
-extern void update_one_process(struct task_struct *p, unsigned long user,
-                              unsigned long system, int cpu);
 extern void scheduler_tick(int user_tick, int system);
 extern unsigned long cache_decay_ticks;
 
@@ -319,6 +317,9 @@ struct user_struct {
        atomic_t __count;       /* reference count */
        atomic_t processes;     /* How many processes does this user have? */
        atomic_t files;         /* How many open files does this user have? */
+       atomic_t sigpending;    /* How many pending signals does this user have? */
+       /* protected by mq_lock */
+       unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */
 
        /* Hash table maintenance information */
        struct list_head uidhash_list;
@@ -366,6 +367,12 @@ struct group_info {
        gid_t *blocks[0];
 };
 
+/*
+ * get_group_info() must be called with the owning task locked (via task_lock())
+ * when task != current.  The reason being that the vast majority of callers are
+ * looking at current->group_info, which can not be changed except by the
+ * current task.  Changing current->group_info requires the task lock, too.
+ */
 #define get_group_info(group_info) do { \
        atomic_inc(&(group_info)->usage); \
 } while (0)
@@ -693,9 +700,9 @@ extern void sched_balance_exec(void);
 
 extern void sched_idle_next(void);
 extern void set_user_nice(task_t *p, long nice);
-extern int task_prio(task_t *p);
-extern int task_nice(task_t *p);
-extern int task_curr(task_t *p);
+extern int task_prio(const task_t *p);
+extern int task_nice(const task_t *p);
+extern int task_curr(const task_t *p);
 extern int idle_cpu(int cpu);
 
 void yield(void);
@@ -731,6 +738,11 @@ extern void __set_special_pids(pid_t session, pid_t pgrp);
 
 /* per-UID process charging. */
 extern struct user_struct * alloc_uid(uid_t);
+static inline struct user_struct *get_uid(struct user_struct *u)
+{
+       atomic_inc(&u->__count);
+       return u;
+}
 extern void free_uid(struct user_struct *);
 extern void switch_uid(struct user_struct *);
 
@@ -750,7 +762,7 @@ extern void FASTCALL(wake_up_forked_process(struct task_struct * tsk));
  static inline void kick_process(struct task_struct *tsk) { }
  static inline void wake_up_forked_thread(struct task_struct * tsk)
  {
-       return wake_up_forked_process(tsk);
+       wake_up_forked_process(tsk);
  }
 #endif
 extern void FASTCALL(sched_fork(task_t * p));
@@ -917,7 +929,7 @@ extern void wait_task_inactive(task_t * p);
 #define while_each_thread(g, t) \
        while ((t = next_thread(t)) != g)
 
-extern task_t * FASTCALL(next_thread(task_t *p));
+extern task_t * FASTCALL(next_thread(const task_t *p));
 
 #define thread_group_leader(p) (p->pid == p->tgid)
 
@@ -934,7 +946,9 @@ static inline int thread_group_empty(task_t *p)
 extern void unhash_process(struct task_struct *p);
 
 /*
- * Protects ->fs, ->files, ->mm, ->ptrace and synchronises with wait4().
+ * Protects ->fs, ->files, ->mm, ->ptrace, ->group_info and synchronises with
+ * wait4().
+ *
  * Nests both inside and outside of read_lock(&tasklist_lock).
  * It must not be nested with write_lock_irq(&tasklist_lock),
  * neither inside nor outside.
@@ -1056,7 +1070,7 @@ extern void signal_wake_up(struct task_struct *t, int resume_stopped);
  */
 #ifdef CONFIG_SMP
 
-static inline unsigned int task_cpu(struct task_struct *p)
+static inline unsigned int task_cpu(const struct task_struct *p)
 {
        return p->thread_info->cpu;
 }
@@ -1068,7 +1082,7 @@ static inline void set_task_cpu(struct task_struct *p, unsigned int cpu)
 
 #else
 
-static inline unsigned int task_cpu(struct task_struct *p)
+static inline unsigned int task_cpu(const struct task_struct *p)
 {
        return 0;
 }
index 44ae55b..3b6afb8 100644 (file)
@@ -58,7 +58,7 @@
 struct sdla_mem {
    int  addr;
    int  len;
-   void *data;
+   void __user *data;
 };
 
 #define SDLA_START                     (FRAD_LAST_IOCTL + 7)
index df0089a..983d7c2 100644 (file)
@@ -53,7 +53,7 @@ extern void cap_task_reparent_to_init (struct task_struct *p);
 extern int cap_syslog (int type);
 extern int cap_vm_enough_memory (long pages);
 
-static inline int cap_netlink_send (struct sk_buff *skb)
+static inline int cap_netlink_send (struct sock *sk, struct sk_buff *skb)
 {
        NETLINK_CB (skb).eff_cap = current->cap_effective;
        return 0;
@@ -639,9 +639,12 @@ struct swap_info_struct;
  *     Save security information for a netlink message so that permission
  *     checking can be performed when the message is processed.  The security
  *     information can be saved using the eff_cap field of the
- *      netlink_skb_parms structure.
+ *      netlink_skb_parms structure.  Also may be used to provide fine
+ *     grained control over message transmission.
+ *     @sk associated sock of task sending the message.,
  *     @skb contains the sk_buff structure for the netlink message.
- *     Return 0 if the information was successfully saved.
+ *     Return 0 if the information was successfully saved and message
+ *     is allowed to be transmitted.
  * @netlink_recv:
  *     Check permission before processing the received netlink message in
  *     @skb.
@@ -1172,7 +1175,7 @@ struct security_operations {
        int (*shm_associate) (struct shmid_kernel * shp, int shmflg);
        int (*shm_shmctl) (struct shmid_kernel * shp, int cmd);
        int (*shm_shmat) (struct shmid_kernel * shp, 
-                         char *shmaddr, int shmflg);
+                         char __user *shmaddr, int shmflg);
 
        int (*sem_alloc_security) (struct sem_array * sma);
        void (*sem_free_security) (struct sem_array * sma);
@@ -1181,7 +1184,7 @@ struct security_operations {
        int (*sem_semop) (struct sem_array * sma, 
                          struct sembuf * sops, unsigned nsops, int alter);
 
-       int (*netlink_send) (struct sk_buff * skb);
+       int (*netlink_send) (struct sock * sk, struct sk_buff * skb);
        int (*netlink_recv) (struct sk_buff * skb);
 
        /* allow module stacking */
@@ -1873,9 +1876,9 @@ static inline int security_setprocattr(struct task_struct *p, char *name, void *
        return security_ops->setprocattr(p, name, value, size);
 }
 
-static inline int security_netlink_send(struct sk_buff * skb)
+static inline int security_netlink_send(struct sock *sk, struct sk_buff * skb)
 {
-       return security_ops->netlink_send(skb);
+       return security_ops->netlink_send(sk, skb);
 }
 
 static inline int security_netlink_recv(struct sk_buff * skb)
@@ -2501,9 +2504,9 @@ static inline int security_setprocattr(struct task_struct *p, char *name, void *
  * (rather than hooking into the capability module) to reduce overhead
  * in the networking code.
  */
-static inline int security_netlink_send (struct sk_buff *skb)
+static inline int security_netlink_send (struct sock *sk, struct sk_buff *skb)
 {
-       return cap_netlink_send (skb);
+       return cap_netlink_send (sk, skb);
 }
 
 static inline int security_netlink_recv (struct sk_buff *skb)
index 00c4b08..f79c67d 100644 (file)
 /* NEC v850.  */
 #define PORT_V850E_UART        40
 
-/* NEC PC-9800 */
-#define PORT_8251_PC98 41
-#define PORT_19K_PC98  42
-#define PORT_FIFO_PC98 43
-#define PORT_VFAST_PC98        44
-#define PORT_PC9861    45
-#define PORT_PC9801_101        46
-
 /* DZ */
 #define PORT_DZ                47
 
index 28f6247..be0ccba 100644 (file)
@@ -105,7 +105,6 @@ static __inline__ void serio_cleanup(struct serio *serio)
 #define SERIO_8042     0x01000000UL
 #define SERIO_RS232    0x02000000UL
 #define SERIO_HIL_MLC  0x03000000UL
-#define SERIO_PC9800   0x04000000UL
 #define SERIO_PS_PSTHRU        0x05000000UL
 #define SERIO_8042_XL  0x06000000UL
 
index 0e95116..2407dd8 100644 (file)
@@ -7,6 +7,9 @@
 #include <asm/siginfo.h>
 
 #ifdef __KERNEL__
+
+#define MAX_SIGPENDING 1024
+
 /*
  * Real Time signals may be queued.
  */
@@ -16,6 +19,7 @@ struct sigqueue {
        spinlock_t *lock;
        int flags;
        siginfo_t info;
+       struct user_struct *user;
 };
 
 /* flags values. */
index b29326a..de156a1 100644 (file)
@@ -816,6 +816,30 @@ static inline void skb_reserve(struct sk_buff *skb, unsigned int len)
        skb->tail += len;
 }
 
+/*
+ * CPUs often take a performance hit when accessing unaligned memory
+ * locations. The actual performance hit varies, it can be small if the
+ * hardware handles it or large if we have to take an exception and fix it
+ * in software.
+ *
+ * Since an ethernet header is 14 bytes network drivers often end up with
+ * the IP header at an unaligned offset. The IP header can be aligned by
+ * shifting the start of the packet by 2 bytes. Drivers should do this
+ * with:
+ *
+ * skb_reserve(NET_IP_ALIGN);
+ *
+ * The downside to this alignment of the IP header is that the DMA is now
+ * unaligned. On some architectures the cost of an unaligned DMA is high
+ * and this cost outweighs the gains made by aligning the IP header.
+ * 
+ * Since this trade off varies between architectures, we allow NET_IP_ALIGN
+ * to be overridden.
+ */
+#ifndef NET_IP_ALIGN
+#define NET_IP_ALIGN   2
+#endif
+
 extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc);
 
 static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
index b907fb2..8ff2a12 100644 (file)
@@ -60,7 +60,7 @@ struct kstat {
        unsigned long   ino;
        dev_t           dev;
        umode_t         mode;
-       nlink_t         nlink;
+       unsigned int    nlink;
        uid_t           uid;
        gid_t           gid;
        dev_t           rdev;
index 36bcc5e..30689cc 100644 (file)
@@ -87,6 +87,7 @@ struct auth_domain {
  */
 struct auth_ops {
        char *  name;
+       struct module *owner;
        int     flavour;
        int     (*accept)(struct svc_rqst *rq, u32 *authp);
        int     (*release)(struct svc_rqst *rq);
index a7fea38..ef19387 100644 (file)
@@ -165,7 +165,8 @@ asmlinkage long sys_wait4(pid_t pid, unsigned int __user *stat_addr,
 asmlinkage long sys_waitpid(pid_t pid, unsigned int __user *stat_addr, int options);
 asmlinkage long sys_set_tid_address(int __user *tidptr);
 asmlinkage long sys_futex(u32 __user *uaddr, int op, int val,
-                       struct timespec __user *utime, u32 __user *uaddr2);
+                       struct timespec __user *utime, u32 __user *uaddr2,
+                       int val3);
 
 asmlinkage long sys_init_module(void __user *umod, unsigned long len,
                                const char __user *uargs);
index 6f33c87..39e2d22 100644 (file)
@@ -183,6 +183,9 @@ struct tcp_info
        __u32   tcpi_snd_cwnd;
        __u32   tcpi_advmss;
        __u32   tcpi_reordering;
+
+       __u32   tcpi_rcv_rtt;
+       __u32   tcpi_rcv_space;
 };
 
 #ifdef __KERNEL__
@@ -351,11 +354,11 @@ struct tcp_opt {
        __u8    urg_mode;       /* In urgent mode               */
        __u32   snd_up;         /* Urgent pointer               */
 
-       /* The syn_wait_lock is necessary only to avoid tcp_get_info having
+       /* The syn_wait_lock is necessary only to avoid proc interface having
         * to grab the main lock sock while browsing the listening hash
         * (otherwise it's deadlock prone).
-        * This lock is acquired in read mode only from tcp_get_info() and
-        * it's acquired in write mode _only_ from code that is actively
+        * This lock is acquired in read mode only from listening_get_next()
+        * and it's acquired in write mode _only_ from code that is actively
         * changing the syn_wait_queue. All readers that are holding
         * the master sock lock don't need to grab this lock in read mode
         * too as the syn_wait_queue writes are always protected from
index 3300f90..d24a690 100644 (file)
@@ -184,7 +184,7 @@ struct timezone {
  * Avoid unnecessary multiplications/divisions in the
  * two most common HZ cases:
  */
-static inline unsigned int jiffies_to_msecs(unsigned long j)
+static inline unsigned int jiffies_to_msecs(const unsigned long j)
 {
 #if HZ <= 1000 && !(1000 % HZ)
        return (1000 / HZ) * j;
@@ -194,7 +194,7 @@ static inline unsigned int jiffies_to_msecs(unsigned long j)
        return (j * 1000) / HZ;
 #endif
 }
-static inline unsigned long msecs_to_jiffies(unsigned int m)
+static inline unsigned long msecs_to_jiffies(const unsigned int m)
 {
 #if HZ <= 1000 && !(1000 % HZ)
        return (m + (1000 / HZ) - 1) / (1000 / HZ);
@@ -217,7 +217,7 @@ static inline unsigned long msecs_to_jiffies(unsigned int m)
  * value to a scaled second value.
  */
 static __inline__ unsigned long
-timespec_to_jiffies(struct timespec *value)
+timespec_to_jiffies(const struct timespec *value)
 {
        unsigned long sec = value->tv_sec;
        long nsec = value->tv_nsec + TICK_NSEC - 1;
@@ -233,7 +233,7 @@ timespec_to_jiffies(struct timespec *value)
 }
 
 static __inline__ void
-jiffies_to_timespec(unsigned long jiffies, struct timespec *value)
+jiffies_to_timespec(const unsigned long jiffies, struct timespec *value)
 {
        /*
         * Convert jiffies to nanoseconds and separate with
@@ -256,7 +256,7 @@ jiffies_to_timespec(unsigned long jiffies, struct timespec *value)
  * instruction above the way it was done above.
  */
 static __inline__ unsigned long
-timeval_to_jiffies(struct timeval *value)
+timeval_to_jiffies(const struct timeval *value)
 {
        unsigned long sec = value->tv_sec;
        long usec = value->tv_usec;
@@ -271,7 +271,7 @@ timeval_to_jiffies(struct timeval *value)
 }
 
 static __inline__ void
-jiffies_to_timeval(unsigned long jiffies, struct timeval *value)
+jiffies_to_timeval(const unsigned long jiffies, struct timeval *value)
 {
        /*
         * Convert jiffies to nanoseconds and separate with
index 4f19d23..46e2bb9 100644 (file)
@@ -40,7 +40,7 @@
 #define UDFFS_DATE                     "2004/29/09"
 #define UDFFS_VERSION                  "0.9.8.1"
 
-#define UDFFS_DEBUG
+#undef UDFFS_DEBUG
 
 #ifdef UDFFS_DEBUG
 #define udf_debug(f, a...) \
index cf24391..4013919 100644 (file)
@@ -334,6 +334,7 @@ extern void usb_put_dev(struct usb_device *dev);
 
 /* mostly for devices emulating SCSI over USB */
 extern int usb_reset_device(struct usb_device *dev);
+extern int __usb_reset_device(struct usb_device *dev);
 
 extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id);
 
index e208b6f..88ba0d2 100644 (file)
@@ -10,6 +10,7 @@
 #define _LINUX_WATCHDOG_H
 
 #include <linux/ioctl.h>
+#include <linux/types.h>
 
 #define        WATCHDOG_IOCTL_BASE     'W'
 
index 7461026..61bd0fd 100644 (file)
@@ -534,8 +534,8 @@ typedef struct wf_patch_info {
                                  WF_{GET,SET}_CHANNEL above.
 
                               */
-    wavefront_any *hdrptr;      /* user-space ptr to hdr bytes */
-    UINT16 *dataptr;            /* actual sample data */
+    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;
index 26b5553..bf86bf6 100644 (file)
@@ -312,7 +312,7 @@ extern int  ax25_check_iframes_acked(ax25_cb *, unsigned short);
 
 /* ax25_route.c */
 extern void ax25_rt_device_down(struct net_device *);
-extern int  ax25_rt_ioctl(unsigned int, void *);
+extern int  ax25_rt_ioctl(unsigned int, void __user *);
 extern struct file_operations ax25_route_fops;
 extern int  ax25_rt_autobind(ax25_cb *, ax25_address *);
 extern ax25_route *ax25_rt_find_route(ax25_route *, ax25_address *,
index 3cb77ae..8308881 100644 (file)
@@ -358,12 +358,12 @@ int hci_dev_open(__u16 dev);
 int hci_dev_close(__u16 dev);
 int hci_dev_reset(__u16 dev);
 int hci_dev_reset_stat(__u16 dev);
-int hci_dev_cmd(unsigned int cmd, unsigned long arg);
-int hci_get_dev_list(unsigned long arg);
-int hci_get_dev_info(unsigned long arg);
-int hci_get_conn_list(unsigned long arg);
-int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg);
-int hci_inquiry(unsigned long arg);
+int hci_dev_cmd(unsigned int cmd, void __user *arg);
+int hci_get_dev_list(void __user *arg);
+int hci_get_dev_info(void __user *arg);
+int hci_get_conn_list(void __user *arg);
+int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
+int hci_inquiry(void __user *arg);
 
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
 
index ce249f1..819b06d 100644 (file)
@@ -348,7 +348,7 @@ struct rfcomm_dev_list_req {
        struct   rfcomm_dev_info dev_info[0];
 };
 
-int  rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg);
+int  rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
 int  rfcomm_init_ttys(void);
 void rfcomm_cleanup_ttys(void);
 
index 120465f..86e8e86 100644 (file)
@@ -155,7 +155,7 @@ struct rtnode_hello_message
 extern void dn_dev_init(void);
 extern void dn_dev_cleanup(void);
 
-extern int dn_dev_ioctl(unsigned int cmd, void *arg);
+extern int dn_dev_ioctl(unsigned int cmd, void __user *arg);
 
 extern void dn_dev_devices_off(void);
 extern void dn_dev_devices_on(void);
index 42dd8f5..ed2504c 100644 (file)
@@ -67,7 +67,7 @@ struct dst_entry
        struct xfrm_state       *xfrm;
 
        int                     (*input)(struct sk_buff*);
-       int                     (*output)(struct sk_buff*);
+       int                     (*output)(struct sk_buff**);
 
 #ifdef CONFIG_NET_CLS_ROUTE
        __u32                   tclassid;
@@ -89,6 +89,7 @@ struct dst_ops
        int                     (*gc)(void);
        struct dst_entry *      (*check)(struct dst_entry *, __u32 cookie);
        void                    (*destroy)(struct dst_entry *);
+       void                    (*ifdown)(struct dst_entry *, int how);
        struct dst_entry *      (*negative_advice)(struct dst_entry *);
        void                    (*link_failure)(struct sk_buff *);
        void                    (*update_pmtu)(struct dst_entry *dst, u32 mtu);
@@ -219,7 +220,7 @@ static inline int dst_output(struct sk_buff *skb)
        int err;
 
        for (;;) {
-               err = skb->dst->output(skb);
+               err = skb->dst->output(&skb);
 
                if (likely(err == 0))
                        return err;
index 94ea1ed..5a683cc 100644 (file)
@@ -92,8 +92,8 @@ extern int            ip_rcv(struct sk_buff *skb, struct net_device *dev,
                               struct packet_type *pt);
 extern int             ip_local_deliver(struct sk_buff *skb);
 extern int             ip_mr_input(struct sk_buff *skb);
-extern int             ip_output(struct sk_buff *skb);
-extern int             ip_mc_output(struct sk_buff *skb);
+extern int             ip_output(struct sk_buff **pskb);
+extern int             ip_mc_output(struct sk_buff **pskb);
 extern int             ip_fragment(struct sk_buff *skb, int (*out)(struct sk_buff*));
 extern int             ip_do_nat(struct sk_buff *skb);
 extern void            ip_send_check(struct iphdr *ip);
index ea27811..2911490 100644 (file)
@@ -65,7 +65,7 @@ extern struct rt6_info                *rt6_lookup(struct in6_addr *daddr,
 extern struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
                                         struct neighbour *neigh,
                                         struct in6_addr *addr,
-                                        int (*output)(struct sk_buff *));
+                                        int (*output)(struct sk_buff **));
 extern int ndisc_dst_gc(int *more);
 extern void fib6_force_start_gc(void);
 
index 06b350c..8f647ae 100644 (file)
@@ -355,8 +355,7 @@ extern int                  ip6_dst_lookup(struct sock *sk,
  *     skb processing functions
  */
 
-extern int                     ip6_output(struct sk_buff *skb);
-extern int                     ip6_output2(struct sk_buff *skb);
+extern int                     ip6_output(struct sk_buff **pskb);
 extern int                     ip6_forward(struct sk_buff *skb);
 extern int                     ip6_input(struct sk_buff *skb);
 extern int                     ip6_mc_input(struct sk_buff *skb);
index 1d4cd8e..2b24544 100644 (file)
 #ifndef IRDA_DEVICE_H
 #define IRDA_DEVICE_H
 
+#include <linux/config.h>
 #include <linux/tty.h>
 #include <linux/netdevice.h>
 #include <linux/spinlock.h>
 #include <linux/skbuff.h>              /* struct sk_buff */
 #include <linux/irda.h>
+#include <linux/types.h>
 
 #include <net/pkt_sched.h>
 #include <net/irda/irda.h>
@@ -236,7 +238,7 @@ dongle_t *irda_device_dongle_init(struct net_device *dev, int type);
 int irda_device_dongle_cleanup(dongle_t *dongle);
 
 #ifdef CONFIG_ISA
-void irda_setup_dma(int channel, char *buffer, int count, int mode);
+void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode);
 #endif
 
 void irda_task_delete(struct irda_task *task);
index 01ee604..8168780 100644 (file)
@@ -206,7 +206,7 @@ extern void nr_check_iframes_acked(struct sock *, unsigned short);
 extern void nr_rt_device_down(struct net_device *);
 extern struct net_device *nr_dev_first(void);
 extern struct net_device *nr_dev_get(ax25_address *);
-extern int  nr_rt_ioctl(unsigned int, void *);
+extern int  nr_rt_ioctl(unsigned int, void __user *);
 extern void nr_link_failed(ax25_cb *, int);
 extern int  nr_route_frame(struct sk_buff *, ax25_cb *);
 extern struct file_operations nr_nodes_fops;
index d164466..f338235 100644 (file)
@@ -207,7 +207,7 @@ extern struct net_device *rose_dev_get(rose_address *);
 extern struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *);
 extern struct net_device *rose_ax25_dev_get(char *);
 extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *, unsigned char *);
-extern int  rose_rt_ioctl(unsigned int, void *);
+extern int  rose_rt_ioctl(unsigned int, void __user *);
 extern void rose_link_failed(ax25_cb *, int);
 extern int  rose_route_frame(struct sk_buff *, ax25_cb *);
 extern void rose_rt_free(void);
index 2f5e32e..c3088c1 100644 (file)
@@ -93,6 +93,7 @@ typedef enum {
        SCTP_CMD_PROCESS_OPERR,  /* Process an ERROR chunk. */
        SCTP_CMD_REPORT_FWDTSN,  /* Report new cumulative TSN Ack. */
        SCTP_CMD_PROCESS_FWDTSN, /* Skips were reported, so process further. */
+       SCTP_CMD_CLEAR_INIT_TAG, /* Clears association peer's inittag. */
        SCTP_CMD_LAST
 } sctp_verb_t;
 
index 7038423..a73cea9 100644 (file)
@@ -440,6 +440,23 @@ static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_a
                BUG();
 }
 
+/* Check VTAG of the packet matches the sender's own tag. */
+static inline int
+sctp_vtag_verify(const struct sctp_chunk *chunk,
+                const struct sctp_association *asoc)
+{
+       /* RFC 2960 Sec 8.5 When receiving an SCTP packet, the endpoint
+        * MUST ensure that the value in the Verification Tag field of
+        * the received SCTP packet matches its own Tag. If the received
+        * Verification Tag value does not match the receiver's own
+        * tag value, the receiver shall silently discard the packet...
+        */
+        if (ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag)
+                return 1;
+
+       return 0;
+}
+
 /* Check VTAG of the packet matches the sender's own tag OR its peer's
  * tag and the T bit is set in the Chunk Flags.
  */
index 691f146..26c97aa 100644 (file)
@@ -437,13 +437,13 @@ struct sctp_af {
        int             (*setsockopt)   (struct sock *sk,
                                         int level,
                                         int optname,
-                                        char *optval,
+                                        char __user *optval,
                                         int optlen);
        int             (*getsockopt)   (struct sock *sk,
                                         int level,
                                         int optname,
-                                        char *optval,
-                                        int *optlen);
+                                        char __user *optval,
+                                        int __user *optlen);
        struct dst_entry *(*get_dst)    (struct sctp_association *asoc,
                                         union sctp_addr *daddr,
                                         union sctp_addr *saddr);
index 290f996..04e9917 100644 (file)
@@ -559,7 +559,7 @@ struct sctp_status {
 struct sctp_getaddrs {
        sctp_assoc_t            assoc_id;
        int                     addr_num;
-       struct sockaddr         *addrs;
+       struct sockaddr         __user *addrs;
 };
 
 /* These are bit fields for msghdr->msg_flags.  See section 5.1.  */
index 1cea997..376de5d 100644 (file)
@@ -400,6 +400,36 @@ static inline int sock_flag(struct sock *sk, enum sock_flags flag)
        return test_bit(flag, &sk->sk_flags);
 }
 
+static inline void sk_acceptq_removed(struct sock *sk)
+{
+       sk->sk_ack_backlog--;
+}
+
+static inline void sk_acceptq_added(struct sock *sk)
+{
+       sk->sk_ack_backlog++;
+}
+
+static inline int sk_acceptq_is_full(struct sock *sk)
+{
+       return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
+}
+
+/*
+ * Compute minimal free write space needed to queue new packets.
+ */
+static inline int sk_stream_min_wspace(struct sock *sk)
+{
+       return sk->sk_wmem_queued / 2;
+}
+
+static inline int sk_stream_wspace(struct sock *sk)
+{
+       return sk->sk_sndbuf - sk->sk_wmem_queued;
+}
+
+extern void sk_stream_write_space(struct sock *sk);
+
 /* The per-socket spinlock must be held here. */
 #define sk_add_backlog(__sk, __skb)                            \
 do {   if (!(__sk)->sk_backlog.tail) {                         \
@@ -412,6 +442,20 @@ do {       if (!(__sk)->sk_backlog.tail) {                         \
        (__skb)->next = NULL;                                   \
 } while(0)
 
+#define sk_wait_event(__sk, __timeo, __condition)              \
+({     int rc;                                                 \
+       release_sock(__sk);                                     \
+       rc = __condition;                                       \
+       if (!rc) {                                              \
+               *(__timeo) = schedule_timeout(*(__timeo));      \
+               rc = __condition;                               \
+       }                                                       \
+       lock_sock(__sk);                                        \
+       rc;                                                     \
+})
+
+extern int sk_wait_data(struct sock *sk, long *timeo);
+
 /* IP protocol blocks we attach to sockets.
  * socket layer -> transport layer interface
  * transport -> network interface is defined by struct inet_proto
@@ -875,6 +919,11 @@ sk_dst_check(struct sock *sk, u32 cookie)
        return dst;
 }
 
+static inline void sk_charge_skb(struct sock *sk, struct sk_buff *skb)
+{
+       sk->sk_wmem_queued   += skb->truesize;
+       sk->sk_forward_alloc -= skb->truesize;
+}
 
 /*
  *     Queue a received datagram if it will fit. Stream and sequenced
@@ -900,6 +949,11 @@ static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
        atomic_add(skb->truesize, &sk->sk_rmem_alloc);
 }
 
+extern void sk_reset_timer(struct sock *sk, struct timer_list* timer,
+                          unsigned long expires);
+
+extern void sk_stop_timer(struct sock *sk, struct timer_list* timer);
+
 static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
        int err = 0;
@@ -1037,6 +1091,20 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
                sk->sk_stamp = *stamp;
 }
 
+/**
+ * sk_eat_skb - Release a skb if it is no longer needed
+ * @sk - socket to eat this skb from
+ * @skb - socket buffer to eat
+ *
+ * This routine must be called with interrupts disabled or with the socket
+ * locked so that the sk_buff queue operation is ok.
+*/
+static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb)
+{
+       __skb_unlink(skb, &sk->sk_receive_queue);
+       __kfree_skb(skb);
+}
+
 extern atomic_t netstamp_needed;
 extern void sock_enable_timestamp(struct sock *sk);
 extern void sock_disable_timestamp(struct sock *sk);
index 62d75ee..5286353 100644 (file)
@@ -870,7 +870,6 @@ extern void                 tcp_close(struct sock *sk,
                                          long timeout);
 extern struct sock *           tcp_accept(struct sock *sk, int flags, int *err);
 extern unsigned int            tcp_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait);
-extern void                    tcp_write_space(struct sock *sk); 
 
 extern int                     tcp_getsockopt(struct sock *sk, int level, 
                                               int optname,
@@ -971,6 +970,9 @@ extern int tcp_sync_mss(struct sock *sk, u32 pmtu);
 
 extern const char timer_bug_msg[];
 
+/* tcp_diag.c */
+extern void tcp_get_info(struct sock *, struct tcp_info *);
+
 /* Read 'sendfile()'-style from a TCP socket */
 typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *,
                                unsigned int, size_t);
@@ -987,9 +989,7 @@ static inline void tcp_clear_xmit_timer(struct sock *sk, int what)
                tp->pending = 0;
 
 #ifdef TCP_CLEAR_TIMERS
-               if (timer_pending(&tp->retransmit_timer) &&
-                   del_timer(&tp->retransmit_timer))
-                       __sock_put(sk);
+               sk_stop_timer(sk, &tp->retransmit_timer);
 #endif
                break;
        case TCP_TIME_DACK:
@@ -997,9 +997,7 @@ static inline void tcp_clear_xmit_timer(struct sock *sk, int what)
                tp->ack.pending = 0;
 
 #ifdef TCP_CLEAR_TIMERS
-               if (timer_pending(&tp->delack_timer) &&
-                   del_timer(&tp->delack_timer))
-                       __sock_put(sk);
+               sk_stop_timer(sk, &tp->delack_timer);
 #endif
                break;
        default:
@@ -1028,15 +1026,13 @@ static inline void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long
        case TCP_TIME_PROBE0:
                tp->pending = what;
                tp->timeout = jiffies+when;
-               if (!mod_timer(&tp->retransmit_timer, tp->timeout))
-                       sock_hold(sk);
+               sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout);
                break;
 
        case TCP_TIME_DACK:
                tp->ack.pending |= TCP_ACK_TIMER;
                tp->ack.timeout = jiffies+when;
-               if (!mod_timer(&tp->delack_timer, tp->ack.timeout))
-                       sock_hold(sk);
+               sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout);
                break;
 
        default:
@@ -1199,21 +1195,6 @@ struct tcp_skb_cb {
 
 #include <net/tcp_ecn.h>
 
-
-/*
- *     Compute minimal free write space needed to queue new packets. 
- */
-static inline int tcp_min_write_space(struct sock *sk)
-{
-       return sk->sk_wmem_queued / 2;
-}
-static inline int tcp_wspace(struct sock *sk)
-{
-       return sk->sk_sndbuf - sk->sk_wmem_queued;
-}
-
-
 /* This determines how many packets are "in the network" to the best
  * of our knowledge.  In many cases it is conservative, but where
  * detailed information is available from the receiver (via SACK
@@ -1799,28 +1780,13 @@ static inline int tcp_full_space( struct sock *sk)
        return tcp_win_from_space(sk->sk_rcvbuf); 
 }
 
-static inline void tcp_acceptq_removed(struct sock *sk)
-{
-       sk->sk_ack_backlog--;
-}
-
-static inline void tcp_acceptq_added(struct sock *sk)
-{
-       sk->sk_ack_backlog++;
-}
-
-static inline int tcp_acceptq_is_full(struct sock *sk)
-{
-       return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
-}
-
 static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req,
                                         struct sock *child)
 {
        struct tcp_opt *tp = tcp_sk(sk);
 
        req->sk = child;
-       tcp_acceptq_added(sk);
+       sk_acceptq_added(sk);
 
        if (!tp->accept_queue_tail) {
                tp->accept_queue = req;
@@ -1919,12 +1885,6 @@ static inline void tcp_free_skb(struct sock *sk, struct sk_buff *skb)
        __kfree_skb(skb);
 }
 
-static inline void tcp_charge_skb(struct sock *sk, struct sk_buff *skb)
-{
-       sk->sk_wmem_queued += skb->truesize;
-       sk->sk_forward_alloc -= skb->truesize;
-}
-
 extern void __tcp_mem_reclaim(struct sock *sk);
 extern int tcp_mem_schedule(struct sock *sk, int size, int kind);
 
index 188c58e..44a3882 100644 (file)
@@ -52,7 +52,7 @@
 
 extern spinlock_t tux_module_lock;
 extern struct module *tux_module;
-extern long (*sys_tux_ptr) (unsigned int action, user_req_t *u_info);
+extern asmlinkage long (*sys_tux_ptr) (unsigned int action, user_req_t *u_info);
 
 #undef Dprintk
 
index c6153ea..0db97e7 100644 (file)
@@ -196,7 +196,7 @@ extern void x25_transmit_restart_confirmation(struct x25_neigh *);
 extern void x25_transmit_diagnostic(struct x25_neigh *, unsigned char);
 extern void x25_transmit_clear_request(struct x25_neigh *, unsigned int, unsigned char);
 extern void x25_transmit_link(struct sk_buff *, struct x25_neigh *);
-extern int  x25_subscr_ioctl(unsigned int, void *);
+extern int  x25_subscr_ioctl(unsigned int, void __user *);
 extern struct x25_neigh *x25_get_neigh(struct net_device *);
 extern void x25_link_free(void);
 
@@ -221,7 +221,7 @@ extern void x25_enquiry_response(struct sock *);
 extern struct x25_route *x25_get_route(struct x25_address *addr);
 extern struct net_device *x25_dev_get(char *);
 extern void x25_route_device_down(struct net_device *dev);
-extern int  x25_route_ioctl(unsigned int, void *);
+extern int  x25_route_ioctl(unsigned int, void __user *);
 extern void x25_route_free(void);
 
 static __inline__ void x25_route_hold(struct x25_route *rt)
index e6d768a..6470496 100644 (file)
@@ -216,7 +216,7 @@ struct xfrm_type
        void                    (*destructor)(struct xfrm_state *);
        int                     (*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
        int                     (*post_input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
-       int                     (*output)(struct sk_buff *skb);
+       int                     (*output)(struct sk_buff **pskb);
        /* Estimate maximal size of result of transformation of a dgram */
        u32                     (*get_max_size)(struct xfrm_state *, int size);
 };
index 9bfb4ac..887601d 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef _SCSI_SCSI_EH_H
 #define _SCSI_SCSI_EH_H
 
+struct scsi_cmnd;
+struct scsi_device;
+struct Scsi_Host;
+
 extern void scsi_add_timer(struct scsi_cmnd *, int,
                           void (*)(struct scsi_cmnd *));
 extern int scsi_delete_timer(struct scsi_cmnd *);
index 84a7065..abba7b4 100644 (file)
@@ -151,7 +151,7 @@ struct scsi_host_template {
         * here then you will get a call to slave_configure(), then the
         * device will be used for however long it is kept around, then when
         * the device is removed from the system (or * possibly at reboot
-        * time), you will then get a call to slave_detach().  This is
+        * time), you will then get a call to slave_destroy().  This is
         * assuming you implement slave_configure and slave_destroy.
         * However, if you allocate memory and hang it off the device struct,
         * then you must implement the slave_destroy() routine at a minimum
@@ -185,7 +185,7 @@ struct scsi_host_template {
         *     specific setup basis...
         * 6.  Return 0 on success, non-0 on error.  The device will be marked
         *     as offline on error so that no access will occur.  If you return
-        *     non-0, your slave_detach routine will never get called for this
+        *     non-0, your slave_destroy routine will never get called for this
         *     device, so don't leave any loose memory hanging around, clean
         *     up after yourself before returning non-0
         *
@@ -313,6 +313,11 @@ struct scsi_host_template {
         */
        unsigned emulated:1;
 
+       /*
+        * True if the low-level driver performs its own reset-settle delays.
+        */
+       unsigned skip_settle_delay:1;
+
        /*
         * Countdown for host blocking with no commands outstanding
         */
index 688fa25..4a46f88 100644 (file)
@@ -41,7 +41,6 @@ typedef struct scsi_fctargaddress {
 } Scsi_FCTargAddress;
 
 extern int scsi_ioctl(struct scsi_device *, int, void __user *);
-extern int kernel_scsi_ioctl(struct scsi_device *, int , void *);
 extern int scsi_ioctl_send_command(struct scsi_device *,
                                   struct scsi_ioctl_command __user *);
 
index 882d17b..c59f737 100644 (file)
@@ -209,9 +209,9 @@ typedef struct {
        void *private_data;
        int (*info)(void *private_data, gf1_info_t *info);
        int (*put_sample)(void *private_data, gf1_wave_t *wave,
-                         char *data, long len, int atomic);
+                         char __user *data, long len, int atomic);
        int (*get_sample)(void *private_data, gf1_wave_t *wave,
-                         char *data, long len, int atomic);
+                         char __user *data, long len, int atomic);
        int (*remove_sample)(void *private_data, gf1_wave_t *wave,
                             int atomic);
        void (*notify)(void *private_data, snd_seq_kinstr_t *instr, int what);
index ace1031..1b5155f 100644 (file)
@@ -357,9 +357,9 @@ typedef struct {
        void *private_data;
        int (*info)(void *private_data, iwffff_info_t *info);
        int (*put_sample)(void *private_data, iwffff_wave_t *wave,
-                         char *data, long len, int atomic);
+                         char __user *data, long len, int atomic);
        int (*get_sample)(void *private_data, iwffff_wave_t *wave,
-                         char *data, long len, int atomic);
+                         char __user *data, long len, int atomic);
        int (*remove_sample)(void *private_data, iwffff_wave_t *wave,
                             int atomic);
        void (*notify)(void *private_data, snd_seq_kinstr_t *instr, int what);
index bef1f99..da73df0 100644 (file)
@@ -140,9 +140,9 @@ typedef struct {
        void *private_data;
        int (*info)(void *private_data, simple_instrument_info_t *info);
        int (*put_sample)(void *private_data, simple_instrument_t *instr,
-                         char *data, long len, int atomic);
+                         char __user *data, long len, int atomic);
        int (*get_sample)(void *private_data, simple_instrument_t *instr,
-                         char *data, long len, int atomic);
+                         char __user *data, long len, int atomic);
        int (*remove_sample)(void *private_data, simple_instrument_t *instr,
                             int atomic);
        void (*notify)(void *private_data, snd_seq_kinstr_t *instr, int what);
index 62841fe..69dc182 100644 (file)
@@ -135,7 +135,7 @@ struct sndrv_hwdep_dsp_status {
 struct sndrv_hwdep_dsp_image {
        unsigned int index;             /* W: DSP index */
        unsigned char name[64];         /* W: ID (e.g. file name) */
-       unsigned char *image;           /* W: binary image */
+       unsigned char __user *image;    /* W: binary image */
        size_t length;                  /* W: size of image in bytes */
        unsigned long driver_data;      /* W: driver-specific data */
 };
@@ -446,13 +446,13 @@ struct sndrv_pcm_sync_ptr {
 
 struct sndrv_xferi {
        sndrv_pcm_sframes_t result;
-       void *buf;
+       void __user *buf;
        sndrv_pcm_uframes_t frames;
 };
 
 struct sndrv_xfern {
        sndrv_pcm_sframes_t result;
-       void **bufs;
+       void __user * __user *bufs;
        sndrv_pcm_uframes_t frames;
 };
 
@@ -776,7 +776,7 @@ struct sndrv_ctl_elem_list {
        unsigned int space;             /* W: count of element IDs to get */
        unsigned int used;              /* R: count of element IDs set */
        unsigned int count;             /* R: count of all elements */
-       struct sndrv_ctl_elem_id *pids; /* R: IDs */
+       struct sndrv_ctl_elem_id __user *pids; /* R: IDs */
        unsigned char reserved[50];
 };
 
index 5d60930..caf1b3c 100644 (file)
@@ -302,8 +302,8 @@ void snd_hidden_vfree(void *obj);
 #endif
 void *snd_kcalloc(size_t size, int flags);
 char *snd_kmalloc_strdup(const char *string, int flags);
-int copy_to_user_fromio(void *dst, unsigned long src, size_t count);
-int copy_from_user_toio(unsigned long dst, const void *src, size_t count);
+int copy_to_user_fromio(void __user *dst, unsigned long src, size_t count);
+int copy_from_user_toio(unsigned long dst, const void __user *src, size_t count);
 
 /* init.c */
 
index 7ce25ed..6182b77 100644 (file)
@@ -1317,14 +1317,14 @@ typedef struct {
        unsigned int gpr_map[0x100];      /* initializers */
 
        unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */
-       emu10k1_fx8010_control_gpr_t *gpr_add_controls; /* GPR controls to add/replace */
+       emu10k1_fx8010_control_gpr_t __user *gpr_add_controls; /* GPR controls to add/replace */
 
        unsigned int gpr_del_control_count; /* count of GPR controls to remove */
-       snd_ctl_elem_id_t *gpr_del_controls; /* IDs of GPR controls to remove */
+       snd_ctl_elem_id_t __user *gpr_del_controls; /* IDs of GPR controls to remove */
 
        unsigned int gpr_list_control_count; /* count of GPR controls to list */
        unsigned int gpr_list_control_total; /* total count of GPR controls */
-       emu10k1_fx8010_control_gpr_t *gpr_list_controls; /* listed GPR controls */
+       emu10k1_fx8010_control_gpr_t __user *gpr_list_controls; /* listed GPR controls */
 
        unsigned long tram_valid[0xa0/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */
        unsigned int tram_data_map[0xa0]; /* data initializers */
index b336e35..c6970aa 100644 (file)
@@ -60,7 +60,7 @@ typedef struct snd_emux_operators {
        void (*free_voice)(snd_emux_voice_t *vp);
        void (*reset)(snd_emux_t *emu, int ch);
        /* the first parameters are snd_emux_t */
-       int (*sample_new)(snd_emux_t *emu, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr, const void *data, long count);
+       int (*sample_new)(snd_emux_t *emu, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr, const void __user *data, long count);
        int (*sample_free)(snd_emux_t *emu, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr);
        void (*sample_reset)(snd_emux_t *emu);
        int (*load_fx)(snd_emux_t *emu, int type, int arg, const void __user *data, long count);
index 6cd0a22..887b03c 100644 (file)
@@ -684,9 +684,9 @@ extern int snd_engine_instrument_register_ask(unsigned short mode);
 #endif
 
 /* gus_dram.c */
-int snd_gus_dram_write(snd_gus_card_t *gus, char *ptr,
+int snd_gus_dram_write(snd_gus_card_t *gus, char __user *ptr,
                       unsigned int addr, unsigned int size);
-int snd_gus_dram_read(snd_gus_card_t *gus, char *ptr,
+int snd_gus_dram_read(snd_gus_card_t *gus, char __user *ptr,
                      unsigned int addr, unsigned int size, int rom);
 
 #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
@@ -699,21 +699,21 @@ void snd_gf1_simple_init(snd_gus_voice_t *voice);
 
 /* gus_instr.c */
 int snd_gus_iwffff_put_sample(void *private_data, iwffff_wave_t *wave,
-                             char *data, long len, int atomic);
+                             char __user *data, long len, int atomic);
 int snd_gus_iwffff_get_sample(void *private_data, iwffff_wave_t *wave,
-                             char *data, long len, int atomic);
+                             char __user *data, long len, int atomic);
 int snd_gus_iwffff_remove_sample(void *private_data, iwffff_wave_t *wave,
                                 int atomic);
 int snd_gus_gf1_put_sample(void *private_data, gf1_wave_t *wave,
-                          char *data, long len, int atomic);
+                          char __user *data, long len, int atomic);
 int snd_gus_gf1_get_sample(void *private_data, gf1_wave_t *wave,
-                          char *data, long len, int atomic);
+                          char __user *data, long len, int atomic);
 int snd_gus_gf1_remove_sample(void *private_data, gf1_wave_t *wave,
                              int atomic);
 int snd_gus_simple_put_sample(void *private_data, simple_instrument_t *instr,
-                             char *data, long len, int atomic);
+                             char __user *data, long len, int atomic);
 int snd_gus_simple_get_sample(void *private_data, simple_instrument_t *instr,
-                             char *data, long len, int atomic);
+                             char __user *data, long len, int atomic);
 int snd_gus_simple_remove_sample(void *private_data, simple_instrument_t *instr,
                                 int atomic);
 
index 21a9f1c..93e0427 100644 (file)
@@ -76,7 +76,7 @@ struct _snd_hdsp_config_info {
 typedef struct _snd_hdsp_firmware hdsp_firmware_t;
 
 struct _snd_hdsp_firmware {
-       unsigned long *firmware_data;   /* 24413 long words */
+       unsigned long __user *firmware_data;    /* 24413 long words */
 };
 
 #define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, hdsp_firmware_t)
index 5e72865..4a4cc01 100644 (file)
@@ -32,8 +32,8 @@ typedef struct sndrv_hwdep_dsp_image snd_hwdep_dsp_image_t;
 
 typedef struct _snd_hwdep_ops {
        long long (*llseek) (snd_hwdep_t *hw, struct file * file, long long offset, int orig);
-       long (*read) (snd_hwdep_t * hw, char *buf, long count, loff_t *offset);
-       long (*write) (snd_hwdep_t * hw, const char *buf, long count, loff_t *offset);
+       long (*read) (snd_hwdep_t * hw, char __user *buf, long count, loff_t *offset);
+       long (*write) (snd_hwdep_t * hw, const char __user *buf, long count, loff_t *offset);
        int (*open) (snd_hwdep_t * hw, struct file * file);
        int (*release) (snd_hwdep_t * hw, struct file * file);
        unsigned int (*poll) (snd_hwdep_t * hw, struct file * file, poll_table * wait);
index 57ba588..9e33b58 100644 (file)
@@ -54,9 +54,9 @@ struct snd_info_entry_ops {
        int (*release) (snd_info_entry_t * entry,
                        unsigned short mode, void *file_private_data);
        long (*read) (snd_info_entry_t *entry, void *file_private_data,
-                     struct file * file, char *buf, long count);
+                     struct file * file, char __user *buf, long count);
        long (*write) (snd_info_entry_t *entry, void *file_private_data,
-                      struct file * file, const char *buf, long count);
+                      struct file * file, const char __user *buf, long count);
        long long (*llseek) (snd_info_entry_t *entry, void *file_private_data,
                            struct file * file, long long offset, int orig);
        unsigned int (*poll) (snd_info_entry_t *entry, void *file_private_data,
index 17d8b22..4229360 100644 (file)
@@ -95,7 +95,7 @@ typedef struct _snd_pcm_ops {
        int (*trigger)(snd_pcm_substream_t * substream, int cmd);
        snd_pcm_uframes_t (*pointer)(snd_pcm_substream_t * substream);
        int (*copy)(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t pos,
-                   void *buf, snd_pcm_uframes_t count);
+                   void __user *buf, snd_pcm_uframes_t count);
        int (*silence)(snd_pcm_substream_t *substream, int channel, 
                       snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
        struct page *(*page)(snd_pcm_substream_t *substream, unsigned long offset);
@@ -479,7 +479,7 @@ int snd_pcm_notify(snd_pcm_notify_t *notify, int nfree);
 extern rwlock_t snd_pcm_link_rwlock;
 
 int snd_pcm_info(snd_pcm_substream_t * substream, snd_pcm_info_t *info);
-int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t *info);
+int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t __user *info);
 int snd_pcm_status(snd_pcm_substream_t * substream, snd_pcm_status_t *status);
 int snd_pcm_prepare(snd_pcm_substream_t *substream);
 int snd_pcm_start(snd_pcm_substream_t *substream);
@@ -881,13 +881,14 @@ void snd_pcm_tick_set(snd_pcm_substream_t *substream, unsigned long ticks);
 void snd_pcm_tick_elapsed(snd_pcm_substream_t *substream);
 void snd_pcm_period_elapsed(snd_pcm_substream_t *substream);
 snd_pcm_sframes_t snd_pcm_lib_write(snd_pcm_substream_t *substream,
-                                   const void *buf, snd_pcm_uframes_t frames);
+                                   const void __user *buf,
+                                   snd_pcm_uframes_t frames);
 snd_pcm_sframes_t snd_pcm_lib_read(snd_pcm_substream_t *substream,
-                                  void *buf, snd_pcm_uframes_t frames);
+                                  void __user *buf, snd_pcm_uframes_t frames);
 snd_pcm_sframes_t snd_pcm_lib_writev(snd_pcm_substream_t *substream,
-                                    void **bufs, snd_pcm_uframes_t frames);
+                                    void __user **bufs, snd_pcm_uframes_t frames);
 snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream,
-                                   void **bufs, snd_pcm_uframes_t frames);
+                                   void __user **bufs, snd_pcm_uframes_t frames);
 
 int snd_pcm_limit_hw_rates(snd_pcm_runtime_t *runtime);
 
index 832d8f5..1a654df 100644 (file)
@@ -79,9 +79,9 @@ struct snd_seq_kinstr_ops {
        char *instr_type;
        int (*info)(void *private_data, char *info_data, long len);
        int (*put)(void *private_data, snd_seq_kinstr_t *kinstr,
-                  char *instr_data, long len, int atomic, int cmd);
+                  char __user *instr_data, long len, int atomic, int cmd);
        int (*get)(void *private_data, snd_seq_kinstr_t *kinstr,
-                  char *instr_data, long len, int atomic, int cmd);
+                  char __user *instr_data, long len, int atomic, int cmd);
        int (*get_size)(void *private_data, snd_seq_kinstr_t *kinstr, long *size);
        int (*remove)(void *private_data, snd_seq_kinstr_t *kinstr, int atomic);
        void (*notify)(void *private_data, snd_seq_kinstr_t *kinstr, int what);
index 22dd3a4..d0b69fb 100644 (file)
@@ -158,7 +158,7 @@ extern int snd_seq_create_kernel_client(snd_card_t *card, int client_index, snd_
 extern int snd_seq_delete_kernel_client(int client);
 extern int snd_seq_kernel_client_enqueue(int client, snd_seq_event_t *ev, int atomic, int hop);
 extern int snd_seq_kernel_client_dispatch(int client, snd_seq_event_t *ev, int atomic, int hop);
-extern int snd_seq_kernel_client_ctl(int client, unsigned int cmd, void __user *arg);
+extern int snd_seq_kernel_client_ctl(int client, unsigned int cmd, void *arg);
 
 #define SNDRV_SEQ_EXT_MASK     0xc0000000
 #define SNDRV_SEQ_EXT_USRPTR   0x80000000
index c6653eb..0d88859 100644 (file)
@@ -12,7 +12,7 @@ struct sscape_bootblock
 
 struct sscape_microcode
 {
-  unsigned char *code;
+  unsigned char __user *code;
 };
 
 #define SND_SSCAPE_LOAD_BOOTB  _IOWR('P', 100, struct sscape_bootblock)
index 5ded7d0..255a5cb 100644 (file)
@@ -479,6 +479,6 @@ int snd_trident_free_pages(trident_t *trident, snd_util_memblk_t *blk);
 snd_util_memblk_t *snd_trident_synth_alloc(trident_t *trident, unsigned int size);
 int snd_trident_synth_free(trident_t *trident, snd_util_memblk_t *blk);
 int snd_trident_synth_bzero(trident_t *trident, snd_util_memblk_t *blk, int offset, int size);
-int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char *data, int size);
+int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char __user *data, int size);
 
 #endif /* __SOUND_TRIDENT_H */
index bcc633a..5609f54 100644 (file)
@@ -254,13 +254,13 @@ inline static unsigned int snd_vx_inl(vx_core_t *chip, int reg)
 inline static void snd_vx_outb(vx_core_t *chip, int reg, unsigned char val)
 {
        snd_assert(chip->ops->out8, return);
-       return chip->ops->out8(chip, reg, val);
+       chip->ops->out8(chip, reg, val);
 }
 
 inline static void snd_vx_outl(vx_core_t *chip, int reg, unsigned int val)
 {
        snd_assert(chip->ops->out32, return);
-       return chip->ops->out32(chip, reg, val);
+       chip->ops->out32(chip, reg, val);
 }
 
 #define vx_inb(chip,reg)       snd_vx_inb(chip, VX_##reg)
index c13fd09..9e572ae 100644 (file)
@@ -554,8 +554,8 @@ typedef struct wf_patch_info {
                                  WF_{GET,SET}_CHANNEL above.
 
                               */
-    wavefront_any *hdrptr;      /* user-space ptr to hdr bytes */
-    u16 *dataptr;            /* actual sample data */
+    wavefront_any __user *hdrptr;      /* user-space ptr to hdr bytes */
+    u16 __user *dataptr;            /* actual sample data */
 
     wavefront_any hdr;          /* kernel-space copy of hdr bytes */         
 } wavefront_patch_info;
index 5d12017..136bf79 100644 (file)
@@ -38,7 +38,8 @@
 #define TV_AVIDEO               0x00000100
 #define TV_SVIDEO               0x00000200
 #define TV_SCART                0x00000400
-#define VB_CONEXANT            0x00000800
+#define VB_CONEXANT            0x00000800      /* 661 series only */
+#define VB_TRUMPION            VB_CONEXANT     /* 300 series only */
 #define TV_PALM                 0x00001000
 #define TV_PALN                 0x00002000
 #define TV_NTSCJ               0x00001000
 #define VB_DISPMODE_DUAL       VB_DUALVIEW_MODE
 #define VB_DISPLAY_MODE        (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
 
-/* *Never* change the order of the following enum */
-typedef enum _SIS_CHIP_TYPE {
-       SIS_VGALegacy = 0,      /* chip_id in sisfb_info */
-       SIS_300,
-       SIS_630,
-       SIS_540,
-       SIS_730,
-       SIS_315H,
-       SIS_315,
-       SIS_315PRO,
-       SIS_550,
-       SIS_650,
-       SIS_740,
-       SIS_330,
-       SIS_661,
-       SIS_741,
-       SIS_660,
-       SIS_760,
-       MAX_SIS_CHIP
-} SIS_CHIP_TYPE;
-
-/* Addtional IOCTLs for communication sisfb <> X driver                */
-/* If changing this, vgatypes.h must also be changed (for X driver)    */
-
-/* ioctl for identifying and giving some info (esp. memory heap start) */
-#define SISFB_GET_INFO         _IOR('n',0xF8,__u32)
-/* ioctrl to get current vertical retrace status */
-#define SISFB_GET_VBRSTATUS    _IOR('n',0xF9,__u32)
-/* ioctl to enable/disable panning auto-maximize (like nomax parameter) */
-#define SISFB_GET_AUTOMAXIMIZE         _IOR('n',0xFA,__u32)
-#define SISFB_SET_AUTOMAXIMIZE         _IOW('n',0xFA,__u32)
-
-/* TW: Structure argument for SISFB_GET_INFO ioctl  */
+/* Structure argument for SISFB_GET_INFO ioctl  */
 typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
 
 struct _SISFB_INFO {
-       unsigned long sisfb_id;         /* for identifying sisfb */
+       __u32   sisfb_id;               /* for identifying sisfb */
 #ifndef SISFB_ID
 #define SISFB_ID         0x53495346    /* Identify myself with 'SISF' */
 #endif
-       int    chip_id;                 /* PCI ID of detected chip */
-       int    memory;                  /* video memory in KB which sisfb manages */
-       int    heapstart;               /* heap start (= sisfb "mem" argument) in KB */
-       unsigned char fbvidmode;        /* current sisfb mode */
+       __u32   chip_id;                /* PCI-ID of detected chip */
+       __u32   memory;                 /* video memory in KB which sisfb manages */
+       __u32   heapstart;              /* heap start (= sisfb "mem" argument) in KB */
+       __u8    fbvidmode;              /* current sisfb mode */
 
-       unsigned char sisfb_version;
-       unsigned char sisfb_revision;
-       unsigned char sisfb_patchlevel;
+       __u8    sisfb_version;
+       __u8    sisfb_revision;
+       __u8    sisfb_patchlevel;
 
-       unsigned char sisfb_caps;       /* Sisfb capabilities */
+       __u8    sisfb_caps;             /* sisfb capabilities */
 
-       int    sisfb_tqlen;             /* turbo queue length (in KB) */
+       __u32   sisfb_tqlen;            /* turbo queue length (in KB) */
 
-       unsigned int sisfb_pcibus;      /* The card's PCI ID */
-       unsigned int sisfb_pcislot;
-       unsigned int sisfb_pcifunc;
+       __u32   sisfb_pcibus;           /* The card's PCI ID */
+       __u32   sisfb_pcislot;
+       __u32   sisfb_pcifunc;
 
-       unsigned char sisfb_lcdpdc;     /* PanelDelayCompensation */
+       __u8    sisfb_lcdpdc;           /* PanelDelayCompensation */
 
-       unsigned char sisfb_lcda;       /* Detected status of LCDA for low res/text modes */
+       __u8    sisfb_lcda;             /* Detected status of LCDA for low res/text modes */
 
-       unsigned long sisfb_vbflags;
-       unsigned long sisfb_currentvbflags;
+       __u32   sisfb_vbflags;
+       __u32   sisfb_currentvbflags;
 
-       int sisfb_scalelcd;
-       unsigned long sisfb_specialtiming;
+       __u32   sisfb_scalelcd;
+       __u32   sisfb_specialtiming;
 
-       unsigned char sisfb_haveemi;
-       unsigned char sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
-       unsigned char sisfb_haveemilcd;
+       __u8    sisfb_haveemi;
+       __u8    sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
+       __u8    sisfb_haveemilcd;
 
-       char reserved[213];             /* for future use */
-};
+       __u8    sisfb_lcdpdca;          /* PanelDelayCompensation for LCD-via-CRT1 */
 
-/* For fb memory manager */
-struct sis_memreq {
-       unsigned long offset;
-       unsigned long size;
-};
+       __u16   sisfb_tvxpos, sisfb_tvypos;  /* Warning: Values + 32 ! */
 
-/* More or less deprecated stuff follows: */
-typedef enum _TVTYPE {
-       TVMODE_NTSC = 0,
-       TVMODE_PAL,
-       TVMODE_HIVISION,
-       TVMODE_TOTAL
-} SIS_TV_TYPE;
-
-typedef enum _TVPLUGTYPE {
-       TVPLUG_Legacy = 0,
-       TVPLUG_COMPOSITE,
-       TVPLUG_SVIDEO,
-       TVPLUG_SCART,
-       TVPLUG_TOTAL
-} SIS_TV_PLUG;
-
-struct mode_info {
-       int    bpp;
-       int    xres;
-       int    yres;
-       int    v_xres;          /* deprecated - use var instead */
-       int    v_yres;          /* deprecated - use var instead */
-       int    org_x;           /* deprecated - use var instead */
-       int    org_y;           /* deprecated - use var instead */
-       unsigned int  vrate;
+       __u8    reserved[208];          /* for future use */
 };
 
-struct ap_data {
-       struct mode_info minfo;
-       unsigned long iobase;
-       unsigned int  mem_size;
-       unsigned long disp_state;  /* deprecated */
-       SIS_CHIP_TYPE chip;
-       unsigned char hasVB;
-       SIS_TV_TYPE TV_type;       /* deprecated */
-       SIS_TV_PLUG TV_plug;       /* deprecated */
-       unsigned long version;
-       unsigned long vbflags;     /* replaces deprecated entries above */
-       unsigned long currentvbflags;
-       char reserved[248];
+/* Addtional IOCTLs for communication sisfb <> X driver                */
+/* If changing this, vgatypes.h must also be changed (for X driver)    */
+
+/* ioctl for identifying and giving some info (esp. memory heap start) */
+#define SISFB_GET_INFO_SIZE    _IOR(0xF3,0x00,__u32)
+#define SISFB_GET_INFO         _IOR(0xF3,0x01,struct _SISFB_INFO)
+
+/* ioctrl to get current vertical retrace status */
+#define SISFB_GET_VBRSTATUS    _IOR(0xF3,0x02,__u32)
+
+/* ioctl to enable/disable panning auto-maximize (like nomax parameter) */
+#define SISFB_GET_AUTOMAXIMIZE         _IOR(0xF3,0x03,__u32)
+#define SISFB_SET_AUTOMAXIMIZE         _IOW(0xF3,0x03,__u32)
+
+/* ioctls to relocate TV output (x=D[31:16], y=D[15:0], + 32)*/
+#define SISFB_GET_TVPOSOFFSET   _IOR(0xF3,0x04,__u32)
+#define SISFB_SET_TVPOSOFFSET   _IOW(0xF3,0x04,__u32)
+
+/* ioctl for locking sisfb (no register access during lock) */
+/* As of now, only used to avoid register access during
+ * the ioctls listed above.
+ */
+#define SISFB_SET_LOCK         _IOW(0xF3,0x06,__u32)
+
+/* more to come soon */
+
+/* ioctls 0xF3 up to 0x3F reserved for sisfb */
+
+/****************************************************************/
+/* The following are deprecated and should not be used anymore: */
+/****************************************************************/
+/* ioctl for identifying and giving some info (esp. memory heap start) */
+#define SISFB_GET_INFO_OLD        _IOR('n',0xF8,__u32)
+/* ioctrl to get current vertical retrace status */
+#define SISFB_GET_VBRSTATUS_OLD           _IOR('n',0xF9,__u32)
+/* ioctl to enable/disable panning auto-maximize (like nomax parameter) */
+#define SISFB_GET_AUTOMAXIMIZE_OLD _IOR('n',0xFA,__u32)
+#define SISFB_SET_AUTOMAXIMIZE_OLD _IOW('n',0xFA,__u32)
+/****************************************************************/
+/*               End of deprecated ioctl numbers                */
+/****************************************************************/
+
+/* For fb memory manager (FBIO_ALLOC, FBIO_FREE) */
+struct sis_memreq {
+       __u32   offset;
+       __u32   size;
 };
 
 /**********************************************/
 /*                  PRIVATE                   */
+/*         (for IN-KERNEL usage only)         */
 /**********************************************/
 
 #ifdef __KERNEL__
-#include <linux/spinlock.h>
-
-typedef enum _VGA_ENGINE {
-       UNKNOWN_VGA = 0,
-       SIS_300_VGA,
-       SIS_315_VGA,
-} VGA_ENGINE;
-
-struct video_info {
-       int           chip_id;
-       unsigned int  video_size;
-       unsigned long video_base;
-       char  *       video_vbase;
-       unsigned long mmio_base;
-       char  *       mmio_vbase;
-       unsigned long vga_base;
-       unsigned long mtrr;
-       unsigned long heapstart;
-
-       int    video_bpp;
-       int    video_cmap_len;
-       int    video_width;
-       int    video_height;
-       int    video_vwidth;                    /* DEPRECATED - use var instead */
-       int    video_vheight;                   /* DEPRECATED - use var instead */
-       int    org_x;                           /* DEPRECATED - use var instead */
-       int    org_y;                           /* DEPRECATED - use var instead */
-       int    video_linelength;
-       unsigned int refresh_rate;
-
-       unsigned long disp_state;               /* DEPRECATED */
-       unsigned char hasVB;                    /* DEPRECATED */
-       unsigned char TV_type;                  /* DEPRECATED */
-       unsigned char TV_plug;                  /* DEPRECATED */
-
-       SIS_CHIP_TYPE chip;
-       unsigned char revision_id;
-
-        unsigned short DstColor;               /* For 2d acceleration */
-       unsigned long  SiS310_AccelDepth;
-       unsigned long  CommandReg;
-
-       spinlock_t     lockaccel;               /* Do not use outside of kernel! */
-
-        unsigned int   pcibus;
-       unsigned int   pcislot;
-       unsigned int   pcifunc;
-
-       int            accel;
-
-       unsigned short subsysvendor;
-       unsigned short subsysdevice;
-
-       unsigned long  vbflags;                 /* Replacing deprecated stuff from above */
-       unsigned long  currentvbflags;
-
-       int    current_bpp;
-       int    current_width;
-       int    current_height;
-       int    current_htotal;
-       int    current_vtotal;
-       __u32  current_pixclock;
-       int    current_refresh_rate;
-
-       char reserved[200];
-};
-
-extern struct video_info ivideo;
+#define        UNKNOWN_VGA  0
+#define        SIS_300_VGA  1
+#define        SIS_315_VGA  2
 
 extern void sis_malloc(struct sis_memreq *req);
-extern void sis_free(unsigned long base);
-extern void sis_dispinfo(struct ap_data *rec);
+extern void sis_free(u32 base);
 #endif
+
 #endif
index f0c5a23..b412c06 100644 (file)
@@ -121,6 +121,18 @@ config BSD_PROCESS_ACCT
          up to the user level program to do useful things with this
          information.  This is generally a good idea, so say Y.
 
+config BSD_PROCESS_ACCT_V3
+       bool "BSD Process Accounting version 3 file format"
+       depends on BSD_PROCESS_ACCT
+       default n
+       help
+         If you say Y here, the process accounting information is written
+         in a new file format that also logs the process IDs of each
+         process and it's parent. Note that this file format is incompatible
+         with previous v0/v1/v2 file formats, so you will need updated tools
+         for processing it. A preliminary version of these tools is available
+         at <http://http://www.de.kernel.org/pub/linux/utils/acct/>.
+
 config SYSCTL
        bool "Sysctl support"
        ---help---
index 076a65f..027896b 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/efi.h>
 #include <linux/unistd.h>
 #include <linux/rmap.h>
+#include <linux/mempolicy.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -186,7 +187,7 @@ void __devinit calibrate_delay(void)
        loops_per_jiffy = (1<<12);
 
        printk("Calibrating delay loop... ");
-       while (loops_per_jiffy <<= 1) {
+       while ((loops_per_jiffy <<= 1) != 0) {
                /* wait for "start of" clock tick */
                ticks = jiffies;
                while (ticks == jiffies)
@@ -268,6 +269,8 @@ static int __init unknown_bootoption(char *param, char *val)
                                panic_later = "Too many boot env vars at `%s'";
                                panic_param = param;
                        }
+                       if (!strncmp(param, envp_init[i], val - param))
+                               break;
                }
                envp_init[i] = param;
        } else {
@@ -385,6 +388,7 @@ static void __init smp_init(void)
 static void noinline rest_init(void)
 {
        kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
+       numa_default_policy();
        unlock_kernel();
        cpu_idle();
 } 
@@ -456,6 +460,7 @@ asmlinkage void __init start_kernel(void)
 #endif
        mem_init();
        kmem_cache_init();
+       numa_policy_init();
        if (late_time_init)
                late_time_init();
        calibrate_delay();
@@ -632,7 +637,7 @@ static int init(void * unused)
         * check if there is an early userspace init.  If yes, let it do all
         * the work
         */
-       if (sys_access("/init", 0) == 0)
+       if (sys_access((const char __user *) "/init", 0) == 0)
                execute_command = "/init";
        else
                prepare_namespace();
@@ -645,8 +650,9 @@ static int init(void * unused)
        free_initmem();
        unlock_kernel();
        system_state = SYSTEM_RUNNING;
+       numa_default_policy();
 
-       if (sys_open("/dev/console", O_RDWR, 0) < 0)
+       if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
                printk("Warning: unable to open an initial console.\n");
 
        (void) sys_dup(0);
index 40a8d41..c9ea777 100644 (file)
 #define CTL_MSGSIZEMAX         4
 
 /* default values */
-#define DFLT_QUEUESMAX 64      /* max number of message queues */
-#define DFLT_MSGMAX    40      /* max number of messages in each queue */
+#define DFLT_QUEUESMAX 256     /* max number of message queues */
+#define DFLT_MSGMAX    10      /* max number of messages in each queue */
 #define HARD_MSGMAX    (131072/sizeof(void*))
-#define DFLT_MSGSIZEMAX 16384  /* max message size */
+#define DFLT_MSGSIZEMAX 8192   /* max message size */
 
 #define NOTIFY_COOKIE_LEN      32
 
@@ -67,6 +67,7 @@ struct mqueue_inode_info {
 
        struct sigevent notify;
        pid_t notify_owner;
+       struct user_struct *user;       /* user who created, for accouting */
        struct sock *notify_sock;
        struct sk_buff *notify_cookie;
 
@@ -114,6 +115,9 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
 
                if (S_ISREG(mode)) {
                        struct mqueue_inode_info *info;
+                       struct task_struct *p = current;
+                       struct user_struct *u = p->user;
+                       unsigned long mq_bytes, mq_msg_tblsz;
 
                        inode->i_fop = &mqueue_file_operations;
                        inode->i_size = FILENT_SIZE;
@@ -123,8 +127,10 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
                        init_waitqueue_head(&info->wait_q);
                        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->qsize = 0;
+                       info->user = NULL;      /* set when all is ok */
                        memset(&info->attr, 0, sizeof(info->attr));
                        info->attr.mq_maxmsg = DFLT_MSGMAX;
                        info->attr.mq_msgsize = DFLT_MSGSIZEMAX;
@@ -132,12 +138,29 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
                                info->attr.mq_maxmsg = attr->mq_maxmsg;
                                info->attr.mq_msgsize = attr->mq_msgsize;
                        }
-                       info->messages = kmalloc(info->attr.mq_maxmsg * sizeof(struct msg_msg *), GFP_KERNEL);
+                       mq_msg_tblsz = info->attr.mq_maxmsg * sizeof(struct msg_msg *);
+                       mq_bytes = (mq_msg_tblsz +
+                               (info->attr.mq_maxmsg * info->attr.mq_msgsize));
+
+                       spin_lock(&mq_lock);
+                       if (u->mq_bytes + mq_bytes < u->mq_bytes ||
+                           u->mq_bytes + mq_bytes >
+                           p->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
+                               spin_unlock(&mq_lock);
+                               goto out_inode;
+                       }
+                       u->mq_bytes += mq_bytes;
+                       spin_unlock(&mq_lock);
+
+                       info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL);
                        if (!info->messages) {
-                               make_bad_inode(inode);
-                               iput(inode);
-                               inode = NULL;
+                               spin_lock(&mq_lock);
+                               u->mq_bytes -= mq_bytes;
+                               spin_unlock(&mq_lock);
+                               goto out_inode;
                        }
+                       /* all is ok */
+                       info->user = get_uid(u);
                } else if (S_ISDIR(mode)) {
                        inode->i_nlink++;
                        /* Some things misbehave if size == 0 on a directory */
@@ -147,6 +170,10 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
                }
        }
        return inode;
+out_inode:
+       make_bad_inode(inode);
+       iput(inode);
+       return NULL;
 }
 
 static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
@@ -205,6 +232,8 @@ static void mqueue_destroy_inode(struct inode *inode)
 static void mqueue_delete_inode(struct inode *inode)
 {
        struct mqueue_inode_info *info;
+       struct user_struct *user;
+       unsigned long mq_bytes;
        int i;
 
        if (S_ISDIR(inode->i_mode)) {
@@ -220,10 +249,15 @@ static void mqueue_delete_inode(struct inode *inode)
 
        clear_inode(inode);
 
-       if (info->messages) {
+       mq_bytes = (info->attr.mq_maxmsg * sizeof(struct msg_msg *) +
+                  (info->attr.mq_maxmsg * info->attr.mq_msgsize));
+       user = info->user;
+       if (user) {
                spin_lock(&mq_lock);
+               user->mq_bytes -= mq_bytes;
                queues_count--;
                spin_unlock(&mq_lock);
+               free_uid(user);
        }
 }
 
@@ -534,6 +568,28 @@ static void remove_notification(struct mqueue_inode_info *info)
        info->notify_owner = 0;
 }
 
+static int mq_attr_ok(struct mq_attr *attr)
+{
+       if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0)
+               return 0;
+       if (capable(CAP_SYS_RESOURCE)) {
+               if (attr->mq_maxmsg > HARD_MSGMAX)
+                       return 0;
+       } else {
+               if (attr->mq_maxmsg > msg_max ||
+                               attr->mq_msgsize > msgsize_max)
+                       return 0;
+       }
+       /* check for overflow */
+       if (attr->mq_msgsize > ULONG_MAX/attr->mq_maxmsg)
+               return 0;
+       if ((unsigned long)(attr->mq_maxmsg * attr->mq_msgsize) +
+           (attr->mq_maxmsg * sizeof (struct msg_msg *)) <
+           (unsigned long)(attr->mq_maxmsg * attr->mq_msgsize))
+               return 0;
+       return 1;
+}
+
 /*
  * Invoked when creating a new queue via sys_mq_open
  */
@@ -547,17 +603,8 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
        if (u_attr != NULL) {
                if (copy_from_user(&attr, u_attr, sizeof(attr)))
                        return ERR_PTR(-EFAULT);
-
-               if (attr.mq_maxmsg <= 0 || attr.mq_msgsize <= 0)
+               if (!mq_attr_ok(&attr))
                        return ERR_PTR(-EINVAL);
-               if (capable(CAP_SYS_RESOURCE)) {
-                       if (attr.mq_maxmsg > HARD_MSGMAX)
-                               return ERR_PTR(-EINVAL);
-               } else {
-                       if (attr.mq_maxmsg > msg_max ||
-                                       attr.mq_msgsize > msgsize_max)
-                               return ERR_PTR(-EINVAL);
-               }
                /* store for use during create */
                dentry->d_fsdata = &attr;
        }
index 18d8eba..9761e3b 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -504,11 +504,14 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
        case SHM_LOCK:
        case SHM_UNLOCK:
        {
-               /* Allow superuser to lock segment in memory */
-               if (!can_do_mlock()) {
+/* Allow superuser to lock segment in memory */
+/* Should the pages be faulted in here or leave it to user? */
+/* need to determine interaction with current->swappable */
+               if (!capable(CAP_IPC_LOCK)) {
                        err = -EPERM;
                        goto out;
                }
+
                shp = shm_lock(shmid);
                if(shp==NULL) {
                        err = -EINVAL;
@@ -523,11 +526,9 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                        goto out_unlock;
                
                if(cmd==SHM_LOCK) {
-                       if (!is_file_hugepages(shp->shm_file)) {
-                               err = shmem_lock(shp->shm_file, 1);
-                               if (!err)
-                                       shp->shm_flags |= SHM_LOCKED;
-                       }
+                       if (!is_file_hugepages(shp->shm_file))
+                               shmem_lock(shp->shm_file, 1);
+                       shp->shm_flags |= SHM_LOCKED;
                } else {
                        if (!is_file_hugepages(shp->shm_file))
                                shmem_lock(shp->shm_file, 0);
index 77e7189..81a145e 100644 (file)
@@ -377,11 +377,8 @@ int ipcperms (struct kern_ipc_perm *ipcp, short flag)
                granted_mode >>= 3;
        /* is there some bit set in requested_mode but not in granted_mode? */
        if ((requested_mode & ~granted_mode & 0007) && 
-           !capable(CAP_IPC_OWNER)) {
-               if (!can_do_mlock())  {
-                       return -1;
-               }
-       }       
+           !capable(CAP_IPC_OWNER))
+               return -1;
 
        return security_ipc_permission(ipcp, flag);
 }
index f0e2bd0..e55e7bb 100644 (file)
@@ -302,6 +302,69 @@ static comp_t encode_comp_t(unsigned long value)
        return exp;
 }
 
+#if ACCT_VERSION==1 || ACCT_VERSION==2
+/*
+ * encode an u64 into a comp2_t (24 bits)
+ *
+ * Format: 5 bit base 2 exponent, 20 bits mantissa.
+ * The leading bit of the mantissa is not stored, but implied for
+ * non-zero exponents.
+ * Largest encodable value is 50 bits.
+ */
+
+#define MANTSIZE2       20                      /* 20 bit mantissa. */
+#define EXPSIZE2        5                       /* 5 bit base 2 exponent. */
+#define MAXFRACT2       ((1ul << MANTSIZE2) - 1) /* Maximum fractional value. */
+#define MAXEXP2         ((1 <<EXPSIZE2) - 1)    /* Maximum exponent. */
+
+static comp2_t encode_comp2_t(u64 value)
+{
+        int exp, rnd;
+
+        exp = (value > (MAXFRACT2>>1));
+        rnd = 0;
+        while (value > MAXFRACT2) {
+                rnd = value & 1;
+                value >>= 1;
+                exp++;
+        }
+
+        /*
+         * If we need to round up, do it (and handle overflow correctly).
+         */
+        if (rnd && (++value > MAXFRACT2)) {
+                value >>= 1;
+                exp++;
+        }
+
+        if (exp > MAXEXP2) {
+                /* Overflow. Return largest representable number instead. */
+                return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1;
+        } else {
+                return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1));
+        }
+}
+#endif
+
+#if ACCT_VERSION==3
+/*
+ * encode an u64 into a 32 bit IEEE float
+ */
+static u32 encode_float(u64 value)
+{
+       unsigned exp = 190;
+       unsigned u;
+
+       if (value==0) return 0;
+       while ((s64)value > 0){
+               value <<= 1;
+               exp--;
+       }
+       u = (u32)(value >> 40) & 0x7fffffu;
+       return u | (exp << 23);
+}
+#endif
+
 /*
  *  Write an accounting entry for an exiting process
  *
@@ -316,7 +379,7 @@ static comp_t encode_comp_t(unsigned long value)
  */
 static void do_acct_process(long exitcode, struct file *file)
 {
-       struct acct ac;
+       acct_t ac;
        mm_segment_t fs;
        unsigned long vsize;
        unsigned long flim;
@@ -333,27 +396,53 @@ static void do_acct_process(long exitcode, struct file *file)
         * Fill the accounting struct with the needed info as recorded
         * by the different kernel functions.
         */
-       memset((caddr_t)&ac, 0, sizeof(struct acct));
+       memset((caddr_t)&ac, 0, sizeof(acct_t));
 
+       ac.ac_version = ACCT_VERSION;
        strlcpy(ac.ac_comm, current->comm, sizeof(ac.ac_comm));
 
-       elapsed = jiffies_64_to_clock_t(get_jiffies_64() - current->start_time);
+       elapsed = jiffies_64_to_AHZ(get_jiffies_64() - current->start_time);
+#if ACCT_VERSION==3
+       ac.ac_etime = encode_float(elapsed);
+#else
        ac.ac_etime = encode_comp_t(elapsed < (unsigned long) -1l ?
                               (unsigned long) elapsed : (unsigned long) -1l);
-       do_div(elapsed, USER_HZ);
+#endif
+#if ACCT_VERSION==1 || ACCT_VERSION==2
+       {
+               /* new enlarged etime field */
+               comp2_t etime = encode_comp2_t(elapsed);
+               ac.ac_etime_hi = etime >> 16;
+               ac.ac_etime_lo = (u16) etime;
+       }
+#endif
+       do_div(elapsed, AHZ);
        ac.ac_btime = xtime.tv_sec - elapsed;
-       ac.ac_utime = encode_comp_t(jiffies_to_clock_t(current->utime));
-       ac.ac_stime = encode_comp_t(jiffies_to_clock_t(current->stime));
+       ac.ac_utime = encode_comp_t(jiffies_to_AHZ(current->utime));
+       ac.ac_stime = encode_comp_t(jiffies_to_AHZ(current->stime));
        /* we really need to bite the bullet and change layout */
        ac.ac_uid = current->uid;
        ac.ac_gid = current->gid;
+#if ACCT_VERSION==2
+       ac.ac_ahz = AHZ;
+#endif
+#if ACCT_VERSION==1 || ACCT_VERSION==2
+       /* backward-compatible 16 bit fields */
+       ac.ac_uid16 = current->uid;
+       ac.ac_gid16 = current->gid;
+#endif
+#if ACCT_VERSION==3
+       ac.ac_pid = current->pid;
+       ac.ac_ppid = current->parent->pid;
+#endif
 
        read_lock(&tasklist_lock);      /* pin current->signal */
        ac.ac_tty = current->signal->tty ?
                old_encode_dev(tty_devnum(current->signal->tty)) : 0;
        read_unlock(&tasklist_lock);
 
-       ac.ac_flag = 0;
+       /* ABYTESEX is always set to allow byte order detection */
+       ac.ac_flag = ABYTESEX;
        if (current->flags & PF_FORKNOEXEC)
                ac.ac_flag |= AFORK;
        if (current->flags & PF_SUPERPRIV)
@@ -395,7 +484,7 @@ static void do_acct_process(long exitcode, struct file *file)
        flim = current->rlim[RLIMIT_FSIZE].rlim_cur;
        current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
        file->f_op->write(file, (char *)&ac,
-                              sizeof(struct acct), &file->f_pos);
+                              sizeof(acct_t), &file->f_pos);
        current->rlim[RLIMIT_FSIZE].rlim_cur = flim;
        set_fs(fs);
 }
index 540574c..57cc48e 100644 (file)
@@ -182,7 +182,7 @@ asmlinkage long compat_sys_sigpending(compat_old_sigset_t __user *set)
        mm_segment_t old_fs = get_fs();
 
        set_fs(KERNEL_DS);
-       ret = sys_sigpending(&s);
+       ret = sys_sigpending((old_sigset_t __user *) &s);
        set_fs(old_fs);
        if (ret == 0)
                ret = put_user(s, set);
@@ -200,7 +200,9 @@ asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set,
                return -EFAULT;
        old_fs = get_fs();
        set_fs(KERNEL_DS);
-       ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
+       ret = sys_sigprocmask(how,
+                             set ? (old_sigset_t __user *) &s : NULL,
+                             oset ? (old_sigset_t __user *) &s : NULL);
        set_fs(old_fs);
        if (ret == 0)
                if (oset)
@@ -223,7 +225,7 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, int val,
                timeout = timespec_to_jiffies(&t) + 1;
        }
        if (op >= FUTEX_REQUEUE)
-               val2 = (int) (long) utime;
+               val2 = (int) (unsigned long) utime;
 
        return do_futex((unsigned long)uaddr, op, val, timeout,
                        (unsigned long)uaddr2, val2, val3);
@@ -250,7 +252,7 @@ asmlinkage long compat_sys_setrlimit(unsigned int resource,
        if (r.rlim_max == COMPAT_RLIM_INFINITY)
                r.rlim_max = RLIM_INFINITY;
        set_fs(KERNEL_DS);
-       ret = sys_setrlimit(resource, &r);
+       ret = sys_setrlimit(resource, (struct rlimit __user *) &r);
        set_fs(old_fs);
        return ret;
 }
@@ -292,7 +294,7 @@ asmlinkage long compat_sys_getrlimit (unsigned int resource,
        mm_segment_t old_fs = get_fs();
 
        set_fs(KERNEL_DS);
-       ret = sys_getrlimit(resource, &r);
+       ret = sys_getrlimit(resource, (struct rlimit __user *) &r);
        set_fs(old_fs);
        if (!ret) {
                if (r.rlim_cur > COMPAT_RLIM_INFINITY)
@@ -340,7 +342,7 @@ asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru)
        mm_segment_t old_fs = get_fs();
 
        set_fs(KERNEL_DS);
-       ret = sys_getrusage(who, &r);
+       ret = sys_getrusage(who, (struct rusage __user *) &r);
        set_fs(old_fs);
 
        if (ret)
@@ -365,7 +367,10 @@ compat_sys_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options,
                mm_segment_t old_fs = get_fs();
 
                set_fs (KERNEL_DS);
-               ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
+               ret = sys_wait4(pid,
+                               (stat_addr ?
+                                (unsigned int __user *) &status : NULL),
+                               options, (struct rusage __user *) &r);
                set_fs (old_fs);
 
                if (ret > 0) {
@@ -382,18 +387,18 @@ asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
                                             unsigned int len,
                                             compat_ulong_t __user *user_mask_ptr)
 {
-       unsigned long kernel_mask;
+       unsigned long kern_mask;
        mm_segment_t old_fs;
        int ret;
 
-       if (get_user(kernel_mask, user_mask_ptr))
+       if (get_user(kern_mask, user_mask_ptr))
                return -EFAULT;
 
        old_fs = get_fs();
        set_fs(KERNEL_DS);
        ret = sys_sched_setaffinity(pid,
-                                   sizeof(kernel_mask),
-                                   &kernel_mask);
+                                   sizeof(kern_mask),
+                                   (unsigned long __user *) &kern_mask);
        set_fs(old_fs);
 
        return ret;
@@ -402,20 +407,20 @@ asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
 asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
                                             compat_ulong_t __user *user_mask_ptr)
 {
-       unsigned long kernel_mask;
+       unsigned long kern_mask;
        mm_segment_t old_fs;
        int ret;
 
        old_fs = get_fs();
        set_fs(KERNEL_DS);
        ret = sys_sched_getaffinity(pid,
-                                   sizeof(kernel_mask),
-                                   &kernel_mask);
+                                   sizeof(kern_mask),
+                                   (unsigned long __user *) &kern_mask);
        set_fs(old_fs);
 
        if (ret > 0) {
                ret = sizeof(compat_ulong_t);
-               if (put_user(kernel_mask, user_mask_ptr))
+               if (put_user(kern_mask, user_mask_ptr))
                        return -EFAULT;
        }
 
@@ -454,7 +459,9 @@ long compat_timer_settime(timer_t timer_id, int flags,
                return -EFAULT; 
        oldfs = get_fs();
        set_fs(KERNEL_DS);
-       err = sys_timer_settime(timer_id, flags, &newts, &oldts);
+       err = sys_timer_settime(timer_id, flags,
+                               (struct itimerspec __user *) &newts,
+                               (struct itimerspec __user *) &oldts);
        set_fs(oldfs); 
        if (!err && old && put_compat_itimerspec(old, &oldts))
                return -EFAULT;
@@ -467,9 +474,11 @@ long compat_timer_gettime(timer_t timer_id,
        long err;
        mm_segment_t oldfs;
        struct itimerspec ts; 
+
        oldfs = get_fs();
        set_fs(KERNEL_DS);
-       err = sys_timer_gettime(timer_id, &ts); 
+       err = sys_timer_gettime(timer_id,
+                               (struct itimerspec __user *) &ts); 
        set_fs(oldfs); 
        if (!err && put_compat_itimerspec(setting, &ts))
                return -EFAULT;
@@ -482,11 +491,13 @@ long compat_clock_settime(clockid_t which_clock,
        long err;
        mm_segment_t oldfs;
        struct timespec ts; 
+
        if (get_compat_timespec(&ts, tp))
                return -EFAULT; 
        oldfs = get_fs();
        set_fs(KERNEL_DS);      
-       err = sys_clock_settime(which_clock, &ts); 
+       err = sys_clock_settime(which_clock,
+                               (struct timespec __user *) &ts);
        set_fs(oldfs);
        return err;
 } 
@@ -497,9 +508,11 @@ long compat_clock_gettime(clockid_t which_clock,
        long err;
        mm_segment_t oldfs;
        struct timespec ts; 
+
        oldfs = get_fs();
        set_fs(KERNEL_DS);
-       err = sys_clock_gettime(which_clock, &ts); 
+       err = sys_clock_gettime(which_clock,
+                               (struct timespec __user *) &ts);
        set_fs(oldfs);
        if (!err && put_compat_timespec(&ts, tp))
                return -EFAULT; 
@@ -512,9 +525,11 @@ long compat_clock_getres(clockid_t which_clock,
        long err;
        mm_segment_t oldfs;
        struct timespec ts; 
+
        oldfs = get_fs();
        set_fs(KERNEL_DS);
-       err = sys_clock_getres(which_clock, &ts); 
+       err = sys_clock_getres(which_clock,
+                              (struct timespec __user *) &ts);
        set_fs(oldfs);
        if (!err && put_compat_timespec(&ts, tp))
                return -EFAULT; 
@@ -528,11 +543,15 @@ long compat_clock_nanosleep(clockid_t which_clock, int flags,
        long err;
        mm_segment_t oldfs;
        struct timespec in, out; 
+
        if (get_compat_timespec(&in, rqtp)) 
                return -EFAULT;
+
        oldfs = get_fs();
-       set_fs(KERNEL_DS);      
-       err = sys_clock_nanosleep(which_clock, flags, &in, &out);  
+       set_fs(KERNEL_DS);
+       err = sys_clock_nanosleep(which_clock, flags,
+                                 (struct timespec __user *) &in,
+                                 (struct timespec __user *) &out);
        set_fs(oldfs);
        if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
            put_compat_timespec(&out, rmtp))
index c8611f1..af4b6af 100644 (file)
@@ -740,7 +740,7 @@ static void exit_notify(struct task_struct *tsk)
         * Clear these here so that update_process_times() won't try to deliver
         * itimer, profile or rlimit signals to this task while it is in late exit.
         */
-       tsk->it_virt_incr = 0;
+       tsk->it_virt_value = 0;
        tsk->it_prof_value = 0;
        tsk->rlim[RLIMIT_CPU].rlim_cur = RLIM_INFINITY;
 
@@ -841,10 +841,10 @@ asmlinkage long sys_exit(int error_code)
        do_exit((error_code&0xff)<<8);
 }
 
-task_t fastcall *next_thread(task_t *p)
+task_t fastcall *next_thread(const task_t *p)
 {
-       struct pid_link *link = p->pids + PIDTYPE_TGID;
-       struct list_head *tmp, *head = &link->pidptr->task_list;
+       const struct pid_link *link = p->pids + PIDTYPE_TGID;
+       const struct list_head *tmp, *head = &link->pidptr->task_list;
 
 #ifdef CONFIG_SMP
        if (!p->sighand)
index 559e6bb..84007a3 100644 (file)
@@ -271,7 +271,7 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm)
        struct vm_area_struct * mpnt, *tmp, **pprev;
        struct rb_node **rb_link, *rb_parent;
        int retval;
-       unsigned long charge = 0;
+       unsigned long charge;
        struct mempolicy *pol;
 
        down_write(&oldmm->mmap_sem);
@@ -304,11 +304,12 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm)
 
                if(mpnt->vm_flags & VM_DONTCOPY)
                        continue;
+               charge = 0;
                if (mpnt->vm_flags & VM_ACCOUNT) {
                        unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
                        if (security_vm_enough_memory(len))
                                goto fail_nomem;
-                       charge += len;
+                       charge = len;
                }
                tmp = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
                if (!tmp)
@@ -360,7 +361,7 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm)
                        tmp->vm_ops->open(tmp);
 
                if (retval)
-                       goto fail;
+                       goto out;
        }
        retval = 0;
 
@@ -372,10 +373,10 @@ fail_nomem_policy:
        kmem_cache_free(vm_area_cachep, tmp);
 fail_nomem:
        retval = -ENOMEM;
-fail:
        vm_unacct_memory(charge);
        goto out;
 }
+
 static inline int mm_alloc_pgd(struct mm_struct * mm)
 {
        mm->pgd = pgd_alloc(mm);
@@ -519,7 +520,7 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
                 * not set up a proper pointer then tough luck.
                 */
                put_user(0, tidptr);
-               sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL);
+               sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
        }
 }
 
index f7afaf5..abae250 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/futex.h>
 #include <linux/mount.h>
 #include <linux/pagemap.h>
+#include <linux/syscalls.h>
 
 #define FUTEX_HASHBITS 8
 
@@ -354,7 +355,7 @@ static int futex_requeue(unsigned long uaddr1, unsigned long uaddr2,
                   before *uaddr1.  */
                smp_mb();
 
-               if (get_user(curval, (int *)uaddr1) != 0) {
+               if (get_user(curval, (int __user *)uaddr1) != 0) {
                        ret = -EFAULT;
                        goto out;
                }
index 10d2e8f..ea62192 100644 (file)
@@ -47,7 +47,7 @@ static struct workqueue_struct *khelper_wq;
 /*
        modprobe_path is set via /proc/sys.
 */
-char modprobe_path[256] = "/sbin/modprobe";
+char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
 
 /**
  * request_module - try to load a kernel module
@@ -132,7 +132,7 @@ EXPORT_SYMBOL(request_module);
        events.  the command is expected to load drivers when
        necessary, and may perform additional system setup.
 */
-char hotplug_path[256] = "/sbin/hotplug";
+char hotplug_path[KMOD_PATH_LEN] = "/sbin/hotplug";
 
 EXPORT_SYMBOL(hotplug_path);
 
@@ -192,10 +192,20 @@ static int wait_for_helper(void *data)
        allow_signal(SIGCHLD);
 
        pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD);
-       if (pid < 0)
+       if (pid < 0) {
                sub_info->retval = pid;
-       else
-               sys_wait4(pid, &sub_info->retval, 0, NULL);
+       } else {
+               /*
+                * Normally it is bogus to call wait4() from in-kernel because
+                * wait4() wants to write the exit code to a userspace address.
+                * But wait_for_helper() always runs as keventd, and put_user()
+                * to a kernel address works OK for kernel threads, due to their
+                * having an mm_segment_t which spans the entire address space.
+                *
+                * Thus the __user pointer cast is valid here.
+                */
+               sys_wait4(pid, (int __user *) &sub_info->retval, 0, NULL);
+       }
 
        complete(sub_info->complete);
        return 0;
index e7a73ba..b96b139 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/stop_machine.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
-#include <asm/pgalloc.h>
 #include <asm/cacheflush.h>
 
 #if 0
@@ -717,7 +716,7 @@ static inline void module_unload_init(struct module *mod)
 }
 
 asmlinkage long
-sys_delete_module(const char *name_user, unsigned int flags)
+sys_delete_module(const char __user *name_user, unsigned int flags)
 {
        return -ENOSYS;
 }
index f846b77..50b7764 100644 (file)
@@ -397,7 +397,6 @@ static struct k_itimer * alloc_posix_timer(void)
        if (!tmr)
                return tmr;
        memset(tmr, 0, sizeof (struct k_itimer));
-       tmr->it_id = (timer_t)-1;
        if (unlikely(!(tmr->sigq = sigqueue_alloc()))) {
                kmem_cache_free(posix_timers_cache, tmr);
                tmr = 0;
@@ -405,9 +404,11 @@ static struct k_itimer * alloc_posix_timer(void)
        return tmr;
 }
 
-static void release_posix_timer(struct k_itimer *tmr)
+#define IT_ID_SET      1
+#define IT_ID_NOT_SET  0
+static void release_posix_timer(struct k_itimer *tmr, int it_id_set)
 {
-       if (tmr->it_id != -1) {
+       if (it_id_set) {
                unsigned long flags;
                spin_lock_irqsave(&idr_lock, flags);
                idr_remove(&posix_timers_id, tmr->it_id);
@@ -429,10 +430,11 @@ sys_timer_create(clockid_t which_clock,
 {
        int error = 0;
        struct k_itimer *new_timer = NULL;
-       timer_t new_timer_id;
+       int new_timer_id;
        struct task_struct *process = 0;
        unsigned long flags;
        sigevent_t event;
+       int it_id_set = IT_ID_NOT_SET;
 
        if ((unsigned) which_clock >= MAX_CLOCKS ||
                                !posix_clocks[which_clock].res)
@@ -443,19 +445,38 @@ sys_timer_create(clockid_t which_clock,
                return -EAGAIN;
 
        spin_lock_init(&new_timer->it_lock);
-       do {
-               if (unlikely(!idr_pre_get(&posix_timers_id, GFP_KERNEL))) {
-                       error = -EAGAIN;
-                       new_timer->it_id = (timer_t)-1;
-                       goto out;
-               }
-               spin_lock_irq(&idr_lock);
-               new_timer_id = (timer_t) idr_get_new(&posix_timers_id,
-                                                       (void *) new_timer);
-               spin_unlock_irq(&idr_lock);
-       } while (unlikely(new_timer_id == -1));
+ retry:
+       if (unlikely(!idr_pre_get(&posix_timers_id, GFP_KERNEL))) {
+               error = -EAGAIN;
+               goto out;
+       }
+       spin_lock_irq(&idr_lock);
+       error = idr_get_new(&posix_timers_id,
+                           (void *) new_timer,
+                           &new_timer_id);
+       spin_unlock_irq(&idr_lock);
+       if (error == -EAGAIN)
+               goto retry;
+       else if (error) {
+               /*
+                * Wierd looking, but we return EAGAIN if the IDR is
+                * full (proper POSIX return value for this)
+                */
+               error = -EAGAIN;
+               goto out;
+       }
+
+       it_id_set = IT_ID_SET;
+       new_timer->it_id = (timer_t) new_timer_id;
+       new_timer->it_clock = which_clock;
+       new_timer->it_incr = 0;
+       new_timer->it_overrun = -1;
+       init_timer(&new_timer->it_timer);
+       new_timer->it_timer.expires = 0;
+       new_timer->it_timer.data = (unsigned long) new_timer;
+       new_timer->it_timer.function = posix_timer_fn;
+       set_timer_inactive(new_timer);
 
-       new_timer->it_id = new_timer_id;
        /*
         * return the timer_id now.  The next step is hard to
         * back out if there is an error.
@@ -470,6 +491,10 @@ sys_timer_create(clockid_t which_clock,
                        error = -EFAULT;
                        goto out;
                }
+               new_timer->it_sigev_notify = event.sigev_notify;
+               new_timer->it_sigev_signo = event.sigev_signo;
+               new_timer->it_sigev_value = event.sigev_value;
+
                read_lock(&tasklist_lock);
                if ((process = good_sigevent(&event))) {
                        /*
@@ -489,6 +514,7 @@ sys_timer_create(clockid_t which_clock,
                         */
                        spin_lock_irqsave(&process->sighand->siglock, flags);
                        if (!(process->flags & PF_EXITING)) {
+                               new_timer->it_process = process;
                                list_add(&new_timer->list,
                                         &process->signal->posix_timers);
                                spin_unlock_irqrestore(&process->sighand->siglock, flags);
@@ -503,35 +529,27 @@ sys_timer_create(clockid_t which_clock,
                        error = -EINVAL;
                        goto out;
                }
-               new_timer->it_sigev_notify = event.sigev_notify;
-               new_timer->it_sigev_signo = event.sigev_signo;
-               new_timer->it_sigev_value = event.sigev_value;
        } else {
                new_timer->it_sigev_notify = SIGEV_SIGNAL;
                new_timer->it_sigev_signo = SIGALRM;
                new_timer->it_sigev_value.sival_int = new_timer->it_id;
                process = current->group_leader;
                spin_lock_irqsave(&process->sighand->siglock, flags);
+               new_timer->it_process = process;
                list_add(&new_timer->list, &process->signal->posix_timers);
                spin_unlock_irqrestore(&process->sighand->siglock, flags);
        }
 
-       new_timer->it_clock = which_clock;
-       new_timer->it_incr = 0;
-       new_timer->it_overrun = -1;
-       init_timer(&new_timer->it_timer);
-       new_timer->it_timer.expires = 0;
-       new_timer->it_timer.data = (unsigned long) new_timer;
-       new_timer->it_timer.function = posix_timer_fn;
-       set_timer_inactive(new_timer);
-
-       /*
-        * Once we set the process, it can be found so do it last...
+       /*
+        * In the case of the timer belonging to another task, after
+        * the task is unlocked, the timer is owned by the other task
+        * and may cease to exist at any time.  Don't use or modify
+        * new_timer after the unlock call.
         */
-       new_timer->it_process = process;
+
 out:
        if (error)
-               release_posix_timer(new_timer);
+               release_posix_timer(new_timer, it_id_set);
 
        return error;
 }
@@ -952,7 +970,7 @@ retry_delete:
        timer->it_process = NULL;
        }
        unlock_timer(timer, flags);
-       release_posix_timer(timer);
+       release_posix_timer(timer, IT_ID_SET);
        return 0;
 }
 /*
@@ -989,7 +1007,7 @@ retry_delete:
                timer->it_process = NULL;
        }
        unlock_timer(timer, flags);
-       release_posix_timer(timer);
+       release_posix_timer(timer, IT_ID_SET);
 }
 
 /*
index 22855ab..dd474cc 100644 (file)
@@ -732,19 +732,6 @@ int pmdisk_resume(void)
 
 /* More restore stuff */
 
-/* FIXME: Why not memcpy(to, from, 1<<pagedir_order*PAGE_SIZE)? */
-static void __init copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
-{
-       int i;
-       char *topointer=(char *)to, *frompointer=(char *)from;
-
-       for(i=0; i < 1 << pagedir_order; i++) {
-               copy_page(topointer, frompointer);
-               topointer += PAGE_SIZE;
-               frompointer += PAGE_SIZE;
-       }
-}
-
 #define does_collide(addr) does_collide_order(pm_pagedir_nosave, addr, 0)
 
 /*
@@ -792,9 +779,10 @@ static int __init relocate_pagedir(void)
         * We have to avoid recursion (not to overflow kernel stack),
         * and that's why code looks pretty cryptic 
         */
-       suspend_pagedir_t *new_pagedir, *old_pagedir = pm_pagedir_nosave;
+       suspend_pagedir_t *old_pagedir = pm_pagedir_nosave;
        void **eaten_memory = NULL;
        void **c = eaten_memory, *m, *f;
+       int err;
 
        pr_debug("pmdisk: Relocating pagedir\n");
 
@@ -803,32 +791,31 @@ static int __init relocate_pagedir(void)
                return 0;
        }
 
+       err = -ENOMEM;
        while ((m = (void *) __get_free_pages(GFP_ATOMIC, pagedir_order))) {
-               memset(m, 0, PAGE_SIZE);
-               if (!does_collide_order(old_pagedir, (unsigned long)m, pagedir_order))
+               if (!does_collide_order(old_pagedir, (unsigned long)m,
+                                       pagedir_order)) {
+                       pm_pagedir_nosave =
+                               memcpy(m, old_pagedir,
+                                      PAGE_SIZE << pagedir_order);
+                       err = 0;
                        break;
+               }
                eaten_memory = m;
                printk( "." ); 
                *eaten_memory = c;
                c = eaten_memory;
        }
 
-       if (!m)
-               return -ENOMEM;
-
-       pm_pagedir_nosave = new_pagedir = m;
-       copy_pagedir(new_pagedir, old_pagedir);
-
        c = eaten_memory;
        while(c) {
                printk(":");
-               f = *c;
+               f = c;
                c = *c;
-               if (f)
-                       free_pages((unsigned long)f, pagedir_order);
+               free_pages((unsigned long)f, pagedir_order);
        }
        printk("|\n");
-       return 0;
+       return err;
 }
 
 
index 752f6cd..ff8fdbc 100644 (file)
@@ -503,6 +503,9 @@ static int count_and_copy_zone(struct zone *zone, struct pbe **pagedir_p)
                if (!pbe)
                        continue;
                pbe->orig_address = (long) page_address(page);
+               /* Copy page is dangerous: it likes to mess with
+                  preempt count on specific cpus. Wrong preempt count is then copied,
+                  oops. */
                copy_page((void *)pbe->address, (void *)pbe->orig_address);
                pbe++;
        }
@@ -860,19 +863,6 @@ int software_suspend(void)
 
 /* More restore stuff */
 
-/* FIXME: Why not memcpy(to, from, 1<<pagedir_order*PAGE_SIZE)? */
-static void copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
-{
-       int i;
-       char *topointer=(char *)to, *frompointer=(char *)from;
-
-       for(i=0; i < 1 << pagedir_order; i++) {
-               copy_page(topointer, frompointer);
-               topointer += PAGE_SIZE;
-               frompointer += PAGE_SIZE;
-       }
-}
-
 #define does_collide(addr) does_collide_order(pagedir_nosave, addr, 0)
 
 /*
@@ -920,11 +910,12 @@ static int relocate_pagedir(void)
         * We have to avoid recursion (not to overflow kernel stack),
         * and that's why code looks pretty cryptic 
         */
-       suspend_pagedir_t *new_pagedir, *old_pagedir = pagedir_nosave;
+       suspend_pagedir_t *old_pagedir = pagedir_nosave;
        void **eaten_memory = NULL;
        void **c = eaten_memory, *m, *f;
+       int ret = 0;
 
-       printk("Relocating pagedir");
+       printk("Relocating pagedir ");
 
        if(!does_collide_order(old_pagedir, (unsigned long)old_pagedir, pagedir_order)) {
                printk("not necessary\n");
@@ -932,7 +923,6 @@ static int relocate_pagedir(void)
        }
 
        while ((m = (void *) __get_free_pages(GFP_ATOMIC, pagedir_order))) {
-               memset(m, 0, PAGE_SIZE);
                if (!does_collide_order(old_pagedir, (unsigned long)m, pagedir_order))
                        break;
                eaten_memory = m;
@@ -941,22 +931,23 @@ static int relocate_pagedir(void)
                c = eaten_memory;
        }
 
-       if (!m)
-               return -ENOMEM;
-
-       pagedir_nosave = new_pagedir = m;
-       copy_pagedir(new_pagedir, old_pagedir);
+       if (!m) {
+               printk("out of memory\n");
+               ret = -ENOMEM;
+       } else {
+               pagedir_nosave =
+                       memcpy(m, old_pagedir, PAGE_SIZE << pagedir_order);
+       }
 
        c = eaten_memory;
-       while(c) {
+       while (c) {
                printk(":");
-               f = *c;
+               f = c;
                c = *c;
-               if (f)
-                       free_pages((unsigned long)f, pagedir_order);
+               free_pages((unsigned long)f, pagedir_order);
        }
        printk("|\n");
-       return 0;
+       return ret;
 }
 
 /*
index f7a704e..da0ffd6 100644 (file)
@@ -332,8 +332,8 @@ int insert_resource(struct resource *parent, struct resource *new)
                if (next->sibling->start > new->end)
                        break;
 
-       /* existing resource overlaps end of new resource */
-       if (next->end > new->end) {
+       /* existing resource includes new resource */
+       if (next->end >= new->end) {
                parent = next;
                result = 0;
                goto begin;
index 305bdfa..5fc41f2 100644 (file)
@@ -547,7 +547,7 @@ static inline void resched_task(task_t *p)
  * task_curr - is this task currently executing on a CPU?
  * @p: the task in question.
  */
-inline int task_curr(task_t *p)
+inline int task_curr(const task_t *p)
 {
        return cpu_curr(task_cpu(p)) == p;
 }
@@ -763,6 +763,13 @@ static int try_to_wake_up(task_t * p, unsigned int state, int sync)
        load = source_load(cpu);
        this_load = target_load(this_cpu);
 
+       /*
+        * If sync wakeup then subtract the (maximum possible) effect of
+        * the currently running task from the load of the current CPU:
+        */
+       if (sync)
+               this_load -= SCHED_LOAD_SCALE;
+
        /* Don't pull the task off an idle CPU to a busy one */
        if (load < SCHED_LOAD_SCALE/2 && this_load > SCHED_LOAD_SCALE/2)
                goto out_set_cpu;
@@ -2654,7 +2661,7 @@ asmlinkage long sys_nice(int increment)
  * RT tasks are offset by -200. Normal tasks are centered
  * around 0, value goes from -16 to +15.
  */
-int task_prio(task_t *p)
+int task_prio(const task_t *p)
 {
        return p->prio - MAX_RT_PRIO;
 }
@@ -2663,7 +2670,7 @@ int task_prio(task_t *p)
  * task_nice - return the nice value of a given task.
  * @p: the task in question.
  */
-int task_nice(task_t *p)
+int task_nice(const task_t *p)
 {
        return TASK_NICE(p);
 }
@@ -3801,7 +3808,7 @@ void sched_domain_debug(void)
 
                sd = rq->sd;
 
-               printk(KERN_DEBUG "CPU%d: %s\n",
+               printk(KERN_WARNING "CPU%d: %s\n",
                                i, (cpu_online(i) ? " online" : "offline"));
 
                do {
@@ -3819,13 +3826,13 @@ void sched_domain_debug(void)
                        printk("domain %d: span %s\n", level, str);
 
                        if (!cpu_isset(i, sd->span))
-                               printk(KERN_DEBUG "ERROR domain->span does not contain CPU%d\n", i);
+                               printk(KERN_WARNING "ERROR domain->span does not contain CPU%d\n", i);
                        if (!cpu_isset(i, group->cpumask))
-                               printk(KERN_DEBUG "ERROR domain->groups does not contain CPU%d\n", i);
+                               printk(KERN_WARNING "ERROR domain->groups does not contain CPU%d\n", i);
                        if (!group->cpu_power)
-                               printk(KERN_DEBUG "ERROR domain->cpu_power not set\n");
+                               printk(KERN_WARNING "ERROR domain->cpu_power not set\n");
 
-                       printk(KERN_DEBUG);
+                       printk(KERN_WARNING);
                        for (j = 0; j < level + 2; j++)
                                printk(" ");
                        printk("groups:");
@@ -3860,7 +3867,7 @@ void sched_domain_debug(void)
                        if (sd) {
                                cpus_and(tmp, groupmask, sd->span);
                                if (!cpus_equal(tmp, groupmask))
-                                       printk(KERN_DEBUG "ERROR parent span is not a superset of domain->span\n");
+                                       printk(KERN_WARNING "ERROR parent span is not a superset of domain->span\n");
                        }
 
                } while (sd);
index a8d18f4..078fc95 100644 (file)
@@ -32,9 +32,6 @@
 
 static kmem_cache_t *sigqueue_cachep;
 
-atomic_t nr_queued_signals;
-int max_queued_signals = 1024;
-
 /*
  * In POSIX a signal is sent either to a specific thread (Linux task)
  * or to the process as a whole (Linux thread group).  How the signal
@@ -265,17 +262,19 @@ next_signal(struct sigpending *pending, sigset_t *mask)
        return sig;
 }
 
-struct sigqueue *__sigqueue_alloc(void)
+static struct sigqueue *__sigqueue_alloc(void)
 {
        struct sigqueue *q = 0;
 
-       if (atomic_read(&nr_queued_signals) < max_queued_signals)
+       if (atomic_read(&current->user->sigpending) <
+                       current->rlim[RLIMIT_SIGPENDING].rlim_cur)
                q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);
        if (q) {
-               atomic_inc(&nr_queued_signals);
                INIT_LIST_HEAD(&q->list);
                q->flags = 0;
                q->lock = 0;
+               q->user = get_uid(current->user);
+               atomic_inc(&q->user->sigpending);
        }
        return(q);
 }
@@ -284,8 +283,9 @@ static inline void __sigqueue_free(struct sigqueue *q)
 {
        if (q->flags & SIGQUEUE_PREALLOC)
                return;
+       atomic_dec(&q->user->sigpending);
+       free_uid(q->user);
        kmem_cache_free(sigqueue_cachep, q);
-       atomic_dec(&nr_queued_signals);
 }
 
 static void flush_sigqueue(struct sigpending *queue)
@@ -700,7 +700,8 @@ static void handle_stop_signal(int sig, struct task_struct *p)
        }
 }
 
-static int send_signal(int sig, struct siginfo *info, struct sigpending *signals)
+static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
+                       struct sigpending *signals)
 {
        struct sigqueue * q = NULL;
        int ret = 0;
@@ -720,12 +721,14 @@ static int send_signal(int sig, struct siginfo *info, struct sigpending *signals
           make sure at least one signal gets delivered and don't
           pass on the info struct.  */
 
-       if (atomic_read(&nr_queued_signals) < max_queued_signals)
+       if (atomic_read(&t->user->sigpending) <
+                       t->rlim[RLIMIT_SIGPENDING].rlim_cur)
                q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);
 
        if (q) {
-               atomic_inc(&nr_queued_signals);
                q->flags = 0;
+               q->user = get_uid(t->user);
+               atomic_inc(&q->user->sigpending);
                list_add_tail(&q->list, &signals->list);
                switch ((unsigned long) info) {
                case 0:
@@ -799,7 +802,7 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
        if (LEGACY_QUEUE(&t->pending, sig))
                goto out;
 
-       ret = send_signal(sig, info, &t->pending);
+       ret = send_signal(sig, info, t, &t->pending);
        if (!ret && !sigismember(&t->blocked, sig))
                signal_wake_up(t, sig == SIGKILL);
 out:
@@ -1000,7 +1003,7 @@ __group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
         * We always use the shared queue for process-wide signals,
         * to avoid several races.
         */
-       ret = send_signal(sig, info, &p->signal->shared_pending);
+       ret = send_signal(sig, info, p, &p->signal->shared_pending);
        if (unlikely(ret))
                return ret;
 
@@ -1072,23 +1075,19 @@ int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
        struct task_struct *p;
        struct list_head *l;
        struct pid *pid;
-       int retval;
-       int found;
+       int retval, success;
 
        if (pgrp <= 0)
                return -EINVAL;
 
-       found = 0;
-       retval = 0;
+       success = 0;
+       retval = -ESRCH;
        for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) {
-               int err;
-
-               found = 1;
-               err = group_send_sig_info(sig, info, p);
-               if (!retval)
-                       retval = err;
+               int err = group_send_sig_info(sig, info, p);
+               success |= !err;
+               retval = err;
        }
-       return found ? retval : -ESRCH;
+       return success ? 0 : retval;
 }
 
 int
@@ -2511,10 +2510,9 @@ sys_sigprocmask(int how, old_sigset_t __user *set, old_sigset_t __user *oset)
 out:
        return error;
 }
+#endif /* __ARCH_WANT_SYS_SIGPROCMASK */
 
-#endif /* SIGPROCMASK */
-
-#ifndef __sparc__
+#ifdef __ARCH_WANT_SYS_RT_SIGACTION
 asmlinkage long
 sys_rt_sigaction(int sig,
                 const struct sigaction __user *act,
@@ -2542,7 +2540,7 @@ sys_rt_sigaction(int sig,
 out:
        return ret;
 }
-#endif /* __sparc__ */
+#endif /* __ARCH_WANT_SYS_RT_SIGACTION */
 
 #ifdef __ARCH_WANT_SYS_SGETMASK
 
index 75f3c3d..e168f36 100644 (file)
@@ -53,8 +53,6 @@ extern int C_A_D;
 extern int sysctl_overcommit_memory;
 extern int sysctl_overcommit_ratio;
 extern int max_threads;
-extern atomic_t nr_queued_signals;
-extern int max_queued_signals;
 extern int sysrq_enabled;
 extern int core_uses_pid;
 extern char core_pattern[];
@@ -241,7 +239,7 @@ static ctl_table kern_table[] = {
                .ctl_name       = KERN_OSTYPE,
                .procname       = "ostype",
                .data           = system_utsname.sysname,
-               .maxlen         = 64,
+               .maxlen         = sizeof(system_utsname.sysname),
                .mode           = 0444,
                .proc_handler   = &proc_doutsstring,
                .strategy       = &sysctl_string,
@@ -250,7 +248,7 @@ static ctl_table kern_table[] = {
                .ctl_name       = KERN_OSRELEASE,
                .procname       = "osrelease",
                .data           = system_utsname.release,
-               .maxlen         = 64,
+               .maxlen         = sizeof(system_utsname.release),
                .mode           = 0444,
                .proc_handler   = &proc_doutsstring,
                .strategy       = &sysctl_string,
@@ -259,7 +257,7 @@ static ctl_table kern_table[] = {
                .ctl_name       = KERN_VERSION,
                .procname       = "version",
                .data           = system_utsname.version,
-               .maxlen         = 64,
+               .maxlen         = sizeof(system_utsname.version),
                .mode           = 0444,
                .proc_handler   = &proc_doutsstring,
                .strategy       = &sysctl_string,
@@ -268,7 +266,7 @@ static ctl_table kern_table[] = {
                .ctl_name       = KERN_NODENAME,
                .procname       = "hostname",
                .data           = system_utsname.nodename,
-               .maxlen         = 64,
+               .maxlen         = sizeof(system_utsname.nodename),
                .mode           = 0644,
                .proc_handler   = &proc_doutsstring,
                .strategy       = &sysctl_string,
@@ -277,7 +275,7 @@ static ctl_table kern_table[] = {
                .ctl_name       = KERN_DOMAINNAME,
                .procname       = "domainname",
                .data           = system_utsname.domainname,
-               .maxlen         = 64,
+               .maxlen         = sizeof(system_utsname.domainname),
                .mode           = 0644,
                .proc_handler   = &proc_doutsstring,
                .strategy       = &sysctl_string,
@@ -449,7 +447,7 @@ static ctl_table kern_table[] = {
                .ctl_name       = KERN_MODPROBE,
                .procname       = "modprobe",
                .data           = &modprobe_path,
-               .maxlen         = 256,
+               .maxlen         = KMOD_PATH_LEN,
                .mode           = 0644,
                .proc_handler   = &proc_dostring,
                .strategy       = &sysctl_string,
@@ -460,7 +458,7 @@ static ctl_table kern_table[] = {
                .ctl_name       = KERN_HOTPLUG,
                .procname       = "hotplug",
                .data           = &hotplug_path,
-               .maxlen         = 256,
+               .maxlen         = KMOD_PATH_LEN,
                .mode           = 0644,
                .proc_handler   = &proc_dostring,
                .strategy       = &sysctl_string,
@@ -486,22 +484,6 @@ static ctl_table kern_table[] = {
                .proc_handler   = &proc_dointvec,
        },
 #endif
-       {
-               .ctl_name       = KERN_RTSIGNR,
-               .procname       = "rtsig-nr",
-               .data           = &nr_queued_signals,
-               .maxlen         = sizeof(int),
-               .mode           = 0444,
-               .proc_handler   = &proc_dointvec,
-       },
-       {
-               .ctl_name       = KERN_RTSIGMAX,
-               .procname       = "rtsig-max",
-               .data           = &max_queued_signals,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
-       },
 #ifdef CONFIG_SYSVIPC
        {
                .ctl_name       = KERN_SHMMAX,
@@ -1966,56 +1948,56 @@ int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
 #else /* CONFIG_PROC_FS */
 
 int proc_dostring(ctl_table *table, int write, struct file *filp,
-                 void *buffer, size_t *lenp)
+                 void __user *buffer, size_t *lenp)
 {
        return -ENOSYS;
 }
 
 static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
-                           void *buffer, size_t *lenp)
+                           void __user *buffer, size_t *lenp)
 {
        return -ENOSYS;
 }
 
 int proc_dointvec(ctl_table *table, int write, struct file *filp,
-                 void *buffer, size_t *lenp)
+                 void __user *buffer, size_t *lenp)
 {
        return -ENOSYS;
 }
 
 int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
-                       void *buffer, size_t *lenp)
+                       void __user *buffer, size_t *lenp)
 {
        return -ENOSYS;
 }
 
 int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
-                   void *buffer, size_t *lenp)
+                   void __user *buffer, size_t *lenp)
 {
        return -ENOSYS;
 }
 
 int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
-                   void *buffer, size_t *lenp)
+                   void __user *buffer, size_t *lenp)
 {
        return -ENOSYS;
 }
 
 int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
-                   void *buffer, size_t *lenp)
+                   void __user *buffer, size_t *lenp)
 {
        return -ENOSYS;
 }
 
 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
-                   void *buffer, size_t *lenp)
+                   void __user *buffer, size_t *lenp)
 {
        return -ENOSYS;
 }
 
 int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
                                      struct file *filp,
-                                     void *buffer, size_t *lenp)
+                                     void __user *buffer, size_t *lenp)
 {
     return -ENOSYS;
 }
@@ -2190,13 +2172,13 @@ int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
 }
 
 int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
-                         void *buffer, size_t *lenp)
+                         void __user *buffer, size_t *lenp)
 {
        return -ENOSYS;
 }
 
 int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
-                         void *buffer, size_t *lenp)
+                         void __user *buffer, size_t *lenp)
 {
        return -ENOSYS;
 }
index 3a8162b..56b315b 100644 (file)
@@ -829,7 +829,7 @@ static inline void do_it_prof(struct task_struct *p)
        }
 }
 
-void update_one_process(struct task_struct *p, unsigned long user,
+static void update_one_process(struct task_struct *p, unsigned long user,
                        unsigned long system, int cpu)
 {
        do_process_times(p, user, system);
index 5ebaa3d..f669941 100644 (file)
@@ -39,7 +39,7 @@ asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid)
 
 asmlinkage long sys_setgid16(old_gid_t gid)
 {
-       return sys_setgid((gid_t)gid);
+       return sys_setgid(low2highgid(gid));
 }
 
 asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid)
@@ -49,7 +49,7 @@ asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid)
 
 asmlinkage long sys_setuid16(old_uid_t uid)
 {
-       return sys_setuid((uid_t)uid);
+       return sys_setuid(low2highuid(uid));
 }
 
 asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid)
@@ -88,12 +88,12 @@ asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid,
 
 asmlinkage long sys_setfsuid16(old_uid_t uid)
 {
-       return sys_setfsuid((uid_t)uid);
+       return sys_setfsuid(low2highuid(uid));
 }
 
 asmlinkage long sys_setfsgid16(old_gid_t gid)
 {
-       return sys_setfsgid((gid_t)gid);
+       return sys_setfsgid(low2highgid(gid));
 }
 
 static int groups16_to_user(old_gid_t __user *grouplist,
@@ -103,7 +103,7 @@ static int groups16_to_user(old_gid_t __user *grouplist,
        old_gid_t group;
 
        for (i = 0; i < group_info->ngroups; i++) {
-               group = (old_gid_t)GROUP_AT(group_info, i);
+               group = high2lowgid(GROUP_AT(group_info, i));
                if (put_user(group, grouplist+i))
                        return -EFAULT;
        }
@@ -120,7 +120,7 @@ static int groups16_from_user(struct group_info *group_info,
        for (i = 0; i < group_info->ngroups; i++) {
                if (get_user(group, grouplist+i))
                        return  -EFAULT;
-               GROUP_AT(group_info, i) = (gid_t)group;
+               GROUP_AT(group_info, i) = low2highgid(group);
        }
 
        return 0;
index 60e942b..9f9859e 100644 (file)
@@ -30,7 +30,9 @@ static spinlock_t uidhash_lock = SPIN_LOCK_UNLOCKED;
 struct user_struct root_user = {
        .__count        = ATOMIC_INIT(1),
        .processes      = ATOMIC_INIT(1),
-       .files          = ATOMIC_INIT(0)
+       .files          = ATOMIC_INIT(0),
+       .sigpending     = ATOMIC_INIT(0),
+       .mq_bytes       = 0
 };
 
 /*
@@ -108,6 +110,9 @@ struct user_struct * alloc_uid(uid_t uid)
                atomic_set(&new->__count, 1);
                atomic_set(&new->processes, 0);
                atomic_set(&new->files, 0);
+               atomic_set(&new->sigpending, 0);
+
+               new->mq_bytes = 0;
 
                /*
                 * Before adding this, check whether we raced
index b4beaca..987fbc2 100644 (file)
@@ -218,6 +218,33 @@ static int worker_thread(void *__cwq)
        return 0;
 }
 
+static void flush_cpu_workqueue(struct cpu_workqueue_struct *cwq)
+{
+       if (cwq->thread == current) {
+               /*
+                * Probably keventd trying to flush its own queue. So simply run
+                * it by hand rather than deadlocking.
+                */
+               run_workqueue(cwq);
+       } else {
+               DEFINE_WAIT(wait);
+               long sequence_needed;
+
+               spin_lock_irq(&cwq->lock);
+               sequence_needed = cwq->insert_sequence;
+
+               while (sequence_needed - cwq->remove_sequence > 0) {
+                       prepare_to_wait(&cwq->work_done, &wait,
+                                       TASK_UNINTERRUPTIBLE);
+                       spin_unlock_irq(&cwq->lock);
+                       schedule();
+                       spin_lock_irq(&cwq->lock);
+               }
+               finish_wait(&cwq->work_done, &wait);
+               spin_unlock_irq(&cwq->lock);
+       }
+}
+
 /*
  * flush_workqueue - ensure that any scheduled work has run to completion.
  *
@@ -234,43 +261,19 @@ static int worker_thread(void *__cwq)
  */
 void fastcall flush_workqueue(struct workqueue_struct *wq)
 {
-       struct cpu_workqueue_struct *cwq;
-       int cpu;
-
        might_sleep();
 
-       lock_cpu_hotplug();
-       for_each_online_cpu(cpu) {
-               DEFINE_WAIT(wait);
-               long sequence_needed;
-
-               if (is_single_threaded(wq))
-                       cwq = wq->cpu_wq + 0; /* Always use cpu 0's area. */
-               else
-                       cwq = wq->cpu_wq + cpu;
-
-               if (cwq->thread == current) {
-                       /*
-                        * Probably keventd trying to flush its own queue.
-                        * So simply run it by hand rather than deadlocking.
-                        */
-                       run_workqueue(cwq);
-                       continue;
-               }
-               spin_lock_irq(&cwq->lock);
-               sequence_needed = cwq->insert_sequence;
+       if (is_single_threaded(wq)) {
+               /* Always use cpu 0's area. */
+               flush_cpu_workqueue(wq->cpu_wq + 0);
+       } else {
+               int cpu;
 
-               while (sequence_needed - cwq->remove_sequence > 0) {
-                       prepare_to_wait(&cwq->work_done, &wait,
-                                       TASK_UNINTERRUPTIBLE);
-                       spin_unlock_irq(&cwq->lock);
-                       schedule();
-                       spin_lock_irq(&cwq->lock);
-               }
-               finish_wait(&cwq->work_done, &wait);
-               spin_unlock_irq(&cwq->lock);
+               lock_cpu_hotplug();
+               for_each_online_cpu(cpu)
+                       flush_cpu_workqueue(wq->cpu_wq + cpu);
+               unlock_cpu_hotplug();
        }
-       unlock_cpu_hotplug();
 }
 
 static struct task_struct *create_workqueue_thread(struct workqueue_struct *wq,
index 8cdc5e8..cd4d138 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
  * so you don't need to be too concerned about locking and conflicts
  * with the slab allocator.
 
- * A word on reuse.  We reuse empty id slots as soon as we can, always
- * using the lowest one available.  But we also merge a counter in the
- * high bits of the id.  The counter is RESERVED_ID_BITS (8 at this time)
- * long.  This means that if you allocate and release the same id in a 
- * loop we will reuse an id after about 256 times around the loop.  The
- * word about is used here as we will NOT return a valid id of -1 so if
- * you loop on the largest possible id (and that is 24 bits, wow!) we
- * will kick the counter to avoid -1.  (Paranoid?  You bet!)
- *
  * What you need to do is, since we don't keep the counter as part of
  * id / ptr pair, to keep a copy of it in the pointed to structure
  * (or else where) so that when you ask for a ptr you can varify that
  *   sleep, so must not be called with any spinlocks held.  If the system is
  *   REALLY out of memory this function returns 0, other wise 1.
 
- * int idr_get_new(struct idr *idp, void *ptr);
+ * int idr_get_new(struct idr *idp, void *ptr, int *id);
  
  *   This is the allocate id function.  It should be called with any
  *   required locks.  In fact, in the SMP case, you MUST lock prior to
- *   calling this function to avoid possible out of memory problems.  If
- *   memory is required, it will return a -1, in which case you should
- *   unlock and go back to the idr_pre_get() call.  ptr is the pointer
- *   you want associated with the id.  In other words:
+ *   calling this function to avoid possible out of memory problems.
+ *   If memory is required, it will return -EAGAIN, you should unlock
+ *   and go back to the idr_pre_get() call.  If the idr is full, it
+ *   will return a -ENOSPC.  ptr is the pointer you want associated
+ *   with the id.  The value is returned in the "id" field.  idr_get_new()
+ *   returns a value in the range 0 ... 0x7fffffff
+
+ * int idr_get_new_above(struct idr *idp, void *ptr, int start_id, int *id);
+
+ *   Like idr_get_new(), but the returned id is guaranteed to be at or
+ *   above start_id.
 
  * void *idr_find(struct idr *idp, int id);
  
  *   removes the given id, freeing that slot and any memory that may
  *   now be unused.  See idr_find() for locking restrictions.
 
+ * int idr_full(struct idr *idp);
+
+ *   Returns true if the idr is full and false if not.
+
  */
 
 
@@ -115,7 +117,7 @@ static struct idr_layer *alloc_layer(struct idr *idp)
 
        spin_lock(&idp->lock);
        if (!(p = idp->id_free))
-               BUG();
+               return NULL;
        idp->id_free = p->ary[0];
        idp->id_free_cnt--;
        p->ary[0] = 0;
@@ -181,8 +183,8 @@ static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
                        sh = IDR_BITS*l;
                        id = ((id >> sh) ^ n ^ m) << sh;
                }
-               if (id >= MAX_ID_BIT)
-                       return -1;
+               if ((id >= MAX_ID_BIT) || (id < 0))
+                       return -3;
                if (l == 0)
                        break;
                /*
@@ -220,7 +222,7 @@ static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
        return(id);
 }
 
-int idr_get_new_above(struct idr *idp, void *ptr, int starting_id)
+static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
 {
        struct idr_layer *p, *new;
        int layers, v, id;
@@ -238,7 +240,7 @@ build_up:
         * Add a new layer to the top of the tree if the requested
         * id is larger than the currently allocated space.
         */
-       while (id >= (1 << (layers*IDR_BITS))) {
+       while ((layers < MAX_LEVEL) && (id >= (1 << (layers*IDR_BITS)))) {
                layers++;
                if (!p->count)
                        continue;
@@ -266,23 +268,47 @@ build_up:
        v = sub_alloc(idp, ptr, &id);
        if (v == -2)
                goto build_up;
-       if ( likely(v >= 0 )) {
-               idp->count++;
-               v += (idp->count << MAX_ID_SHIFT);
-               if ( unlikely( v == -1 ))
-                    v += (1L << MAX_ID_SHIFT);
-       }
        return(v);
 }
+
+int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
+{
+       int rv;
+       rv = idr_get_new_above_int(idp, ptr, starting_id);
+       /*
+        * This is a cheap hack until the IDR code can be fixed to
+        * return proper error values.
+        */
+       if (rv < 0) {
+               if (rv == -1)
+                       return -EAGAIN;
+               else /* Will be -3 */
+                       return -ENOSPC;
+       }
+       *id = rv;
+       return 0;
+}
 EXPORT_SYMBOL(idr_get_new_above);
 
-int idr_get_new(struct idr *idp, void *ptr)
+int idr_get_new(struct idr *idp, void *ptr, int *id)
 {
-       return idr_get_new_above(idp, ptr, 0);
+       int rv;
+       rv = idr_get_new_above_int(idp, ptr, 0);
+       /*
+        * This is a cheap hack until the IDR code can be fixed to
+        * return proper error values.
+        */
+       if (rv < 0) {
+               if (rv == -1)
+                       return -EAGAIN;
+               else /* Will be -3 */
+                       return -ENOSPC;
+       }
+       *id = rv;
+       return 0;
 }
 EXPORT_SYMBOL(idr_get_new);
 
-
 static void sub_remove(struct idr *idp, int shift, int id)
 {
        struct idr_layer *p = idp->top;
@@ -311,10 +337,14 @@ static void sub_remove(struct idr *idp, int shift, int id)
                        idp->layers = 0;
        }
 }
+
 void idr_remove(struct idr *idp, int id)
 {
        struct idr_layer *p;
 
+       /* Mask off upper bits we don't use for the search. */
+       id &= MAX_ID_MASK;
+
        sub_remove(idp, (idp->layers - 1) * IDR_BITS, id);
        if ( idp->top && idp->top->count == 1 && 
             (idp->layers > 1) &&
@@ -350,6 +380,9 @@ void *idr_find(struct idr *idp, int id)
        if ( unlikely( (id & ~(~0 << MAX_ID_SHIFT)) >> (n + IDR_BITS)))
             return NULL;
 #endif
+       /* Mask off upper bits we don't use for the search. */
+       id &= MAX_ID_MASK;
+
        while (n > 0 && p) {
                n -= IDR_BITS;
                p = p->ary[(id >> n) & IDR_MASK];
index ce15eb0..27dcd95 100644 (file)
@@ -29,15 +29,15 @@ void rwsemtrace(struct rw_semaphore *sem, const char *str)
 
 /*
  * handle the lock being released whilst there are processes blocked on it that can now run
- * - if we come here, then:
- *   - the 'active part' of the count (&0x0000ffff) reached zero but has been re-incremented
+ * - if we come here from up_xxxx(), then:
+ *   - the 'active part' of the count (&0x0000ffff) had reached zero (but may have changed)
  *   - the 'waiting part' of the count (&0xffff0000) is negative (and will still be so)
  *   - there must be someone on the queue
  * - the spinlock must be held by the caller
  * - woken process blocks are discarded from the list after having task zeroed
- * - writers are only woken if wakewrite is non-zero
+ * - writers are only woken if downgrading is false
  */
-static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int wakewrite)
+static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int downgrading)
 {
        struct rwsem_waiter *waiter;
        struct task_struct *tsk;
@@ -46,10 +46,12 @@ static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int
 
        rwsemtrace(sem,"Entering __rwsem_do_wake");
 
-       if (!wakewrite)
+       if (downgrading)
                goto dont_wake_writers;
 
-       /* only wake someone up if we can transition the active part of the count from 0 -> 1 */
+       /* if we came through an up_xxxx() call, we only only wake someone up
+        * if we can transition the active part of the count from 0 -> 1
+        */
  try_again:
        oldcount = rwsem_atomic_update(RWSEM_ACTIVE_BIAS,sem) - RWSEM_ACTIVE_BIAS;
        if (oldcount & RWSEM_ACTIVE_MASK)
@@ -78,9 +80,10 @@ static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int
        if (waiter->flags & RWSEM_WAITING_FOR_WRITE)
                goto out;
 
-       /* grant an infinite number of read locks to the readers at the front of the queue
-        * - note we increment the 'active part' of the count by the number of readers (less one
-        *   for the activity decrement we've already done) before waking any processes up
+       /* grant an infinite number of read locks to the readers at the front
+        * of the queue
+        * - note we increment the 'active part' of the count by the number of
+        *   readers before waking any processes up
         */
  readers_only:
        woken = 0;
@@ -95,8 +98,10 @@ static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int
        } while (waiter->flags & RWSEM_WAITING_FOR_READ);
 
        loop = woken;
-       woken *= RWSEM_ACTIVE_BIAS-RWSEM_WAITING_BIAS;
-       woken -= RWSEM_ACTIVE_BIAS;
+       woken *= RWSEM_ACTIVE_BIAS - RWSEM_WAITING_BIAS;
+       if (!downgrading)
+               woken -= RWSEM_ACTIVE_BIAS; /* we'd already done one increment
+                                            * earlier */
        rwsem_atomic_add(woken,sem);
 
        next = sem->wait_list.next;
@@ -150,7 +155,7 @@ static inline struct rw_semaphore *rwsem_down_failed_common(struct rw_semaphore
         * - it might even be this process, since the waker takes a more active part
         */
        if (!(count & RWSEM_ACTIVE_MASK))
-               sem = __rwsem_do_wake(sem,1);
+               sem = __rwsem_do_wake(sem, 0);
 
        spin_unlock(&sem->wait_lock);
 
@@ -201,7 +206,7 @@ struct rw_semaphore fastcall __sched *rwsem_down_write_failed(struct rw_semaphor
 
 /*
  * handle waking up a waiter on the semaphore
- * - up_read has decremented the active part of the count if we come here
+ * - up_read/up_write has decremented the active part of the count if we come here
  */
 struct rw_semaphore fastcall *rwsem_wake(struct rw_semaphore *sem)
 {
@@ -211,7 +216,7 @@ struct rw_semaphore fastcall *rwsem_wake(struct rw_semaphore *sem)
 
        /* do nothing if list empty */
        if (!list_empty(&sem->wait_list))
-               sem = __rwsem_do_wake(sem,1);
+               sem = __rwsem_do_wake(sem, 0);
 
        spin_unlock(&sem->wait_lock);
 
@@ -233,7 +238,7 @@ struct rw_semaphore fastcall *rwsem_downgrade_wake(struct rw_semaphore *sem)
 
        /* do nothing if list empty */
        if (!list_empty(&sem->wait_list))
-               sem = __rwsem_do_wake(sem,0);
+               sem = __rwsem_do_wake(sem, 1);
 
        spin_unlock(&sem->wait_lock);
 
index 603c717..d4dbd2c 100644 (file)
@@ -162,7 +162,7 @@ char * strncat(char *dest, const char *src, size_t count)
        if (count) {
                while (*dest)
                        dest++;
-               while ((*dest++ = *src++)) {
+               while ((*dest++ = *src++) != 0) {
                        if (--count == 0) {
                                *dest = '\0';
                                break;
index b6d2833..4969239 100644 (file)
@@ -40,11 +40,14 @@ unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
                if (*cp == '0') {
                        base = 8;
                        cp++;
-                       if ((*cp == 'x') && isxdigit(cp[1])) {
+                       if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
                                cp++;
                                base = 16;
                        }
                }
+       } else if (base == 16) {
+               if (cp[0] == '0' && toupper(cp[1]) == 'X')
+                       cp += 2;
        }
        while (isxdigit(*cp) &&
               (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
@@ -88,11 +91,14 @@ unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
                if (*cp == '0') {
                        base = 8;
                        cp++;
-                       if ((*cp == 'x') && isxdigit(cp[1])) {
+                       if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
                                cp++;
                                base = 16;
                        }
                }
+       } else if (base == 16) {
+               if (cp[0] == '0' && toupper(cp[1]) == 'X')
+                       cp += 2;
        }
        while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
            ? toupper(*cp) : *cp)-'A'+10) < base) {
index 248ec21..2b57176 100644 (file)
@@ -651,7 +651,8 @@ void do_generic_mapping_read(struct address_space *mapping,
                             int nonblock)
 {
        struct inode *inode = mapping->host;
-       unsigned long index, offset;
+       unsigned long index, end_index, offset;
+       loff_t isize;
        struct page *cached_page;
        int error;
        struct file_ra_state ra = *_ra;
@@ -660,26 +661,18 @@ void do_generic_mapping_read(struct address_space *mapping,
        index = *ppos >> PAGE_CACHE_SHIFT;
        offset = *ppos & ~PAGE_CACHE_MASK;
 
+       isize = i_size_read(inode);
+       end_index = isize >> PAGE_CACHE_SHIFT;
+       if (index > end_index)
+               goto out;
+
        for (;;) {
                struct page *page;
-               unsigned long end_index, nr, ret;
-               loff_t isize = i_size_read(inode);
-
-               end_index = isize >> PAGE_CACHE_SHIFT;
-                       
-               if (index > end_index)
-                       break;
-               nr = PAGE_CACHE_SIZE;
-               if (index == end_index) {
-                       nr = isize & ~PAGE_CACHE_MASK;
-                       if (nr <= offset)
-                               break;
-               }
+               unsigned long nr, ret;
 
                cond_resched();
                page_cache_readahead(mapping, &ra, filp, index);
 
-               nr = nr - offset;
 find_page:
                page = find_get_page(mapping, index);
                if (unlikely(page == NULL)) {
@@ -699,6 +692,17 @@ find_page:
                        goto page_not_up_to_date;
                }
 page_ok:
+               /* nr is the maximum number of bytes to copy from this page */
+               nr = PAGE_CACHE_SIZE;
+               if (index == end_index) {
+                       nr = isize & ~PAGE_CACHE_MASK;
+                       if (nr <= offset) {
+                               page_cache_release(page);
+                               goto out;
+                       }
+               }
+               nr = nr - offset;
+
                /* If users can be writing to this page using arbitrary
                 * virtual addresses, take care about potential aliasing
                 * before reading the page on the kernel side.
@@ -730,7 +734,7 @@ page_ok:
                page_cache_release(page);
                if (ret == nr && desc->count)
                        continue;
-               break;
+               goto out;
 
 page_not_up_to_date:
                /* Get exclusive access to the page ... */
@@ -750,22 +754,41 @@ page_not_up_to_date:
                }
 
 readpage:
-               /* ... and start the actual read. The read will unlock the page. */
+               /* Start the actual read. The read will unlock the page. */
                error = mapping->a_ops->readpage(filp, page);
 
-               if (!error) {
-                       if (PageUptodate(page))
-                               goto page_ok;
+               if (unlikely(error))
+                       goto readpage_error;
+
+               if (!PageUptodate(page)) {
                        wait_on_page_locked(page);
-                       if (PageUptodate(page))
-                               goto page_ok;
-                       error = -EIO;
+                       if (!PageUptodate(page)) {
+                               error = -EIO;
+                               goto readpage_error;
+                       }
                }
 
+               /*
+                * i_size must be checked after we have done ->readpage.
+                *
+                * Checking i_size after the readpage allows us to calculate
+                * the correct value for "nr", which means the zero-filled
+                * part of the page is not copied back to userspace (unless
+                * another truncate extends the file - this is desired though).
+                */
+               isize = i_size_read(inode);
+               end_index = isize >> PAGE_CACHE_SHIFT;
+               if (index > end_index) {
+                       page_cache_release(page);
+                       goto out;
+               }
+               goto page_ok;
+
+readpage_error:
                /* UHHUH! A synchronous read error occurred. Report it */
                desc->error = error;
                page_cache_release(page);
-               break;
+               goto out;
 
 no_cached_page:
                /*
@@ -776,7 +799,7 @@ no_cached_page:
                        cached_page = page_cache_alloc_cold(mapping);
                        if (!cached_page) {
                                desc->error = -ENOMEM;
-                               break;
+                               goto out;
                        }
                }
                error = add_to_page_cache_lru(cached_page, mapping,
@@ -785,13 +808,14 @@ no_cached_page:
                        if (error == -EEXIST)
                                goto find_page;
                        desc->error = error;
-                       break;
+                       goto out;
                }
                page = cached_page;
                cached_page = NULL;
                goto readpage;
        }
 
+out:
        *_ra = ra;
 
        *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
@@ -1902,7 +1926,7 @@ generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
                count -= written;
        }
 
-       buf = iov->iov_base;
+       buf = iov->iov_base + written;  /* handle partial DIO write */
        do {
                unsigned long index;
                unsigned long offset;
index 8eefa7a..6bf423f 100644 (file)
@@ -155,6 +155,7 @@ asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
        unsigned long end = start + size;
        struct vm_area_struct *vma;
        int err = -EINVAL;
+       int has_write_lock = 0;
 
        if (__prot)
                return err;
@@ -175,7 +176,8 @@ asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
 #endif
 
        /* We need down_write() to change vma->vm_flags. */
-       down_write(&mm->mmap_sem);
+       down_read(&mm->mmap_sem);
+ retry:
        vma = find_vma(mm, start);
 
        /*
@@ -194,6 +196,12 @@ asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
                /* Must set VM_NONLINEAR before any pages are populated. */
                if (pgoff != linear_page_index(vma, start) &&
                    !(vma->vm_flags & VM_NONLINEAR)) {
+                       if (!has_write_lock) {
+                               up_read(&mm->mmap_sem);
+                               down_write(&mm->mmap_sem);
+                               has_write_lock = 1;
+                               goto retry;
+                       }
                        mapping = vma->vm_file->f_mapping;
                        spin_lock(&mapping->i_mmap_lock);
                        flush_dcache_mmap_lock(mapping);
@@ -206,8 +214,6 @@ asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
                        spin_unlock(&mapping->i_mmap_lock);
                }
 
-               /* ->populate can take a long time, so downgrade the lock. */
-               downgrade_write(&mm->mmap_sem);
                err = vma->vm_ops->populate(vma, start, size,
                                            vma->vm_page_prot,
                                            pgoff, flags & MAP_NONBLOCK);
@@ -217,10 +223,11 @@ asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
                 * it after ->populate completes, and that would prevent
                 * downgrading the lock.  (Locks can't be upgraded).
                 */
+       }
+       if (likely(!has_write_lock))
                up_read(&mm->mmap_sem);
-       } else {
+       else
                up_write(&mm->mmap_sem);
-       }
 
        return err;
 }
index 9fc1106..09eac06 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/init.h>
 #include <linux/hash.h>
 #include <linux/highmem.h>
-#include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 
 static mempool_t *page_pool, *isa_page_pool;
index 6acf0d8..bce0d47 100644 (file)
@@ -57,6 +57,7 @@ void free_huge_page(struct page *page)
        BUG_ON(page_count(page));
 
        INIT_LIST_HEAD(&page->lru);
+       page[1].mapping = NULL;
 
        spin_lock(&hugetlb_lock);
        enqueue_huge_page(page);
@@ -181,7 +182,8 @@ static unsigned long set_max_huge_pages(unsigned long count)
 
 #ifdef CONFIG_SYSCTL
 int hugetlb_sysctl_handler(struct ctl_table *table, int write,
-                          struct file *file, void *buffer, size_t *length)
+                          struct file *file, void __user *buffer,
+                          size_t *length)
 {
        proc_doulongvec_minmax(table, write, file, buffer, length);
        max_huge_pages = set_max_huge_pages(max_huge_pages);
index 0f2a1e6..1ed4056 100644 (file)
@@ -644,15 +644,11 @@ follow_page(struct mm_struct *mm, unsigned long address, int write)
        if (pte_present(pte)) {
                if (write && !pte_write(pte))
                        goto out;
-               if (write && !pte_dirty(pte)) {
-                       struct page *page = pte_page(pte);
-                       if (!PageDirty(page))
-                               set_page_dirty(page);
-               }
                pfn = pte_pfn(pte);
                if (pfn_valid(pfn)) {
-                       struct page *page = pfn_to_page(pfn);
-                       
+                       page = pfn_to_page(pfn);
+                       if (write && !pte_dirty(pte) && !PageDirty(page))
+                               set_page_dirty(page);
                        mark_page_accessed(page);
                        return page;
                }
@@ -734,6 +730,7 @@ static inline struct page *get_page_map(struct page *page)
 }
 
 
+#ifndef CONFIG_X86_4G
 static inline int
 untouched_anonymous_page(struct mm_struct* mm, struct vm_area_struct *vma,
                         unsigned long address)
@@ -758,6 +755,7 @@ untouched_anonymous_page(struct mm_struct* mm, struct vm_area_struct *vma,
        /* There is a pte slot for 'address' in 'mm'. */
        return 0;
 }
+#endif
 
 
 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
@@ -828,12 +826,21 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                                 * insanly big anonymously mapped areas that
                                 * nobody touched so far. This is important
                                 * for doing a core dump for these mappings.
+                                *
+                                * disable this for 4:4 - it prevents
+                                * follow_page() from ever seeing these pages.
+                                *
+                                * (The 'fix' is dubious anyway, there's
+                                * nothing that this code avoids which couldnt
+                                * be triggered from userspace anyway.)
                                 */
+#ifndef CONFIG_X86_4G
                                if (!lookup_write &&
                                    untouched_anonymous_page(mm,vma,start)) {
                                        map = ZERO_PAGE(start);
                                        break;
                                }
+#endif
                                spin_unlock(&mm->page_table_lock);
                                switch (handle_mm_fault(mm,vma,start,write)) {
                                case VM_FAULT_MINOR:
index a62a65c..096a249 100644 (file)
@@ -61,6 +61,7 @@
 
 #include <linux/mempolicy.h>
 #include <linux/mm.h>
+#include <linux/highmem.h>
 #include <linux/hugetlb.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -1001,7 +1002,8 @@ void mpol_free_shared_policy(struct shared_policy *p)
        up(&p->sem);
 }
 
-static __init int numa_policy_init(void)
+/* assumes fs == KERNEL_DS */
+void __init numa_policy_init(void)
 {
        policy_cache = kmem_cache_create("numa_policy",
                                         sizeof(struct mempolicy),
@@ -1010,6 +1012,17 @@ static __init int numa_policy_init(void)
        sn_cache = kmem_cache_create("shared_policy_node",
                                     sizeof(struct sp_node),
                                     0, SLAB_PANIC, NULL, NULL);
-       return 0;
+
+       /* Set interleaving policy for system init. This way not all
+          the data structures allocated at system boot end up in node zero. */
+
+       if (sys_set_mempolicy(MPOL_INTERLEAVE, node_online_map, MAX_NUMNODES) < 0)
+               printk("numa_policy_init: interleaving failed\n");
+}
+
+/* Reset policy of current process to default.
+ * Assumes fs == KERNEL_DS */
+void numa_default_policy(void)
+{
+       sys_set_mempolicy(MPOL_DEFAULT, NULL, 0);
 }
-module_init(numa_policy_init);
index da6ad1e..a6c1537 100644 (file)
@@ -89,11 +89,6 @@ mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
 }
 EXPORT_SYMBOL(mempool_create);
 
-/*
- * mempool_resize is disabled for now, because it has no callers.  Feel free
- * to turn it back on if needed.
- */
-#if 0
 /**
  * mempool_resize - resize an existing memory pool
  * @pool:       pointer to the memory pool which was allocated via
@@ -163,7 +158,6 @@ out:
        return 0;
 }
 EXPORT_SYMBOL(mempool_resize);
-#endif
 
 /**
  * mempool_destroy - deallocate a memory pool
index eac70db..280abef 100644 (file)
@@ -14,7 +14,6 @@
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
-#include <asm/pgalloc.h>
 
 /*
  * Later we can get more picky about what "in core" means precisely.
index e15aef8..a9e3716 100644 (file)
@@ -60,7 +60,7 @@ static int do_mlock(unsigned long start, size_t len, int on)
        struct vm_area_struct * vma, * next;
        int error;
 
-       if (on && !can_do_mlock())
+       if (on && !capable(CAP_IPC_LOCK))
                return -EPERM;
        len = PAGE_ALIGN(len);
        end = start + len;
@@ -118,7 +118,7 @@ asmlinkage long sys_mlock(unsigned long start, size_t len)
        lock_limit >>= PAGE_SHIFT;
 
        /* check against resource limits */
-       if ( (locked <= lock_limit) || capable(CAP_IPC_LOCK))
+       if (locked <= lock_limit)
                error = do_mlock(start, len, 1);
        up_write(&current->mm->mmap_sem);
        return error;
@@ -142,7 +142,7 @@ static int do_mlockall(int flags)
        unsigned int def_flags;
        struct vm_area_struct * vma;
 
-       if (!can_do_mlock())
+       if (!capable(CAP_IPC_LOCK))
                return -EPERM;
 
        def_flags = 0;
@@ -177,7 +177,7 @@ asmlinkage long sys_mlockall(int flags)
        lock_limit >>= PAGE_SHIFT;
 
        ret = -ENOMEM;
-       if ((current->mm->total_vm <= lock_limit) || capable(CAP_IPC_LOCK))
+       if (current->mm->total_vm <= lock_limit)
                ret = do_mlockall(flags);
 out:
        up_write(&current->mm->mmap_sem);
index b00732b..4d32ab0 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -25,7 +25,6 @@
 #include <linux/rmap.h>
 
 #include <asm/uaccess.h>
-#include <asm/pgalloc.h>
 #include <asm/cacheflush.h>
 #include <asm/tlb.h>
 
@@ -295,10 +294,8 @@ __vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
        struct vm_area_struct *prev, struct rb_node **rb_link,
        struct rb_node *rb_parent)
 {
-       vma_prio_tree_init(vma);
        __vma_link_list(mm, vma, prev, rb_parent);
        __vma_link_rb(mm, vma, rb_link, rb_parent);
-       __vma_link_file(vma);
        __anon_vma_link(vma);
 }
 
@@ -314,7 +311,10 @@ static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
        if (mapping)
                spin_lock(&mapping->i_mmap_lock);
        anon_vma_lock(vma);
+
        __vma_link(mm, vma, prev, rb_link, rb_parent);
+       __vma_link_file(vma);
+
        anon_vma_unlock(vma);
        if (mapping)
                spin_unlock(&mapping->i_mmap_lock);
@@ -325,9 +325,9 @@ static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
 }
 
 /*
- * Insert vm structure into process list sorted by address and into the
- * inode's i_mmap tree. The caller should hold mm->mmap_sem and
- * ->f_mappping->i_mmap_lock if vm_file is non-NULL.
+ * Helper for vma_adjust in the split_vma insert case:
+ * insert vm structure into list and rbtree and anon_vma,
+ * but it has already been inserted into prio_tree earlier.
  */
 static void
 __insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
@@ -339,9 +339,7 @@ __insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
        if (__vma && __vma->vm_start < vma->vm_end)
                BUG();
        __vma_link(mm, vma, prev, rb_link, rb_parent);
-       mark_mm_hugetlb(mm, vma);
        mm->map_count++;
-       validate_mm(mm);
 }
 
 static inline void
@@ -377,20 +375,27 @@ void vma_adjust(struct vm_area_struct *vma, unsigned long start,
 
        if (next && !insert) {
                if (end >= next->vm_end) {
+                       /*
+                        * vma expands, overlapping all the next, and
+                        * perhaps the one after too (mprotect case 6).
+                        */
 again:                 remove_next = 1 + (end > next->vm_end);
                        end = next->vm_end;
                        anon_vma = next->anon_vma;
-               } else if (end < vma->vm_end || end > next->vm_start) {
+               } else if (end > next->vm_start) {
                        /*
-                        * vma shrinks, and !insert tells it's not
-                        * split_vma inserting another: so it must
-                        * be mprotect shifting the boundary down.
-                        *   Or:
                         * vma expands, overlapping part of the next:
-                        * must be mprotect shifting the boundary up.
+                        * mprotect case 5 shifting the boundary up.
+                        */
+                       adjust_next = (end - next->vm_start) >> PAGE_SHIFT;
+                       anon_vma = next->anon_vma;
+               } else if (end < vma->vm_end) {
+                       /*
+                        * vma shrinks, and !insert tells it's not
+                        * split_vma inserting another: so it must be
+                        * mprotect case 4 shifting the boundary down.
                         */
-                       BUG_ON(vma->vm_end != next->vm_start);
-                       adjust_next = end - next->vm_start;
+                       adjust_next = - ((vma->vm_end - end) >> PAGE_SHIFT);
                        anon_vma = next->anon_vma;
                }
        }
@@ -400,6 +405,15 @@ again:                     remove_next = 1 + (end > next->vm_end);
                if (!(vma->vm_flags & VM_NONLINEAR))
                        root = &mapping->i_mmap;
                spin_lock(&mapping->i_mmap_lock);
+               if (insert) {
+                       /*
+                        * Put into prio_tree now, so instantiated pages
+                        * are visible to arm/parisc __flush_dcache_page
+                        * throughout; but we cannot insert into address
+                        * space until vma start or end is updated.
+                        */
+                       __vma_link_file(insert);
+               }
        }
 
        /*
@@ -422,8 +436,8 @@ again:                      remove_next = 1 + (end > next->vm_end);
        vma->vm_end = end;
        vma->vm_pgoff = pgoff;
        if (adjust_next) {
-               next->vm_start += adjust_next;
-               next->vm_pgoff += adjust_next >> PAGE_SHIFT;
+               next->vm_start += adjust_next << PAGE_SHIFT;
+               next->vm_pgoff += adjust_next;
        }
 
        if (root) {
@@ -773,17 +787,15 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
                        mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
 
        if (flags & MAP_LOCKED) {
-               if (!can_do_mlock())
+               if (!capable(CAP_IPC_LOCK))
                        return -EPERM;
                vm_flags |= VM_LOCKED;
        }
        /* mlock MCL_FUTURE? */
        if (vm_flags & VM_LOCKED) {
-               unsigned long locked, lock_limit;
-               locked = mm->locked_vm << PAGE_SHIFT;
-               lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+               unsigned long locked = mm->locked_vm << PAGE_SHIFT;
                locked += len;
-               if (locked > lock_limit && !capable(CAP_IPC_LOCK))
+               if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
                        return -EAGAIN;
        }
 
@@ -1479,6 +1491,7 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
 
        /* most fields are the same, copy all, and then fixup */
        *new = *vma;
+       vma_prio_tree_init(new);
 
        if (new_below)
                new->vm_end = addr;
@@ -1623,11 +1636,9 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
         * mlock MCL_FUTURE?
         */
        if (mm->def_flags & VM_LOCKED) {
-               unsigned long locked, lock_limit;
-               locked = mm->locked_vm << PAGE_SHIFT;
-               lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+               unsigned long locked = mm->locked_vm << PAGE_SHIFT;
                locked += len;
-               if (locked > lock_limit && !capable(CAP_IPC_LOCK))
+               if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
                        return -EAGAIN;
        }
 
@@ -1798,6 +1809,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
                new_vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
                if (new_vma) {
                        *new_vma = *vma;
+                       vma_prio_tree_init(new_vma);
                        pol = mpol_copy(vma_policy(vma));
                        if (IS_ERR(pol)) {
                                kmem_cache_free(vm_area_cachep, new_vma);
index 7dbb64d..3890a96 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/mempolicy.h>
 
 #include <asm/uaccess.h>
-#include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/cacheflush.h>
index 33b41cb..62d9072 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/security.h>
 
 #include <asm/uaccess.h>
-#include <asm/pgalloc.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
@@ -325,12 +324,10 @@ unsigned long do_mremap(unsigned long addr,
                        goto out;
        }
        if (vma->vm_flags & VM_LOCKED) {
-               unsigned long locked, lock_limit;
-               locked = current->mm->locked_vm << PAGE_SHIFT;
-               lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+               unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
                locked += new_len - old_len;
                ret = -EAGAIN;
-               if (locked > lock_limit && !capable(CAP_IPC_LOCK))
+               if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
                        goto out;
        }
        ret = -ENOMEM;
index 5467df5..2aaad04 100644 (file)
@@ -11,9 +11,9 @@
 #include <linux/pagemap.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
+#include <linux/hugetlb.h>
 
 #include <asm/pgtable.h>
-#include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 
 /*
@@ -106,6 +106,13 @@ static int filemap_sync(struct vm_area_struct * vma, unsigned long address,
 
        dir = pgd_offset(vma->vm_mm, address);
        flush_cache_range(vma, address, end);
+
+       /* For hugepages we can't go walking the page table normally,
+        * but that's ok, hugetlbfs is memory based, so we don't need
+        * to do anything more on an msync() */
+       if (is_vm_hugetlb_page(vma))
+               goto out;
+
        if (address >= end)
                BUG();
        do {
@@ -118,7 +125,7 @@ static int filemap_sync(struct vm_area_struct * vma, unsigned long address,
         * dirty bits.
         */
        flush_tlb_range(vma, end - size, end);
-
+ out:
        spin_unlock(&vma->vm_mm->page_table_lock);
 
        return error;
index 5872905..f02e673 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/blkdev.h>
 #include <linux/backing-dev.h>
 
-#include <asm/pgalloc.h>
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
index ed0cee4..203923c 100644 (file)
@@ -245,7 +245,6 @@ void out_of_memory(void)
         * If it's been a long time since last failure,
         * we're not oom.
         */
-       last = now;
        if (since > 5*HZ)
                goto reset;
 
index d74d6ad..a2aa511 100644 (file)
@@ -99,6 +99,22 @@ EXPORT_SYMBOL(laptop_mode);
 
 static void background_writeout(unsigned long _min_pages);
 
+struct writeback_state
+{
+       unsigned long nr_dirty;
+       unsigned long nr_unstable;
+       unsigned long nr_mapped;
+       unsigned long nr_writeback;
+};
+
+static void get_writeback_state(struct writeback_state *wbs)
+{
+       wbs->nr_dirty = read_page_state(nr_dirty);
+       wbs->nr_unstable = read_page_state(nr_unstable);
+       wbs->nr_mapped = read_page_state(nr_mapped);
+       wbs->nr_writeback = read_page_state(nr_writeback);
+}
+
 /*
  * Work out the current dirty-memory clamping and background writeout
  * thresholds.
@@ -117,7 +133,7 @@ static void background_writeout(unsigned long _min_pages);
  * clamping level.
  */
 static void
-get_dirty_limits(struct page_state *ps, long *pbackground, long *pdirty)
+get_dirty_limits(struct writeback_state *wbs, long *pbackground, long *pdirty)
 {
        int background_ratio;           /* Percentages */
        int dirty_ratio;
@@ -126,9 +142,9 @@ get_dirty_limits(struct page_state *ps, long *pbackground, long *pdirty)
        long dirty;
        struct task_struct *tsk;
 
-       get_page_state(ps);
+       get_writeback_state(wbs);
 
-       unmapped_ratio = 100 - (ps->nr_mapped * 100) / total_pages;
+       unmapped_ratio = 100 - (wbs->nr_mapped * 100) / total_pages;
 
        dirty_ratio = vm_dirty_ratio;
        if (dirty_ratio > unmapped_ratio / 2)
@@ -161,7 +177,7 @@ get_dirty_limits(struct page_state *ps, long *pbackground, long *pdirty)
  */
 static void balance_dirty_pages(struct address_space *mapping)
 {
-       struct page_state ps;
+       struct writeback_state wbs;
        long nr_reclaimable;
        long background_thresh;
        long dirty_thresh;
@@ -178,9 +194,9 @@ static void balance_dirty_pages(struct address_space *mapping)
                        .nr_to_write    = write_chunk,
                };
 
-               get_dirty_limits(&ps, &background_thresh, &dirty_thresh);
-               nr_reclaimable = ps.nr_dirty + ps.nr_unstable;
-               if (nr_reclaimable + ps.nr_writeback <= dirty_thresh)
+               get_dirty_limits(&wbs, &background_thresh, &dirty_thresh);
+               nr_reclaimable = wbs.nr_dirty + wbs.nr_unstable;
+               if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh)
                        break;
 
                dirty_exceeded = 1;
@@ -193,10 +209,10 @@ static void balance_dirty_pages(struct address_space *mapping)
                 */
                if (nr_reclaimable) {
                        writeback_inodes(&wbc);
-                       get_dirty_limits(&ps, &background_thresh,
+                       get_dirty_limits(&wbs, &background_thresh,
                                        &dirty_thresh);
-                       nr_reclaimable = ps.nr_dirty + ps.nr_unstable;
-                       if (nr_reclaimable + ps.nr_writeback <= dirty_thresh)
+                       nr_reclaimable = wbs.nr_dirty + wbs.nr_unstable;
+                       if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh)
                                break;
                        pages_written += write_chunk - wbc.nr_to_write;
                        if (pages_written >= write_chunk)
@@ -205,7 +221,7 @@ static void balance_dirty_pages(struct address_space *mapping)
                blk_congestion_wait(WRITE, HZ/10);
        }
 
-       if (nr_reclaimable + ps.nr_writeback <= dirty_thresh)
+       if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh)
                dirty_exceeded = 0;
 
        if (writeback_in_progress(bdi))
@@ -232,10 +248,10 @@ static void balance_dirty_pages(struct address_space *mapping)
  * which was newly dirtied.  The function will periodically check the system's
  * dirty state and will initiate writeback if needed.
  *
- * On really big machines, get_page_state is expensive, so try to avoid calling
- * it too often (ratelimiting).  But once we're over the dirty memory limit we
- * decrease the ratelimiting by a lot, to prevent individual processes from
- * overshooting the limit by (ratelimit_pages) each.
+ * On really big machines, get_writeback_state is expensive, so try to avoid
+ * calling it too often (ratelimiting).  But once we're over the dirty memory
+ * limit we decrease the ratelimiting by a lot, to prevent individual processes
+ * from overshooting the limit by (ratelimit_pages) each.
  */
 void balance_dirty_pages_ratelimited(struct address_space *mapping)
 {
@@ -276,12 +292,12 @@ static void background_writeout(unsigned long _min_pages)
        };
 
        for ( ; ; ) {
-               struct page_state ps;
+               struct writeback_state wbs;
                long background_thresh;
                long dirty_thresh;
 
-               get_dirty_limits(&ps, &background_thresh, &dirty_thresh);
-               if (ps.nr_dirty + ps.nr_unstable < background_thresh
+               get_dirty_limits(&wbs, &background_thresh, &dirty_thresh);
+               if (wbs.nr_dirty + wbs.nr_unstable < background_thresh
                                && min_pages <= 0)
                        break;
                wbc.encountered_congestion = 0;
@@ -306,10 +322,10 @@ static void background_writeout(unsigned long _min_pages)
 int wakeup_bdflush(long nr_pages)
 {
        if (nr_pages == 0) {
-               struct page_state ps;
+               struct writeback_state wbs;
 
-               get_page_state(&ps);
-               nr_pages = ps.nr_dirty + ps.nr_unstable;
+               get_writeback_state(&wbs);
+               nr_pages = wbs.nr_dirty + wbs.nr_unstable;
        }
        return pdflush_operation(background_writeout, nr_pages);
 }
@@ -343,7 +359,7 @@ static void wb_kupdate(unsigned long arg)
        unsigned long start_jif;
        unsigned long next_jif;
        long nr_to_write;
-       struct page_state ps;
+       struct writeback_state wbs;
        struct writeback_control wbc = {
                .bdi            = NULL,
                .sync_mode      = WB_SYNC_NONE,
@@ -355,11 +371,11 @@ static void wb_kupdate(unsigned long arg)
 
        sync_supers();
 
-       get_page_state(&ps);
+       get_writeback_state(&wbs);
        oldest_jif = jiffies - (dirty_expire_centisecs * HZ) / 100;
        start_jif = jiffies;
        next_jif = start_jif + (dirty_writeback_centisecs * HZ) / 100;
-       nr_to_write = ps.nr_dirty + ps.nr_unstable +
+       nr_to_write = wbs.nr_dirty + wbs.nr_unstable +
                        (inodes_stat.nr_inodes - inodes_stat.nr_unused);
        while (nr_to_write > 0) {
                wbc.encountered_congestion = 0;
@@ -434,8 +450,8 @@ void laptop_sync_completion(void)
 /*
  * If ratelimit_pages is too high then we can get into dirty-data overload
  * if a large number of processes all perform writes at the same time.
- * If it is too low then SMP machines will call the (expensive) get_page_state
- * too often.
+ * If it is too low then SMP machines will call the (expensive)
+ * get_writeback_state too often.
  *
  * Here we set ratelimit_pages to a level which ensures that when all CPUs are
  * dirtying in parallel, we cannot go more than 3% (1/32) over the dirty memory
index 5769a39..444bb53 100644 (file)
@@ -732,53 +732,12 @@ got_pg:
 
 EXPORT_SYMBOL(__alloc_pages);
 
-#ifdef CONFIG_NUMA
-/* Early boot: Everything is done by one cpu, but the data structures will be
- * used by all cpus - spread them on all nodes.
- */
-static __init unsigned long get_boot_pages(unsigned int gfp_mask, unsigned int order)
-{
-static int nodenr;
-       int i = nodenr;
-       struct page *page;
-
-       for (;;) {
-               if (i > nodenr + numnodes)
-                       return 0;
-               if (node_present_pages(i%numnodes)) {
-                       struct zone **z;
-                       /* The node contains memory. Check that there is
-                        * memory in the intended zonelist.
-                        */
-                       z = NODE_DATA(i%numnodes)->node_zonelists[gfp_mask & GFP_ZONEMASK].zones;
-                       while (*z) {
-                               if ( (*z)->free_pages > (1UL<<order))
-                                       goto found_node;
-                               z++;
-                       }
-               }
-               i++;
-       }
-found_node:
-       nodenr = i+1;
-       page = alloc_pages_node(i%numnodes, gfp_mask, order);
-       if (!page)
-               return 0;
-       return (unsigned long) page_address(page);
-}
-#endif
-
 /*
  * Common helper functions.
  */
 fastcall unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order)
 {
        struct page * page;
-
-#ifdef CONFIG_NUMA
-       if (unlikely(system_state == SYSTEM_BOOTING))
-               return get_boot_pages(gfp_mask, order);
-#endif
        page = alloc_pages(gfp_mask, order);
        if (!page)
                return 0;
@@ -988,6 +947,23 @@ void get_full_page_state(struct page_state *ret)
        __get_page_state(ret, sizeof(*ret) / sizeof(unsigned long));
 }
 
+unsigned long __read_page_state(unsigned offset)
+{
+       unsigned long ret = 0;
+       int cpu;
+
+       for (cpu = 0; cpu < NR_CPUS; cpu++) {
+               unsigned long in;
+
+               if (!cpu_possible(cpu))
+                       continue;
+
+               in = (unsigned long)&per_cpu(page_states, cpu) + offset;
+               ret += *((unsigned long *)in);
+       }
+       return ret;
+}
+
 void get_zone_counts(unsigned long *active,
                unsigned long *inactive, unsigned long *free)
 {
index 871e76b..4dd7f38 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -193,7 +193,7 @@ vma_address(struct page *page, struct vm_area_struct *vma)
  * repeatedly from either page_referenced_anon or page_referenced_file.
  */
 static int page_referenced_one(struct page *page,
-       struct vm_area_struct *vma, unsigned int *mapcount, int *failed)
+       struct vm_area_struct *vma, unsigned int *mapcount)
 {
        struct mm_struct *mm = vma->vm_mm;
        unsigned long address;
@@ -208,14 +208,8 @@ static int page_referenced_one(struct page *page,
        if (address == -EFAULT)
                goto out;
 
-       if (!spin_trylock(&mm->page_table_lock)) {
-               /*
-                * For debug we're currently warning if not all found,
-                * but in this case that's expected: suppress warning.
-                */
-               (*failed)++;
+       if (!spin_trylock(&mm->page_table_lock))
                goto out;
-       }
 
        pgd = pgd_offset(mm, address);
        if (!pgd_present(*pgd))
@@ -232,7 +226,7 @@ static int page_referenced_one(struct page *page,
        if (page_to_pfn(page) != pte_pfn(*pte))
                goto out_unmap;
 
-       if (ptep_test_and_clear_young(pte))
+       if (ptep_clear_flush_young(vma, address, pte))
                referenced++;
 
        (*mapcount)--;
@@ -251,18 +245,14 @@ static inline int page_referenced_anon(struct page *page)
        struct anon_vma *anon_vma = (struct anon_vma *) page->mapping;
        struct vm_area_struct *vma;
        int referenced = 0;
-       int failed = 0;
 
        spin_lock(&anon_vma->lock);
        BUG_ON(list_empty(&anon_vma->head));
        list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
-               referenced += page_referenced_one(page, vma,
-                                                 &mapcount, &failed);
+               referenced += page_referenced_one(page, vma, &mapcount);
                if (!mapcount)
-                       goto out;
+                       break;
        }
-       WARN_ON(!failed);
-out:
        spin_unlock(&anon_vma->lock);
        return referenced;
 }
@@ -289,7 +279,6 @@ static inline int page_referenced_file(struct page *page)
        struct vm_area_struct *vma = NULL;
        struct prio_tree_iter iter;
        int referenced = 0;
-       int failed = 0;
 
        if (!spin_trylock(&mapping->i_mmap_lock))
                return 0;
@@ -299,17 +288,13 @@ static inline int page_referenced_file(struct page *page)
                if ((vma->vm_flags & (VM_LOCKED|VM_MAYSHARE))
                                  == (VM_LOCKED|VM_MAYSHARE)) {
                        referenced++;
-                       goto out;
+                       break;
                }
-               referenced += page_referenced_one(page, vma,
-                                                 &mapcount, &failed);
+               referenced += page_referenced_one(page, vma, &mapcount);
                if (!mapcount)
-                       goto out;
+                       break;
        }
 
-       if (list_empty(&mapping->i_mmap_nonlinear))
-               WARN_ON(!failed);
-out:
        spin_unlock(&mapping->i_mmap_lock);
        return referenced;
 }
@@ -480,7 +465,24 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma)
         * skipped over this mm) then we should reactivate it.
         */
        if ((vma->vm_flags & (VM_LOCKED|VM_RESERVED)) ||
-                       ptep_test_and_clear_young(pte)) {
+                       ptep_clear_flush_young(vma, address, pte)) {
+               ret = SWAP_FAIL;
+               goto out_unmap;
+       }
+
+       /*
+        * Don't pull an anonymous page out from under get_user_pages.
+        * GUP carefully breaks COW and raises page count (while holding
+        * page_table_lock, as we have here) to make sure that the page
+        * cannot be freed.  If we unmap that page here, a user write
+        * access to the virtual address will bring back the page, but
+        * its raised count will (ironically) be taken to mean it's not
+        * an exclusive swap page, do_wp_page will replace it by a copy
+        * page, and the user never get to see the data GUP was holding
+        * the original page for.
+        */
+       if (PageSwapCache(page) &&
+           page_count(page) != page->mapcount + 2) {
                ret = SWAP_FAIL;
                goto out_unmap;
        }
@@ -590,7 +592,7 @@ static int try_to_unmap_cluster(unsigned long cursor,
                if (PageReserved(page))
                        continue;
 
-               if (ptep_test_and_clear_young(pte))
+               if (ptep_clear_flush_young(vma, address, pte))
                        continue;
 
                /* Nuke the page table entry. */
index ada4f73..21d58bd 100644 (file)
@@ -1161,36 +1161,17 @@ shmem_get_policy(struct vm_area_struct *vma, unsigned long addr)
 }
 #endif
 
-int shmem_lock(struct file *file, int lock)
+void shmem_lock(struct file *file, int lock)
 {
        struct inode *inode = file->f_dentry->d_inode;
        struct shmem_inode_info *info = SHMEM_I(inode);
-       struct mm_struct *mm = current->mm;
-       unsigned long lock_limit, locked;
-       int retval = -ENOMEM;
 
        spin_lock(&info->lock);
-       if (lock && !(info->flags & VM_LOCKED)) {
-               locked = inode->i_size >> PAGE_SHIFT;
-               locked += mm->locked_vm;
-               lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
-               lock_limit >>= PAGE_SHIFT;
-               if ((locked > lock_limit) && !capable(CAP_IPC_LOCK))
-                       goto out_nomem;
-               mm->locked_vm = locked;
-       }
-       if (!lock && (info->flags & VM_LOCKED) && mm) {
-               locked = inode->i_size >> PAGE_SHIFT;
-               mm->locked_vm -= locked;
-       }
        if (lock)
                info->flags |= VM_LOCKED;
        else
                info->flags &= ~VM_LOCKED;
-       retval = 0;
-out_nomem:
        spin_unlock(&info->lock);
-       return retval;
 }
 
 static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
index 6dd0825..5717135 100644 (file)
@@ -6,7 +6,7 @@
  *
  *  Rewritten to use page cache, (C) 1998 Stephen Tweedie
  */
-
+#include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/kernel_stat.h>
 #include <linux/swap.h>
@@ -19,7 +19,8 @@
 
 /*
  * swapper_space is a fiction, retained to simplify the path through
- * vmscan's shrink_list.  Only those fields initialized below are used.
+ * vmscan's shrink_list, to make sync_page look nicer, and to allow
+ * future use of radix_tree tags in the swap cache.
  */
 static struct address_space_operations swap_aops = {
        .writepage      = swap_writepage,
@@ -36,8 +37,10 @@ struct address_space swapper_space = {
        .page_tree      = RADIX_TREE_INIT(GFP_ATOMIC),
        .tree_lock      = SPIN_LOCK_UNLOCKED,
        .a_ops          = &swap_aops,
+       .i_mmap_nonlinear = LIST_HEAD_INIT(swapper_space.i_mmap_nonlinear),
        .backing_dev_info = &swap_backing_dev_info,
 };
+EXPORT_SYMBOL(swapper_space);
 
 #define INC_CACHE_INFO(x)      do { swap_cache_info.x++; } while (0)
 
index 1dd32a2..c9a30ae 100644 (file)
@@ -243,6 +243,10 @@ EXPORT_SYMBOL(invalidate_inode_pages);
  * where the page is seen to be mapped into process pagetables.  In that case,
  * the page is marked clean but is left attached to its address_space.
  *
+ * The page is also marked not uptodate so that a subsequent pagefault will
+ * perform I/O to bringthe page's contents back into sync with its backing
+ * store.
+ *
  * FIXME: invalidate_inode_pages2() is probably trivially livelockable.
  */
 void invalidate_inode_pages2(struct address_space *mapping)
@@ -260,10 +264,12 @@ void invalidate_inode_pages2(struct address_space *mapping)
                        if (page->mapping == mapping) { /* truncate race? */
                                wait_on_page_writeback(page);
                                next = page->index + 1;
-                               if (page_mapped(page))
+                               if (page_mapped(page)) {
                                        clear_page_dirty(page);
-                               else
+                                       ClearPageUptodate(page);
+                               } else {
                                        invalidate_complete_page(mapping, page);
+                               }
                        }
                        unlock_page(page);
                }
index 27400b9..7e5123f 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/vmalloc.h>
 
 #include <asm/uaccess.h>
-#include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 
 
index da9e185..0849579 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/cpu.h>
 #include <linux/notifier.h>
 
-#include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
 
@@ -245,17 +244,107 @@ static void handle_write_error(struct address_space *mapping,
        unlock_page(page);
 }
 
+/* possible outcome of pageout() */
+typedef enum {
+       /* failed to write page out, page is locked */
+       PAGE_KEEP,
+       /* move page to the active list, page is locked */
+       PAGE_ACTIVATE,
+       /* page has been sent to the disk successfully, page is unlocked */
+       PAGE_SUCCESS,
+       /* page is clean and locked */
+       PAGE_CLEAN,
+} pageout_t;
+
 /*
- * shrink_list returns the number of reclaimed pages
+ * pageout is called by shrink_list() for each dirty page. Calls ->writepage().
  */
-static int
-shrink_list(struct list_head *page_list, unsigned int gfp_mask,
-               int *nr_scanned, int do_writepage)
+static pageout_t pageout(struct page *page, struct address_space *mapping)
+{
+       /*
+        * If the page is dirty, only perform writeback if that write
+        * will be non-blocking.  To prevent this allocation from being
+        * stalled by pagecache activity.  But note that there may be
+        * stalls if we need to run get_block().  We could test
+        * PagePrivate for that.
+        *
+        * If this process is currently in generic_file_write() against
+        * this page's queue, we can perform writeback even if that
+        * will block.
+        *
+        * If the page is swapcache, write it back even if that would
+        * block, for some throttling. This happens by accident, because
+        * swap_backing_dev_info is bust: it doesn't reflect the
+        * congestion state of the swapdevs.  Easy to fix, if needed.
+        * See swapfile.c:page_queue_congested().
+        */
+       if (!is_page_cache_freeable(page))
+               return PAGE_KEEP;
+       if (!mapping)
+               return PAGE_KEEP;
+       if (mapping->a_ops->writepage == NULL)
+               return PAGE_ACTIVATE;
+       if (!may_write_to_queue(mapping->backing_dev_info))
+               return PAGE_KEEP;
+
+       if (clear_page_dirty_for_io(page)) {
+               int res;
+               struct writeback_control wbc = {
+                       .sync_mode = WB_SYNC_NONE,
+                       .nr_to_write = SWAP_CLUSTER_MAX,
+                       .nonblocking = 1,
+                       .for_reclaim = 1,
+               };
+
+               SetPageReclaim(page);
+               res = mapping->a_ops->writepage(page, &wbc);
+               if (res < 0)
+                       handle_write_error(mapping, page, res);
+               if (res == WRITEPAGE_ACTIVATE) {
+                       ClearPageReclaim(page);
+                       return PAGE_ACTIVATE;
+               }
+               if (!PageWriteback(page)) {
+                       /* synchronous write or broken a_ops? */
+                       ClearPageReclaim(page);
+               }
+
+               return PAGE_SUCCESS;
+       }
+
+       return PAGE_CLEAN;
+}
+
+struct scan_control {
+       /* Ask refill_inactive_zone, or shrink_cache to scan this many pages */
+       unsigned long nr_to_scan;
+
+       /* Incremented by the number of inactive pages that were scanned */
+       unsigned long nr_scanned;
+
+       /* Incremented by the number of pages reclaimed */
+       unsigned long nr_reclaimed;
+
+       unsigned long nr_mapped;        /* From page_state */
+
+       /* Ask shrink_caches, or shrink_zone to scan at this priority */
+       unsigned int priority;
+
+       /* This context's GFP mask */
+       unsigned int gfp_mask;
+
+       int may_writepage;
+};
+
+/*
+ * shrink_list adds the number of reclaimed pages to sc->nr_reclaimed
+ */
+static int shrink_list(struct list_head *page_list, struct scan_control *sc)
 {
        LIST_HEAD(ret_pages);
        struct pagevec freed_pvec;
        int pgactivate = 0;
-       int ret = 0;
+       int reclaimed = 0;
 
        cond_resched();
 
@@ -272,15 +361,16 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
                if (TestSetPageLocked(page))
                        goto keep;
 
-               /* Double the slab pressure for mapped and swapcache pages */
-               if (page_mapped(page) || PageSwapCache(page))
-                       (*nr_scanned)++;
-
                BUG_ON(PageActive(page));
 
                if (PageWriteback(page))
                        goto keep_locked;
 
+               sc->nr_scanned++;
+               /* Double the slab pressure for mapped and swapcache pages */
+               if (page_mapped(page) || PageSwapCache(page))
+                       sc->nr_scanned++;
+
                page_map_lock(page);
                referenced = page_referenced(page);
                if (referenced && page_mapping_inuse(page)) {
@@ -305,8 +395,8 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
 #endif /* CONFIG_SWAP */
 
                mapping = page_mapping(page);
-               may_enter_fs = (gfp_mask & __GFP_FS) ||
-                       (PageSwapCache(page) && (gfp_mask & __GFP_IO));
+               may_enter_fs = (sc->gfp_mask & __GFP_FS) ||
+                       (PageSwapCache(page) && (sc->gfp_mask & __GFP_IO));
 
                /*
                 * The page is mapped into the page tables of one or more
@@ -326,60 +416,34 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
                }
                page_map_unlock(page);
 
-               /*
-                * If the page is dirty, only perform writeback if that write
-                * will be non-blocking.  To prevent this allocation from being
-                * stalled by pagecache activity.  But note that there may be
-                * stalls if we need to run get_block().  We could test
-                * PagePrivate for that.
-                *
-                * If this process is currently in generic_file_write() against
-                * this page's queue, we can perform writeback even if that
-                * will block.
-                *
-                * If the page is swapcache, write it back even if that would
-                * block, for some throttling. This happens by accident, because
-                * swap_backing_dev_info is bust: it doesn't reflect the
-                * congestion state of the swapdevs.  Easy to fix, if needed.
-                * See swapfile.c:page_queue_congested().
-                */
                if (PageDirty(page)) {
                        if (referenced)
                                goto keep_locked;
-                       if (!is_page_cache_freeable(page))
-                               goto keep_locked;
-                       if (!mapping)
-                               goto keep_locked;
-                       if (mapping->a_ops->writepage == NULL)
-                               goto activate_locked;
                        if (!may_enter_fs)
                                goto keep_locked;
-                       if (!may_write_to_queue(mapping->backing_dev_info))
+                       if (laptop_mode && !sc->may_writepage)
                                goto keep_locked;
-                       if (laptop_mode && !do_writepage)
+
+                       /* Page is dirty, try to write it out here */
+                       switch(pageout(page, mapping)) {
+                       case PAGE_KEEP:
                                goto keep_locked;
-                       if (clear_page_dirty_for_io(page)) {
-                               int res;
-                               struct writeback_control wbc = {
-                                       .sync_mode = WB_SYNC_NONE,
-                                       .nr_to_write = SWAP_CLUSTER_MAX,
-                                       .nonblocking = 1,
-                                       .for_reclaim = 1,
-                               };
-
-                               SetPageReclaim(page);
-                               res = mapping->a_ops->writepage(page, &wbc);
-                               if (res < 0)
-                                       handle_write_error(mapping, page, res);
-                               if (res == WRITEPAGE_ACTIVATE) {
-                                       ClearPageReclaim(page);
-                                       goto activate_locked;
-                               }
-                               if (!PageWriteback(page)) {
-                                       /* synchronous write or broken a_ops? */
-                                       ClearPageReclaim(page);
-                               }
-                               goto keep;
+                       case PAGE_ACTIVATE:
+                               goto activate_locked;
+                       case PAGE_SUCCESS:
+                               if (PageWriteback(page) || PageDirty(page))
+                                       goto keep;
+                               /*
+                                * A synchronous write - probably a ramdisk.  Go
+                                * ahead and try to reclaim the page.
+                                */
+                               if (TestSetPageLocked(page))
+                                       goto keep;
+                               if (PageDirty(page) || PageWriteback(page))
+                                       goto keep_locked;
+                               mapping = page_mapping(page);
+                       case PAGE_CLEAN:
+                               ; /* try to free the page below */
                        }
                }
 
@@ -401,11 +465,11 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
                 * the pages which were not successfully invalidated in
                 * truncate_complete_page().  We try to drop those buffers here
                 * and if that worked, and the page is no longer mapped into
-                * process address space (page_count == 0) it can be freed.
+                * process address space (page_count == 1) it can be freed.
                 * Otherwise, leave the page on the LRU so it is swappable.
                 */
                if (PagePrivate(page)) {
-                       if (!try_to_release_page(page, gfp_mask))
+                       if (!try_to_release_page(page, sc->gfp_mask))
                                goto activate_locked;
                        if (!mapping && page_count(page) == 1)
                                goto free_it;
@@ -443,7 +507,7 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
 
 free_it:
                unlock_page(page);
-               ret++;
+               reclaimed++;
                if (!pagevec_add(&freed_pvec, page))
                        __pagevec_release_nonlru(&freed_pvec);
                continue;
@@ -461,7 +525,8 @@ keep:
        if (pagevec_count(&freed_pvec))
                __pagevec_release_nonlru(&freed_pvec);
        mod_page_state(pgactivate, pgactivate);
-       return ret;
+       sc->nr_reclaimed += reclaimed;
+       return reclaimed;
 }
 
 /*
@@ -469,19 +534,16 @@ keep:
  * a batch of pages and working on them outside the lock.  Any pages which were
  * not freed will be added back to the LRU.
  *
- * shrink_cache() is passed the number of pages to scan and returns the number
- * of pages which were reclaimed.
+ * shrink_cache() adds the number of pages reclaimed to sc->nr_reclaimed
  *
  * For pagecache intensive workloads, the first loop here is the hottest spot
  * in the kernel (apart from the copy_*_user functions).
  */
-static int
-shrink_cache(struct zone *zone, unsigned int gfp_mask,
-               int max_scan, int *total_scanned, int do_writepage)
+static void shrink_cache(struct zone *zone, struct scan_control *sc)
 {
        LIST_HEAD(page_list);
        struct pagevec pvec;
-       int ret = 0;
+       int max_scan = sc->nr_to_scan;
 
        pagevec_init(&pvec, 1);
 
@@ -527,17 +589,11 @@ shrink_cache(struct zone *zone, unsigned int gfp_mask,
                        mod_page_state_zone(zone, pgscan_kswapd, nr_scan);
                else
                        mod_page_state_zone(zone, pgscan_direct, nr_scan);
-               nr_freed = shrink_list(&page_list, gfp_mask,
-                                       total_scanned, do_writepage);
-               *total_scanned += nr_taken;
+               nr_freed = shrink_list(&page_list, sc);
                if (current_is_kswapd())
                        mod_page_state(kswapd_steal, nr_freed);
                mod_page_state_zone(zone, pgsteal, nr_freed);
 
-               ret += nr_freed;
-               if (nr_freed <= 0 && list_empty(&page_list))
-                       goto done;
-
                spin_lock_irq(&zone->lru_lock);
                /*
                 * Put back any unfreeable pages.
@@ -561,7 +617,6 @@ shrink_cache(struct zone *zone, unsigned int gfp_mask,
        spin_unlock_irq(&zone->lru_lock);
 done:
        pagevec_release(&pvec);
-       return ret;
 }
 
 /*
@@ -582,12 +637,12 @@ done:
  * But we had to alter page->flags anyway.
  */
 static void
-refill_inactive_zone(struct zone *zone, const int nr_pages_in,
-                       struct page_state *ps)
+refill_inactive_zone(struct zone *zone, struct scan_control *sc)
 {
        int pgmoved;
        int pgdeactivate = 0;
-       int nr_pages = nr_pages_in;
+       int pgscanned = 0;
+       int nr_pages = sc->nr_to_scan;
        LIST_HEAD(l_hold);      /* The pages which were snipped off */
        LIST_HEAD(l_inactive);  /* Pages to go onto the inactive_list */
        LIST_HEAD(l_active);    /* Pages to go onto the active_list */
@@ -601,7 +656,7 @@ refill_inactive_zone(struct zone *zone, const int nr_pages_in,
        lru_add_drain();
        pgmoved = 0;
        spin_lock_irq(&zone->lru_lock);
-       while (nr_pages && !list_empty(&zone->active_list)) {
+       while (pgscanned < nr_pages && !list_empty(&zone->active_list)) {
                page = lru_to_page(&zone->active_list);
                prefetchw_prev_lru_page(page, &zone->active_list, flags);
                if (!TestClearPageLRU(page))
@@ -621,7 +676,7 @@ refill_inactive_zone(struct zone *zone, const int nr_pages_in,
                        list_add(&page->lru, &l_hold);
                        pgmoved++;
                }
-               nr_pages--;
+               pgscanned++;
        }
        zone->nr_active -= pgmoved;
        spin_unlock_irq(&zone->lru_lock);
@@ -637,7 +692,7 @@ refill_inactive_zone(struct zone *zone, const int nr_pages_in,
         * mapped memory instead of just pagecache.  Work out how much memory
         * is mapped.
         */
-       mapped_ratio = (ps->nr_mapped * 100) / total_memory;
+       mapped_ratio = (sc->nr_mapped * 100) / total_memory;
 
        /*
         * Now decide how much we really want to unmap some pages.  The mapped
@@ -736,7 +791,7 @@ refill_inactive_zone(struct zone *zone, const int nr_pages_in,
        spin_unlock_irq(&zone->lru_lock);
        pagevec_release(&pvec);
 
-       mod_page_state_zone(zone, pgrefill, nr_pages_in - nr_pages);
+       mod_page_state_zone(zone, pgrefill, pgscanned);
        mod_page_state(pgdeactivate, pgdeactivate);
 }
 
@@ -744,13 +799,14 @@ refill_inactive_zone(struct zone *zone, const int nr_pages_in,
  * Scan `nr_pages' from this zone.  Returns the number of reclaimed pages.
  * This is a basic per-zone page freer.  Used by both kswapd and direct reclaim.
  */
-static int
-shrink_zone(struct zone *zone, int max_scan, unsigned int gfp_mask,
-               int *total_scanned, struct page_state *ps, int do_writepage)
+static void
+shrink_zone(struct zone *zone, struct scan_control *sc)
 {
-       unsigned long scan_active;
+       unsigned long scan_active, scan_inactive;
        int count;
 
+       scan_inactive = (zone->nr_active + zone->nr_inactive) >> sc->priority;
+
        /*
         * Try to keep the active list 2/3 of the size of the cache.  And
         * make sure that refill_inactive is given a decent number of pages.
@@ -763,13 +819,13 @@ shrink_zone(struct zone *zone, int max_scan, unsigned int gfp_mask,
         */
        if (zone->nr_active >= 4*(zone->nr_inactive*2 + 1)) {
                /* Don't scan more than 4 times the inactive list scan size */
-               scan_active = 4*max_scan;
+               scan_active = 4*scan_inactive;
        } else {
                unsigned long long tmp;
 
                /* Cast to long long so the multiply doesn't overflow */
 
-               tmp = (unsigned long long)max_scan * zone->nr_active;
+               tmp = (unsigned long long)scan_inactive * zone->nr_active;
                do_div(tmp, zone->nr_inactive*2 + 1);
                scan_active = (unsigned long)tmp;
        }
@@ -778,17 +834,17 @@ shrink_zone(struct zone *zone, int max_scan, unsigned int gfp_mask,
        count = atomic_read(&zone->nr_scan_active);
        if (count >= SWAP_CLUSTER_MAX) {
                atomic_set(&zone->nr_scan_active, 0);
-               refill_inactive_zone(zone, count, ps);
+               sc->nr_to_scan = count;
+               refill_inactive_zone(zone, sc);
        }
 
-       atomic_add(max_scan, &zone->nr_scan_inactive);
+       atomic_add(scan_inactive, &zone->nr_scan_inactive);
        count = atomic_read(&zone->nr_scan_inactive);
        if (count >= SWAP_CLUSTER_MAX) {
                atomic_set(&zone->nr_scan_inactive, 0);
-               return shrink_cache(zone, gfp_mask, count,
-                                       total_scanned, do_writepage);
+               sc->nr_to_scan = count;
+               shrink_cache(zone, sc);
        }
-       return 0;
 }
 
 /*
@@ -807,28 +863,23 @@ shrink_zone(struct zone *zone, int max_scan, unsigned int gfp_mask,
  * If a zone is deemed to be full of pinned pages then just give it a light
  * scan then give up on it.
  */
-static int
-shrink_caches(struct zone **zones, int priority, int *total_scanned,
-               int gfp_mask, struct page_state *ps, int do_writepage)
+static void
+shrink_caches(struct zone **zones, struct scan_control *sc)
 {
-       int ret = 0;
        int i;
 
        for (i = 0; zones[i] != NULL; i++) {
                struct zone *zone = zones[i];
-               int max_scan;
 
-               if (zone->free_pages < zone->pages_high)
-                       zone->temp_priority = priority;
+               zone->temp_priority = sc->priority;
+               if (zone->prev_priority > sc->priority)
+                       zone->prev_priority = sc->priority;
 
-               if (zone->all_unreclaimable && priority != DEF_PRIORITY)
+               if (zone->all_unreclaimable && sc->priority != DEF_PRIORITY)
                        continue;       /* Let kswapd poll it */
 
-               max_scan = (zone->nr_active + zone->nr_inactive) >> priority;
-               ret += shrink_zone(zone, max_scan, gfp_mask,
-                                       total_scanned, ps, do_writepage);
+               shrink_zone(zone, sc);
        }
-       return ret;
 }
  
 /*
@@ -839,25 +890,23 @@ shrink_caches(struct zone **zones, int priority, int *total_scanned,
  *
  * If the caller is !__GFP_FS then the probability of a failure is reasonably
  * high - the zone may be full of dirty or under-writeback pages, which this
- * caller can't do much about.  So for !__GFP_FS callers, we just perform a
- * small LRU walk and if that didn't work out, fail the allocation back to the
- * caller.  GFP_NOFS allocators need to know how to deal with it.  Kicking
- * bdflush, waiting and retrying will work.
- *
- * This is a fairly lame algorithm - it can result in excessive CPU burning and
- * excessive rotation of the inactive list, which is _supposed_ to be an LRU,
- * yes?
+ * caller can't do much about.  We kick pdflush and take explicit naps in the
+ * hope that some of these pages can be written.  But if the allocating task
+ * holds filesystem locks which prevent writeout this might not work, and the
+ * allocation attempt will fail.
  */
 int try_to_free_pages(struct zone **zones,
                unsigned int gfp_mask, unsigned int order)
 {
        int priority;
        int ret = 0;
-       int nr_reclaimed = 0;
+       int total_scanned = 0, total_reclaimed = 0;
        struct reclaim_state *reclaim_state = current->reclaim_state;
+       struct scan_control sc;
        int i;
-       unsigned long total_scanned = 0;
-       int do_writepage = 0;
+
+       sc.gfp_mask = gfp_mask;
+       sc.may_writepage = 0;
 
        inc_page_state(allocstall);
 
@@ -865,23 +914,23 @@ int try_to_free_pages(struct zone **zones,
                zones[i]->temp_priority = DEF_PRIORITY;
 
        for (priority = DEF_PRIORITY; priority >= 0; priority--) {
-               int scanned = 0;
-               struct page_state ps;
-
-               get_page_state(&ps);
-               nr_reclaimed += shrink_caches(zones, priority, &scanned,
-                                               gfp_mask, &ps, do_writepage);
-               shrink_slab(scanned, gfp_mask);
+               sc.nr_mapped = read_page_state(nr_mapped);
+               sc.nr_scanned = 0;
+               sc.nr_reclaimed = 0;
+               sc.priority = priority;
+               shrink_caches(zones, &sc);
+               shrink_slab(sc.nr_scanned, gfp_mask);
                if (reclaim_state) {
-                       nr_reclaimed += reclaim_state->reclaimed_slab;
+                       sc.nr_reclaimed += reclaim_state->reclaimed_slab;
                        reclaim_state->reclaimed_slab = 0;
                }
-               if (nr_reclaimed >= SWAP_CLUSTER_MAX) {
+               if (sc.nr_reclaimed >= SWAP_CLUSTER_MAX) {
                        ret = 1;
                        goto out;
                }
-               if (!(gfp_mask & __GFP_FS))
-                       break;          /* Let the caller handle it */
+               total_scanned += sc.nr_scanned;
+               total_reclaimed += sc.nr_reclaimed;
+
                /*
                 * Try to write back as many pages as we just scanned.  This
                 * tends to cause slow streaming writers to write data to the
@@ -889,14 +938,13 @@ int try_to_free_pages(struct zone **zones,
                 * that's undesirable in laptop mode, where we *want* lumpy
                 * writeout.  So in laptop mode, write out the whole world.
                 */
-               total_scanned += scanned;
                if (total_scanned > SWAP_CLUSTER_MAX + SWAP_CLUSTER_MAX/2) {
                        wakeup_bdflush(laptop_mode ? 0 : total_scanned);
-                       do_writepage = 1;
+                       sc.may_writepage = 1;
                }
 
                /* Take a nap, wait for some writeback to complete */
-               if (scanned && priority < DEF_PRIORITY - 2)
+               if (sc.nr_scanned && priority < DEF_PRIORITY - 2)
                        blk_congestion_wait(WRITE, HZ/10);
        }
        if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY))
@@ -932,15 +980,18 @@ out:
  * the page allocator fallback scheme to ensure that aging of pages is balanced
  * across the zones.
  */
-static int balance_pgdat(pg_data_t *pgdat, int nr_pages, struct page_state *ps)
+static int balance_pgdat(pg_data_t *pgdat, int nr_pages)
 {
        int to_free = nr_pages;
        int priority;
        int i;
+       int total_scanned = 0, total_reclaimed = 0;
        struct reclaim_state *reclaim_state = current->reclaim_state;
-       unsigned long total_scanned = 0;
-       unsigned long total_reclaimed = 0;
-       int do_writepage = 0;
+       struct scan_control sc;
+
+       sc.gfp_mask = GFP_KERNEL;
+       sc.may_writepage = 0;
+       sc.nr_mapped = read_page_state(nr_mapped);
 
        inc_page_state(pageoutrun);
 
@@ -950,7 +1001,7 @@ static int balance_pgdat(pg_data_t *pgdat, int nr_pages, struct page_state *ps)
                zone->temp_priority = DEF_PRIORITY;
        }
 
-       for (priority = DEF_PRIORITY; priority; priority--) {
+       for (priority = DEF_PRIORITY; priority >= 0; priority--) {
                int all_zones_ok = 1;
                int end_zone = 0;       /* Inclusive.  0 = ZONE_DMA */
 
@@ -988,9 +1039,6 @@ scan:
                 */
                for (i = 0; i <= end_zone; i++) {
                        struct zone *zone = pgdat->node_zones + i;
-                       int max_scan;
-                       int reclaimed;
-                       int scanned = 0;
 
                        if (zone->all_unreclaimable && priority != DEF_PRIORITY)
                                continue;
@@ -1000,16 +1048,16 @@ scan:
                                        all_zones_ok = 0;
                        }
                        zone->temp_priority = priority;
-                       max_scan = (zone->nr_active + zone->nr_inactive)
-                                                               >> priority;
-                       reclaimed = shrink_zone(zone, max_scan, GFP_KERNEL,
-                                       &scanned, ps, do_writepage);
-                       total_scanned += scanned;
+                       if (zone->prev_priority > priority)
+                               zone->prev_priority = priority;
+                       sc.nr_scanned = 0;
+                       sc.nr_reclaimed = 0;
+                       sc.priority = priority;
+                       shrink_zone(zone, &sc);
                        reclaim_state->reclaimed_slab = 0;
-                       shrink_slab(scanned, GFP_KERNEL);
-                       reclaimed += reclaim_state->reclaimed_slab;
-                       total_reclaimed += reclaimed;
-                       to_free -= reclaimed;
+                       shrink_slab(sc.nr_scanned, GFP_KERNEL);
+                       sc.nr_reclaimed += reclaim_state->reclaimed_slab;
+                       total_reclaimed += sc.nr_reclaimed;
                        if (zone->all_unreclaimable)
                                continue;
                        if (zone->pages_scanned > zone->present_pages * 2)
@@ -1021,9 +1069,9 @@ scan:
                         */
                        if (total_scanned > SWAP_CLUSTER_MAX * 2 &&
                            total_scanned > total_reclaimed+total_reclaimed/2)
-                               do_writepage = 1;
+                               sc.may_writepage = 1;
                }
-               if (nr_pages && to_free > 0)
+               if (nr_pages && to_free > total_reclaimed)
                        continue;       /* swsusp: need to do more work */
                if (all_zones_ok)
                        break;          /* kswapd: all done */
@@ -1087,16 +1135,14 @@ int kswapd(void *p)
        tsk->flags |= PF_MEMALLOC|PF_KSWAPD;
 
        for ( ; ; ) {
-               struct page_state ps;
-
                if (current->flags & PF_FREEZE)
                        refrigerator(PF_FREEZE);
                prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
                schedule();
                finish_wait(&pgdat->kswapd_wait, &wait);
                try_to_clip_inodes();           
-               get_page_state(&ps);
-               balance_pgdat(pgdat, 0, &ps);
+
+               balance_pgdat(pgdat, 0);
        }
 }
 
@@ -1129,10 +1175,7 @@ int shrink_all_memory(int nr_pages)
        current->reclaim_state = &reclaim_state;
        for_each_pgdat(pgdat) {
                int freed;
-               struct page_state ps;
-
-               get_page_state(&ps);
-               freed = balance_pgdat(pgdat, nr_to_free, &ps);
+               freed = balance_pgdat(pgdat, nr_to_free);
                ret += freed;
                nr_to_free -= freed;
                if (nr_to_free <= 0)
index 6203a56..a44c900 100644 (file)
@@ -49,7 +49,7 @@ static char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>";
 static char vlan_buggyright[] = "David S. Miller <davem@redhat.com>";
 
 static int vlan_device_event(struct notifier_block *, unsigned long, void *);
-static int vlan_ioctl_handler(unsigned long);
+static int vlan_ioctl_handler(void __user *);
 static int unregister_vlan_dev(struct net_device *, unsigned short );
 
 struct notifier_block vlan_notifier_block = {
@@ -661,9 +661,9 @@ out:
 /*
  *     VLAN IOCTL handler.
  *     o execute requested action or pass command to the device driver
- *   arg is really a void* to a vlan_ioctl_args structure.
+ *   arg is really a struct vlan_ioctl_args __user *.
  */
-static int vlan_ioctl_handler(unsigned long arg)
+static int vlan_ioctl_handler(void __user *arg)
 {
        int err = 0;
        struct vlan_ioctl_args args;
@@ -675,8 +675,7 @@ static int vlan_ioctl_handler(unsigned long arg)
        if (!capable(CAP_NET_ADMIN))
                return -EPERM;
 
-       if (copy_from_user(&args, (void*)arg,
-                           sizeof(struct vlan_ioctl_args)))
+       if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args)))
                return -EFAULT;
 
        /* Null terminate this sucker, just in case. */
index 265d172..4170de1 100644 (file)
@@ -673,7 +673,7 @@ static int ddp_device_event(struct notifier_block *this, unsigned long event,
 
 /* ioctl calls. Shouldn't even need touching */
 /* Device configuration ioctl calls */
-static int atif_ioctl(int cmd, void *arg)
+static int atif_ioctl(int cmd, void __user *arg)
 {
        static char aarp_mcast[6] = { 0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF };
        struct ifreq atreq;
@@ -892,7 +892,7 @@ static int atif_ioctl(int cmd, void *arg)
 }
 
 /* Routing ioctl() calls */
-static int atrtr_ioctl(unsigned int cmd, void *arg)
+static int atrtr_ioctl(unsigned int cmd, void __user *arg)
 {
        struct rtentry rt;
 
@@ -1567,7 +1567,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
        struct atalk_route *rt;
        int err;
 
-       if (flags & ~MSG_DONTWAIT)
+       if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
                return -EINVAL;
 
        if (len > DDP_MAXSZ)
@@ -1769,6 +1769,7 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        int rc = -EINVAL;
        struct sock *sk = sock->sk;
+       void __user *argp = (void __user *)arg;
 
        switch (cmd) {
                /* Protocol layer */
@@ -1778,7 +1779,7 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
                        if (amount < 0)
                                amount = 0;
-                       rc = put_user(amount, (int *)arg);
+                       rc = put_user(amount, (int __user *)argp);
                        break;
                }
                case TIOCINQ: {
@@ -1791,18 +1792,18 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
                        if (skb)
                                amount = skb->len - sizeof(struct ddpehdr);
-                       rc = put_user(amount, (int *)arg);
+                       rc = put_user(amount, (int __user *)argp);
                        break;
                }
                case SIOCGSTAMP:
-                       rc = sock_get_timestamp(sk, (struct timeval __user *)arg);
+                       rc = sock_get_timestamp(sk, argp);
                        break;
                /* Routing */
                case SIOCADDRT:
                case SIOCDELRT:
                        rc = -EPERM;
                        if (capable(CAP_NET_ADMIN))
-                               rc = atrtr_ioctl(cmd, (void *)arg);
+                               rc = atrtr_ioctl(cmd, argp);
                        break;
                /* Interface */
                case SIOCGIFADDR:
@@ -1813,7 +1814,7 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                case SIOCSARP:          /* proxy AARP */
                case SIOCDARP:          /* proxy AARP */
                        rtnl_lock();
-                       rc = atif_ioctl(cmd, (void *)arg);
+                       rc = atif_ioctl(cmd, argp);
                        rtnl_unlock();
                        break;
                /* Physical layer ioctl calls */
@@ -1829,7 +1830,7 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                case SIOCGIFCOUNT:
                case SIOCGIFINDEX:
                case SIOCGIFNAME:
-                       rc = dev_ioctl(cmd, (void __user *)arg);
+                       rc = dev_ioctl(cmd, argp);
                        break;
        }
 
index 459bdee..96407a0 100644 (file)
@@ -114,7 +114,7 @@ int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr)
 }
 
 
-int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size)
+int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,int size)
 {
        unsigned long flags;
        struct atm_dev_addr *walk;
@@ -134,7 +134,7 @@ int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size)
                memcpy(tmp_bufp++, &walk->addr, sizeof(struct sockaddr_atmsvc));
        spin_unlock_irqrestore(&dev->lock, flags);
        error = total > size ? -E2BIG : total;
-       if (copy_to_user(u_buf, tmp_buf, total < size ? total : size))
+       if (copy_to_user(buf, tmp_buf, total < size ? total : size))
                error = -EFAULT;
        kfree(tmp_buf);
        return error;
index 89f651c..2affa3a 100644 (file)
@@ -13,6 +13,6 @@
 void atm_reset_addr(struct atm_dev *dev);
 int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
 int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
-int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size);
+int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,int size);
 
 #endif
index f469813..91a89d3 100644 (file)
@@ -342,12 +342,12 @@ static int br2684_mac_addr(struct net_device *dev, void *p)
 
 #ifdef CONFIG_ATM_BR2684_IPFILTER
 /* this IOCTL is experimental. */
-static int br2684_setfilt(struct atm_vcc *atmvcc, unsigned long arg)
+static int br2684_setfilt(struct atm_vcc *atmvcc, void __user *arg)
 {
        struct br2684_vcc *brvcc;
        struct br2684_filter_set fs;
 
-       if (copy_from_user(&fs, (void *) arg, sizeof fs))
+       if (copy_from_user(&fs, arg, sizeof fs))
                return -EFAULT;
        if (fs.ifspec.method != BR2684_FIND_BYNOTHING) {
                /*
@@ -494,7 +494,7 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
        netif_rx(skb);
 }
 
-static int br2684_regvcc(struct atm_vcc *atmvcc, unsigned long arg)
+static int br2684_regvcc(struct atm_vcc *atmvcc, void __user *arg)
 {
 /* assign a vcc to a dev
 Note: we do not have explicit unassign, but look at _push()
@@ -507,7 +507,7 @@ Note: we do not have explicit unassign, but look at _push()
        struct net_device *net_dev;
        struct atm_backend_br2684 be;
 
-       if (copy_from_user(&be, (void *) arg, sizeof be))
+       if (copy_from_user(&be, arg, sizeof be))
                return -EFAULT;
        brvcc = kmalloc(sizeof(struct br2684_vcc), GFP_KERNEL);
        if (!brvcc)
@@ -593,7 +593,7 @@ static void br2684_setup(struct net_device *netdev)
        INIT_LIST_HEAD(&brdev->brvccs);
 }
 
-static int br2684_create(unsigned long arg)
+static int br2684_create(void __user *arg)
 {
        int err;
        struct net_device *netdev;
@@ -602,7 +602,7 @@ static int br2684_create(unsigned long arg)
 
        DPRINTK("br2684_create\n");
 
-       if (copy_from_user(&ni, (void *) arg, sizeof ni)) {
+       if (copy_from_user(&ni, arg, sizeof ni)) {
                return -EFAULT;
        }
        if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500) {
@@ -642,13 +642,14 @@ static int br2684_ioctl(struct socket *sock, unsigned int cmd,
        unsigned long arg)
 {
        struct atm_vcc *atmvcc = ATM_SD(sock);
+       void __user *argp = (void __user *)arg;
 
        int err;
        switch(cmd) {
        case ATM_SETBACKEND:
        case ATM_NEWBACKENDIF: {
                atm_backend_t b;
-               err = get_user(b, (atm_backend_t *) arg);
+               err = get_user(b, (atm_backend_t __user *) argp);
                if (err)
                        return -EFAULT;
                if (b != ATM_BACKEND_BR2684)
@@ -656,9 +657,9 @@ static int br2684_ioctl(struct socket *sock, unsigned int cmd,
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
                if (cmd == ATM_SETBACKEND)
-                       return br2684_regvcc(atmvcc, arg);
+                       return br2684_regvcc(atmvcc, argp);
                else
-                       return br2684_create(arg);
+                       return br2684_create(argp);
                }
 #ifdef CONFIG_ATM_BR2684_IPFILTER
        case BR2684_SETFILT:
@@ -666,7 +667,7 @@ static int br2684_ioctl(struct socket *sock, unsigned int cmd,
                        return -ENOIOCTLCMD;
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
-               err = br2684_setfilt(atmvcc, arg);
+               err = br2684_setfilt(atmvcc, argp);
                return err;
 #endif /* CONFIG_ATM_BR2684_IPFILTER */
        }
index 859b727..ce00ea6 100644 (file)
@@ -509,7 +509,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
        struct atm_vcc *vcc;
        struct sk_buff *skb;
        int eff,error;
-       const void *buff;
+       const void __user *buff;
        int size;
 
        lock_sock(sk);
@@ -676,7 +676,7 @@ static int check_qos(struct atm_qos *qos)
 }
 
 int vcc_setsockopt(struct socket *sock, int level, int optname,
-                  char *optval, int optlen)
+                  char __user *optval, int optlen)
 {
        struct atm_vcc *vcc;
        unsigned long value;
@@ -704,7 +704,7 @@ int vcc_setsockopt(struct socket *sock, int level, int optname,
                                return 0;
                        }
                case SO_SETCLP:
-                       if (get_user(value,(unsigned long *) optval))
+                       if (get_user(value,(unsigned long __user *)optval))
                                return -EFAULT;
                        if (value) vcc->atm_options |= ATM_ATMOPT_CLP;
                        else vcc->atm_options &= ~ATM_ATMOPT_CLP;
@@ -719,7 +719,7 @@ int vcc_setsockopt(struct socket *sock, int level, int optname,
 
 
 int vcc_getsockopt(struct socket *sock, int level, int optname,
-                  char *optval, int *optlen)
+                  char __user *optval, int __user *optlen)
 {
        struct atm_vcc *vcc;
        int len;
@@ -738,7 +738,7 @@ int vcc_getsockopt(struct socket *sock, int level, int optname,
                            -EFAULT : 0;
                case SO_SETCLP:
                        return put_user(vcc->atm_options & ATM_ATMOPT_CLP ? 1 :
-                         0,(unsigned long *) optval) ? -EFAULT : 0;
+                         0,(unsigned long __user *)optval) ? -EFAULT : 0;
                case SO_ATMPVC:
                        {
                                struct sockaddr_atmpvc pvc;
index fe634ab..d4cb95c 100644 (file)
@@ -19,10 +19,10 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
                size_t total_len);
 unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait);
 int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
-int vcc_setsockopt(struct socket *sock, int level, int optname, char *optval,
-                  int optlen);
-int vcc_getsockopt(struct socket *sock, int level, int optname, char *optval,
-                  int *optlen);
+int vcc_setsockopt(struct socket *sock, int level, int optname,
+                  char __user *optval, int optlen);
+int vcc_getsockopt(struct socket *sock, int level, int optname,
+                  char __user *optval, int __user *optlen);
 
 void atm_shutdown_dev(struct atm_dev *dev);
 
index a2d9cd2..b15e724 100644 (file)
@@ -49,6 +49,7 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        struct atm_vcc *vcc;
        int error;
        struct list_head * pos;
+       void __user *argp = (void __user *)arg;
 
        vcc = ATM_SD(sock);
        switch (cmd) {
@@ -60,7 +61,7 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        }
                        error = put_user(vcc->sk->sk_sndbuf -
                                         atomic_read(&vcc->sk->sk_wmem_alloc),
-                                        (int *) arg) ? -EFAULT : 0;
+                                        (int __user *) argp) ? -EFAULT : 0;
                        goto done;
                case SIOCINQ:
                        {
@@ -72,12 +73,11 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                                }
                                skb = skb_peek(&vcc->sk->sk_receive_queue);
                                error = put_user(skb ? skb->len : 0,
-                                                (int *) arg) ? -EFAULT : 0;
+                                                (int __user *)argp) ? -EFAULT : 0;
                                goto done;
                        }
                case SIOCGSTAMP: /* borrowed from IP */
-                       error = sock_get_timestamp(vcc->sk,
-                                       (struct timeval __user *) arg);
+                       error = sock_get_timestamp(vcc->sk, argp);
                        goto done;
                case ATM_SETSC:
                        printk(KERN_WARNING "ATM_SETSC is obsolete\n");
@@ -131,7 +131,7 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        if (error != -ENOIOCTLCMD)
                goto done;
 
-       error = atm_dev_ioctl(cmd, arg);
+       error = atm_dev_ioctl(cmd, argp);
 
 done:
        return error;
index fb6cc84..b005e1a 100644 (file)
@@ -774,7 +774,7 @@ lec_pop(struct atm_vcc *vcc, struct sk_buff *skb)
 }
 
 int 
-lec_vcc_attach(struct atm_vcc *vcc, void *arg)
+lec_vcc_attach(struct atm_vcc *vcc, void __user *arg)
 {
        struct lec_vcc_priv *vpriv;
         int bytes_left;
@@ -1161,7 +1161,7 @@ static int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        err = lec_mcast_attach(vcc, (int) arg);
                        break;
                case ATMLEC_DATA:
-                       err = lec_vcc_attach(vcc, (void *) arg);
+                       err = lec_vcc_attach(vcc, (void __user *) arg);
                        break;
        }
 
index 673bd78..af65591 100644 (file)
@@ -148,7 +148,7 @@ struct lec_vcc_priv {
 #define LEC_VCC_PRIV(vcc)      ((struct lec_vcc_priv *)((vcc)->user_back))
 
 int lecd_attach(struct atm_vcc *vcc, int arg);
-int lec_vcc_attach(struct atm_vcc *vcc, void *arg);
+int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg);
 int lec_mcast_attach(struct atm_vcc *vcc, int arg);
 struct net_device *get_dev_lec(int itf);
 int make_lec(struct atm_vcc *vcc);
index 0ca1184..e629e89 100644 (file)
@@ -565,7 +565,7 @@ static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev)
        return retval;
 }
 
-int atm_mpoa_vcc_attach(struct atm_vcc *vcc, long arg)
+int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg)
 {
        int bytes_left;
        struct mpoa_client *mpc;
@@ -574,7 +574,7 @@ int atm_mpoa_vcc_attach(struct atm_vcc *vcc, long arg)
        uint32_t  ipaddr;
        unsigned char *ip;
 
-       bytes_left = copy_from_user(&ioc_data, (void *)arg, sizeof(struct atmmpc_ioc));
+       bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmmpc_ioc));
        if (bytes_left != 0) {
                printk("mpoa: mpc_vcc_attach: Short read (missed %d bytes) from userland\n", bytes_left);
                return -EFAULT;
@@ -1366,7 +1366,7 @@ static void clean_up(struct k_message *msg, struct mpoa_client *mpc, int action)
        return;
 }
 
-static void mpc_timer_refresh()
+static void mpc_timer_refresh(void)
 {
        mpc_timer.expires = jiffies + (MPC_P2 * HZ);
        mpc_timer.data = mpc_timer.expires;
@@ -1418,7 +1418,7 @@ static int atm_mpoa_ioctl(struct socket *sock, unsigned int cmd, unsigned long a
                                sock->state = SS_CONNECTED;
                        break;
                case ATMMPC_DATA:
-                       err = atm_mpoa_vcc_attach(vcc, arg);
+                       err = atm_mpoa_vcc_attach(vcc, (void __user *)arg);
                        break;
                default:
                        break;
index a28e4b2..c7b1108 100644 (file)
@@ -13,7 +13,7 @@ int msg_to_mpoad(struct k_message *msg, struct mpoa_client *mpc);
 
 /* Functions for ioctl(ATMMPC_*) operations */
 int atm_mpoa_mpoad_attach(struct atm_vcc *vcc, int arg);
-int atm_mpoa_vcc_attach(struct atm_vcc *vcc, long arg);
+int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg);
 
 struct mpoa_client {
         struct mpoa_client *next;
index 6201756..64c676d 100644 (file)
 extern struct mpoa_client *mpcs;
 extern struct proc_dir_entry *atm_proc_root;  /* from proc.c. */
 
-static ssize_t proc_mpc_read(struct file *file, char *buff,
+static ssize_t proc_mpc_read(struct file *file, char __user *buff,
                             size_t count, loff_t *pos);
 
-static ssize_t proc_mpc_write(struct file *file, const char *buff,
+static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
                               size_t nbytes, loff_t *ppos);
 
 static int parse_qos(const char *buff, int len);
@@ -99,7 +99,7 @@ static const char *egress_state_string(int state){
 /*
  * READING function - called when the /proc/atm/mpoa file is read from.
  */
-static ssize_t proc_mpc_read(struct file *file, char *buff,
+static ssize_t proc_mpc_read(struct file *file, char __user *buff,
                             size_t count, loff_t *pos){
         unsigned long page = 0;
        unsigned char *temp;
@@ -165,12 +165,12 @@ static ssize_t proc_mpc_read(struct file *file, char *buff,
         return length;
 }
 
-static ssize_t proc_mpc_write(struct file *file, const char *buff,
+static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
                               size_t nbytes, loff_t *ppos)
 {
         int incoming, error, retval;
         char *page, c;
-        const char *tmp;
+        const char __user *tmp;
 
         if (nbytes == 0) return 0;
         if (nbytes >= PAGE_SIZE) nbytes = PAGE_SIZE-1;
index 95b63a0..e430c24 100644 (file)
@@ -257,10 +257,10 @@ static int pppoatm_devppp_ioctl(struct ppp_channel *chan, unsigned int cmd,
 {
        switch (cmd) {
        case PPPIOCGFLAGS:
-               return put_user(chan_to_pvcc(chan)->flags, (int *) arg)
+               return put_user(chan_to_pvcc(chan)->flags, (int __user *) arg)
                    ? -EFAULT : 0;
        case PPPIOCSFLAGS:
-               return get_user(chan_to_pvcc(chan)->flags, (int *) arg)
+               return get_user(chan_to_pvcc(chan)->flags, (int __user *) arg)
                    ? -EFAULT : 0;
        }
        return -ENOTTY;
@@ -271,7 +271,7 @@ static /*const*/ struct ppp_channel_ops pppoatm_ops = {
        .ioctl = pppoatm_devppp_ioctl,
 };
 
-static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, unsigned long arg)
+static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, void __user *arg)
 {
        struct atm_backend_ppp be;
        struct pppoatm_vcc *pvcc;
@@ -281,7 +281,7 @@ static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, unsigned long arg)
         * prototypical one used to initialize them
         */
        static const DECLARE_TASKLET(tasklet_proto, pppoatm_wakeup_sender, 0);
-       if (copy_from_user(&be, (void *) arg, sizeof be))
+       if (copy_from_user(&be, arg, sizeof be))
                return -EFAULT;
        if (be.encaps != PPPOATM_ENCAPS_AUTODETECT &&
            be.encaps != PPPOATM_ENCAPS_VC && be.encaps != PPPOATM_ENCAPS_LLC)
@@ -319,26 +319,27 @@ static int pppoatm_ioctl(struct socket *sock, unsigned int cmd,
        unsigned long arg)
 {
        struct atm_vcc *atmvcc = ATM_SD(sock);
+       void __user *argp = (void __user *)arg;
 
        if (cmd != ATM_SETBACKEND && atmvcc->push != pppoatm_push)
                return -ENOIOCTLCMD;
        switch (cmd) {
        case ATM_SETBACKEND: {
                atm_backend_t b;
-               if (get_user(b, (atm_backend_t *) arg))
+               if (get_user(b, (atm_backend_t __user *) argp))
                        return -EFAULT;
                if (b != ATM_BACKEND_PPP)
                        return -ENOIOCTLCMD;
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
-               return pppoatm_assign_vcc(atmvcc, arg);
+               return pppoatm_assign_vcc(atmvcc, argp);
                }
        case PPPIOCGCHAN:
                return put_user(ppp_channel_index(&atmvcc_to_pvcc(atmvcc)->
-                   chan), (int *) arg) ? -EFAULT : 0;
+                   chan), (int __user *) argp) ? -EFAULT : 0;
        case PPPIOCGUNIT:
                return put_user(ppp_unit_number(&atmvcc_to_pvcc(atmvcc)->
-                   chan), (int *) arg) ? -EFAULT : 0;
+                   chan), (int __user *) argp) ? -EFAULT : 0;
        }
        return -ENOIOCTLCMD;
 }
index fffc39b..12f49fe 100644 (file)
@@ -31,7 +31,7 @@
 #include "common.h" /* atm_proc_init prototype */
 #include "signaling.h" /* to get sigd - ugly too */
 
-static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count,
+static ssize_t proc_dev_atm_read(struct file *file,char __user *buf,size_t count,
     loff_t *pos);
 
 static struct file_operations proc_atm_dev_ops = {
@@ -384,8 +384,8 @@ static struct file_operations svc_seq_fops = {
        .release        = vcc_seq_release,
 };
 
-static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count,
-    loff_t *pos)
+static ssize_t proc_dev_atm_read(struct file *file, char __user *buf,
+                                size_t count, loff_t *pos)
 {
        struct atm_dev *dev;
        unsigned long page;
index a72dc2d..58de2ac 100644 (file)
@@ -180,7 +180,7 @@ static void subtract_aal_stats(struct k_atm_aal_stats *from,
 }
 
 
-static int fetch_stats(struct atm_dev *dev, struct atm_dev_stats *arg, int zero)
+static int fetch_stats(struct atm_dev *dev, struct atm_dev_stats __user *arg, int zero)
 {
        struct atm_dev_stats tmp;
        int error = 0;
@@ -199,19 +199,20 @@ static int fetch_stats(struct atm_dev *dev, struct atm_dev_stats *arg, int zero)
 }
 
 
-int atm_dev_ioctl(unsigned int cmd, unsigned long arg)
+int atm_dev_ioctl(unsigned int cmd, void __user *arg)
 {
-       void *buf;
+       void __user *buf;
        int error, len, number, size = 0;
        struct atm_dev *dev;
        struct list_head *p;
        int *tmp_buf, *tmp_p;
-
+       struct atm_iobuf __user *iobuf = arg;
+       struct atmif_sioc __user *sioc = arg;
        switch (cmd) {
                case ATM_GETNAMES:
-                       if (get_user(buf, &((struct atm_iobuf *) arg)->buffer))
+                       if (get_user(buf, &iobuf->buffer))
                                return -EFAULT;
-                       if (get_user(len, &((struct atm_iobuf *) arg)->length))
+                       if (get_user(len, &iobuf->length))
                                return -EFAULT;
                        spin_lock(&atm_dev_lock);
                        list_for_each(p, &atm_devs)
@@ -232,7 +233,7 @@ int atm_dev_ioctl(unsigned int cmd, unsigned long arg)
                        }
                        spin_unlock(&atm_dev_lock);
                        error = ((copy_to_user(buf, tmp_buf, size)) ||
-                                       put_user(size, &((struct atm_iobuf *) arg)->length))
+                                       put_user(size, &iobuf->length))
                                                ? -EFAULT : 0;
                        kfree(tmp_buf);
                        return error;
@@ -240,11 +241,11 @@ int atm_dev_ioctl(unsigned int cmd, unsigned long arg)
                        break;
        }
 
-       if (get_user(buf, &((struct atmif_sioc *) arg)->arg))
+       if (get_user(buf, &sioc->arg))
                return -EFAULT;
-       if (get_user(len, &((struct atmif_sioc *) arg)->length))
+       if (get_user(len, &sioc->length))
                return -EFAULT;
-       if (get_user(number, &((struct atmif_sioc *) arg)->number))
+       if (get_user(number, &sioc->number))
                return -EFAULT;
 
        if (!(dev = atm_dev_lookup(number)))
@@ -351,7 +352,7 @@ int atm_dev_ioctl(unsigned int cmd, unsigned long arg)
                        size = error;
                        /* may return 0, but later on size == 0 means "don't
                           write the length" */
-                       error = put_user(size, &((struct atmif_sioc *) arg)->length)
+                       error = put_user(size, &sioc->length)
                                ? -EFAULT : 0;
                        goto done;
                case ATM_SETLOOP:
@@ -385,7 +386,7 @@ int atm_dev_ioctl(unsigned int cmd, unsigned long arg)
        }
        
        if (size)
-               error = put_user(size, &((struct atmif_sioc *) arg)->length)
+               error = put_user(size, &sioc->length)
                        ? -EFAULT : 0;
        else
                error = 0;
index 5f69a94..1291061 100644 (file)
@@ -14,7 +14,7 @@ extern struct list_head atm_devs;
 extern spinlock_t atm_dev_lock;
 
 
-int atm_dev_ioctl(unsigned int cmd, unsigned long arg);
+int atm_dev_ioctl(unsigned int cmd, void __user *arg);
 
 
 #ifdef CONFIG_PROC_FS
index 563350a..47fbd98 100644 (file)
@@ -336,7 +336,7 @@ void ax25_destroy_socket(ax25_cb *ax25)
  *               includes a KILL command to abort any connection.
  *               VERY useful for debugging ;-)
  */
-static int ax25_ctl_ioctl(const unsigned int cmd, void *arg)
+static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
 {
        struct ax25_ctl_struct ax25_ctl;
        ax25_digi digi;
@@ -1413,9 +1413,8 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,
        size_t size;
        int lv, err, addr_len = msg->msg_namelen;
 
-       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR)) {
+       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
                return -EINVAL;
-       }
 
        lock_sock(sk);
        ax25 = ax25_sk(sk);
@@ -1669,6 +1668,7 @@ static int ax25_shutdown(struct socket *sk, int how)
 static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
+       void __user *argp = (void __user *)arg;
        int res = 0;
 
        lock_sock(sk);
@@ -1678,7 +1678,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
                if (amount < 0)
                        amount = 0;
-               res = put_user(amount, (int *)arg);
+               res = put_user(amount, (int __user *)argp);
                break;
        }
 
@@ -1688,13 +1688,13 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                /* These two are safe on a single CPU system as only user tasks fiddle here */
                if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
                        amount = skb->len;
-               res = put_user(amount, (int *)arg);
+               res = put_user(amount, (int __user *)argp);
                break;
        }
 
        case SIOCGSTAMP:
                if (sk != NULL) {
-                       res = sock_get_timestamp(sk, (struct timeval __user *)arg);
+                       res = sock_get_timestamp(sk, argp);
                        break;
                }
                res = -EINVAL;
@@ -1704,7 +1704,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        case SIOCAX25DELUID:    /* Delete a uid from the uid/call map table */
        case SIOCAX25GETUID: {
                struct sockaddr_ax25 sax25;
-               if (copy_from_user(&sax25, (void *)arg, sizeof(sax25))) {
+               if (copy_from_user(&sax25, argp, sizeof(sax25))) {
                        res = -EFAULT;
                        break;
                }
@@ -1718,7 +1718,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        res = -EPERM;
                        break;
                }
-               if (get_user(amount, (long *)arg)) {
+               if (get_user(amount, (long __user *)argp)) {
                        res = -EFAULT;
                        break;
                }
@@ -1738,7 +1738,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        res = -EPERM;
                        break;
                }
-               res = ax25_rt_ioctl(cmd, (void *)arg);
+               res = ax25_rt_ioctl(cmd, argp);
                break;
 
        case SIOCAX25CTLCON:
@@ -1746,7 +1746,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        res = -EPERM;
                        break;
                }
-               res = ax25_ctl_ioctl(cmd, (void *)arg);
+               res = ax25_ctl_ioctl(cmd, argp);
                break;
 
        case SIOCAX25GETINFO:
@@ -1783,12 +1783,12 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                                warned=1;
                        }
 
-                       if (copy_to_user((void *)arg, &ax25_info, sizeof(struct ax25_info_struct_deprecated))) {
+                       if (copy_to_user(argp, &ax25_info, sizeof(struct ax25_info_struct_deprecated))) {
                                res = -EFAULT;
                                break;
                        }
                } else {
-                       if (copy_to_user((void *)arg, &ax25_info, sizeof(struct ax25_info_struct))) {
+                       if (copy_to_user(argp, &ax25_info, sizeof(struct ax25_info_struct))) {
                                res = -EINVAL;
                                break;
                        }
@@ -1804,7 +1804,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        res = -EPERM;
                        break;
                }
-               if (copy_from_user(&ax25_fwd, (void *)arg, sizeof(ax25_fwd))) {
+               if (copy_from_user(&ax25_fwd, argp, sizeof(ax25_fwd))) {
                        res = -EFAULT;
                        break;
                }
@@ -1826,7 +1826,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                break;
 
        default:
-               res = dev_ioctl(cmd, (void __user *)arg);
+               res = dev_ioctl(cmd, argp);
                break;
        }
        release_sock(sk);
index 7c977eb..de40eee 100644 (file)
@@ -253,7 +253,7 @@ out:
        return err;
 }
 
-int ax25_rt_ioctl(unsigned int cmd, void *arg)
+int ax25_rt_ioctl(unsigned int cmd, void __user *arg)
 {
        struct ax25_route_opt_struct rt_option;
        struct ax25_routes_struct route;
index 0978a58..990e503 100644 (file)
@@ -77,6 +77,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        struct bnep_conndel_req  cd;
        struct bnep_conninfo ci;
        struct socket *nsock;
+       void __user *argp = (void __user *)arg;
        int err;
 
        BT_DBG("cmd %x arg %lx", cmd, arg);
@@ -86,7 +87,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
                if (!capable(CAP_NET_ADMIN))
                        return -EACCES;
 
-               if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
+               if (copy_from_user(&ca, argp, sizeof(ca)))
                        return -EFAULT;
        
                nsock = sockfd_lookup(ca.sock, &err);
@@ -100,7 +101,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
 
                err = bnep_add_connection(&ca, nsock);
                if (!err) {
-                       if (copy_to_user((void *) arg, &ca, sizeof(ca)))
+                       if (copy_to_user(argp, &ca, sizeof(ca)))
                                err = -EFAULT;
                } else
                        fput(nsock->file);
@@ -111,30 +112,30 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
                if (!capable(CAP_NET_ADMIN))
                        return -EACCES;
 
-               if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
+               if (copy_from_user(&cd, argp, sizeof(cd)))
                        return -EFAULT;
        
                return bnep_del_connection(&cd);
 
        case BNEPGETCONNLIST:
-               if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
+               if (copy_from_user(&cl, argp, sizeof(cl)))
                        return -EFAULT;
 
                if (cl.cnum <= 0)
                        return -EINVAL;
        
                err = bnep_get_connlist(&cl);
-               if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
+               if (!err && copy_to_user(argp, &cl, sizeof(cl)))
                        return -EFAULT;
 
                return err;
 
        case BNEPGETCONNINFO:
-               if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
+               if (copy_from_user(&ci, argp, sizeof(ci)))
                        return -EFAULT;
 
                err = bnep_get_conninfo(&ci);
-               if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
+               if (!err && copy_to_user(argp, &ci, sizeof(ci)))
                        return -EFAULT;
 
                return err;
index 0a00626..58e4adc 100644 (file)
@@ -55,7 +55,7 @@ struct cmtp_conninfo {
 
 struct cmtp_connlist_req {
        __u32  cnum;
-       struct cmtp_conninfo *ci;
+       struct cmtp_conninfo __user *ci;
 };
 
 int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock);
index 6181559..bf4e7d7 100644 (file)
@@ -71,6 +71,7 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        struct cmtp_connlist_req cl;
        struct cmtp_conninfo ci;
        struct socket *nsock;
+       void __user *argp = (void __user *)arg;
        int err;
 
        BT_DBG("cmd %x arg %lx", cmd, arg);
@@ -80,7 +81,7 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
                if (!capable(CAP_NET_ADMIN))
                        return -EACCES;
 
-               if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
+               if (copy_from_user(&ca, argp, sizeof(ca)))
                        return -EFAULT;
 
                nsock = sockfd_lookup(ca.sock, &err);
@@ -94,7 +95,7 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
 
                err = cmtp_add_connection(&ca, nsock);
                if (!err) {
-                       if (copy_to_user((void *) arg, &ca, sizeof(ca)))
+                       if (copy_to_user(argp, &ca, sizeof(ca)))
                                err = -EFAULT;
                } else
                        fput(nsock->file);
@@ -105,30 +106,30 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
                if (!capable(CAP_NET_ADMIN))
                        return -EACCES;
 
-               if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
+               if (copy_from_user(&cd, argp, sizeof(cd)))
                        return -EFAULT;
 
                return cmtp_del_connection(&cd);
 
        case CMTPGETCONNLIST:
-               if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
+               if (copy_from_user(&cl, argp, sizeof(cl)))
                        return -EFAULT;
 
                if (cl.cnum <= 0)
                        return -EINVAL;
 
                err = cmtp_get_connlist(&cl);
-               if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
+               if (!err && copy_to_user(argp, &cl, sizeof(cl)))
                        return -EFAULT;
 
                return err;
 
        case CMTPGETCONNINFO:
-               if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
+               if (copy_from_user(&ci, argp, sizeof(ci)))
                        return -EFAULT;
 
                err = cmtp_get_conninfo(&ci);
-               if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
+               if (!err && copy_to_user(argp, &ci, sizeof(ci)))
                        return -EFAULT;
 
                return err;
index e279612..51976db 100644 (file)
@@ -353,7 +353,7 @@ void hci_conn_hash_flush(struct hci_dev *hdev)
        }
 }
 
-int hci_get_conn_list(unsigned long arg)
+int hci_get_conn_list(void __user *arg)
 {
        struct hci_conn_list_req req, *cl;
        struct hci_conn_info *ci;
@@ -361,7 +361,7 @@ int hci_get_conn_list(unsigned long arg)
        struct list_head *p;
        int n = 0, size, err;
 
-       if (copy_from_user(&req, (void *) arg, sizeof(req)))
+       if (copy_from_user(&req, arg, sizeof(req)))
                return -EFAULT;
 
        if (!req.conn_num || req.conn_num > (PAGE_SIZE * 2) / sizeof(*ci))
@@ -401,20 +401,20 @@ int hci_get_conn_list(unsigned long arg)
 
        hci_dev_put(hdev);
 
-       err = copy_to_user((void *) arg, cl, size);
+       err = copy_to_user(arg, cl, size);
        kfree(cl);
 
        return err ? -EFAULT : 0;
 }
 
-int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg)
+int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
 {
        struct hci_conn_info_req req;
        struct hci_conn_info ci;
        struct hci_conn *conn;
-       char *ptr = (void *) arg + sizeof(req);
+       char __user *ptr = arg + sizeof(req);
 
-       if (copy_from_user(&req, (void *) arg, sizeof(req)))
+       if (copy_from_user(&req, arg, sizeof(req)))
                return -EFAULT;
 
        hci_dev_lock_bh(hdev);
index 71ed408..69ab2e7 100644 (file)
@@ -366,15 +366,15 @@ static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
        hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, sizeof(cp), &cp);
 }
 
-int hci_inquiry(unsigned long arg)
+int hci_inquiry(void __user *arg)
 {
+       __u8 __user *ptr = arg;
        struct hci_inquiry_req ir;
        struct hci_dev *hdev;
        int err = 0, do_inquiry = 0, max_rsp;
        long timeo;
-       __u8 *buf, *ptr;
+       __u8 *buf;
 
-       ptr = (void *) arg;
        if (copy_from_user(&ir, ptr, sizeof(ir)))
                return -EFAULT;
 
@@ -616,13 +616,13 @@ int hci_dev_reset_stat(__u16 dev)
        return ret;
 }
 
-int hci_dev_cmd(unsigned int cmd, unsigned long arg)
+int hci_dev_cmd(unsigned int cmd, void __user *arg)
 {
        struct hci_dev *hdev;
        struct hci_dev_req dr;
        int err = 0;
 
-       if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
+       if (copy_from_user(&dr, arg, sizeof(dr)))
                return -EFAULT;
 
        if (!(hdev = hci_dev_get(dr.dev_id)))
@@ -685,7 +685,7 @@ int hci_dev_cmd(unsigned int cmd, unsigned long arg)
        return err;
 }
 
-int hci_get_dev_list(unsigned long arg)
+int hci_get_dev_list(void __user *arg)
 {
        struct hci_dev_list_req *dl;
        struct hci_dev_req *dr;
@@ -693,7 +693,7 @@ int hci_get_dev_list(unsigned long arg)
        int n = 0, size, err;
        __u16 dev_num;
 
-       if (get_user(dev_num, (__u16 *) arg))
+       if (get_user(dev_num, (__u16 __user *) arg))
                return -EFAULT;
 
        if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
@@ -720,19 +720,19 @@ int hci_get_dev_list(unsigned long arg)
        dl->dev_num = n;
        size = sizeof(*dl) + n * sizeof(*dr);
 
-       err = copy_to_user((void *) arg, dl, size);
+       err = copy_to_user(arg, dl, size);
        kfree(dl);
 
        return err ? -EFAULT : 0;
 }
 
-int hci_get_dev_info(unsigned long arg)
+int hci_get_dev_info(void __user *arg)
 {
        struct hci_dev *hdev;
        struct hci_dev_info di;
        int err = 0;
 
-       if (copy_from_user(&di, (void *) arg, sizeof(di)))
+       if (copy_from_user(&di, arg, sizeof(di)))
                return -EFAULT;
 
        if (!(hdev = hci_dev_get(di.dev_id)))
@@ -753,7 +753,7 @@ int hci_get_dev_info(unsigned long arg)
        memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
        memcpy(&di.features, &hdev->features, sizeof(di.features));
 
-       if (copy_to_user((void *) arg, &di, sizeof(di)))
+       if (copy_to_user(arg, &di, sizeof(di)))
                err = -EFAULT;
 
        hci_dev_put(hdev);
index 4d16b40..348a82f 100644 (file)
@@ -186,7 +186,7 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign
                return 0;
 
        case HCIGETCONNINFO:
-               return hci_get_conn_info(hdev, arg);
+               return hci_get_conn_info(hdev, (void __user *)arg);
 
        default:
                if (hdev->ioctl)
@@ -198,19 +198,20 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign
 static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
+       void __user *argp = (void __user *)arg;
        int err;
 
        BT_DBG("cmd %x arg %lx", cmd, arg);
 
        switch (cmd) {
        case HCIGETDEVLIST:
-               return hci_get_dev_list(arg);
+               return hci_get_dev_list(argp);
 
        case HCIGETDEVINFO:
-               return hci_get_dev_info(arg);
+               return hci_get_dev_info(argp);
 
        case HCIGETCONNLIST:
-               return hci_get_conn_list(arg);
+               return hci_get_conn_list(argp);
 
        case HCIDEVUP:
                if (!capable(CAP_NET_ADMIN))
@@ -242,10 +243,10 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a
        case HCISETSCOMTU:
                if (!capable(CAP_NET_ADMIN))
                        return -EACCES;
-               return hci_dev_cmd(cmd, arg);
+               return hci_dev_cmd(cmd, argp);
 
        case HCIINQUIRY:
-               return hci_inquiry(arg);
+               return hci_inquiry(argp);
 
        default:
                lock_sock(sk);
index 21a4556..298a25f 100644 (file)
@@ -95,17 +95,13 @@ static void l2cap_sock_timeout(unsigned long arg)
 static void l2cap_sock_set_timer(struct sock *sk, long timeout)
 {
        BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
-
-       if (!mod_timer(&sk->sk_timer, jiffies + timeout))
-               sock_hold(sk);
+       sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
 }
 
 static void l2cap_sock_clear_timer(struct sock *sk)
 {
        BT_DBG("sock %p state %d", sk, sk->sk_state);
-
-       if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer))
-               __sock_put(sk);
+       sk_stop_timer(sk, &sk->sk_timer);
 }
 
 static void l2cap_sock_init_timer(struct sock *sk)
index fbafeb2..1aa1387 100644 (file)
@@ -707,7 +707,7 @@ static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned lon
        lock_sock(sk);
 
 #ifdef CONFIG_BT_RFCOMM_TTY
-       err = rfcomm_dev_ioctl(sk, cmd, arg);
+       err = rfcomm_dev_ioctl(sk, cmd, (void __user *)arg);
 #else
        err = -EOPNOTSUPP;
 #endif
index 9a777b9..ed8abef 100644 (file)
@@ -302,13 +302,13 @@ static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size
 
 #define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
 
-static int rfcomm_create_dev(struct sock *sk, unsigned long arg)
+static int rfcomm_create_dev(struct sock *sk, void __user *arg)
 {
        struct rfcomm_dev_req req;
        struct rfcomm_dlc *dlc;
        int id;
 
-       if (copy_from_user(&req, (void *) arg, sizeof(req)))
+       if (copy_from_user(&req, arg, sizeof(req)))
                return -EFAULT;
 
        BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags);
@@ -344,12 +344,12 @@ static int rfcomm_create_dev(struct sock *sk, unsigned long arg)
        return id;
 }
 
-static int rfcomm_release_dev(unsigned long arg)
+static int rfcomm_release_dev(void __user *arg)
 {
        struct rfcomm_dev_req req;
        struct rfcomm_dev *dev;
 
-       if (copy_from_user(&req, (void *) arg, sizeof(req)))
+       if (copy_from_user(&req, arg, sizeof(req)))
                return -EFAULT;
 
        BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags);
@@ -370,7 +370,7 @@ static int rfcomm_release_dev(unsigned long arg)
        return 0;
 }
 
-static int rfcomm_get_dev_list(unsigned long arg)
+static int rfcomm_get_dev_list(void __user *arg)
 {
        struct rfcomm_dev_list_req *dl;
        struct rfcomm_dev_info *di;
@@ -380,7 +380,7 @@ static int rfcomm_get_dev_list(unsigned long arg)
 
        BT_DBG("");
 
-       if (get_user(dev_num, (u16 *) arg))
+       if (get_user(dev_num, (u16 __user *) arg))
                return -EFAULT;
 
        if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
@@ -412,13 +412,13 @@ static int rfcomm_get_dev_list(unsigned long arg)
        dl->dev_num = n;
        size = sizeof(*dl) + n * sizeof(*di);
 
-       err = copy_to_user((void *) arg, dl, size);
+       err = copy_to_user(arg, dl, size);
        kfree(dl);
 
        return err ? -EFAULT : 0;
 }
 
-static int rfcomm_get_dev_info(unsigned long arg)
+static int rfcomm_get_dev_info(void __user *arg)
 {
        struct rfcomm_dev *dev;
        struct rfcomm_dev_info di;
@@ -426,7 +426,7 @@ static int rfcomm_get_dev_info(unsigned long arg)
 
        BT_DBG("");
 
-       if (copy_from_user(&di, (void *)arg, sizeof(di)))
+       if (copy_from_user(&di, arg, sizeof(di)))
                return -EFAULT;
 
        if (!(dev = rfcomm_dev_get(di.id)))
@@ -438,16 +438,16 @@ static int rfcomm_get_dev_info(unsigned long arg)
        bacpy(&di.src, &dev->src);
        bacpy(&di.dst, &dev->dst);
 
-       if (copy_to_user((void *)arg, &di, sizeof(di)))
+       if (copy_to_user(arg, &di, sizeof(di)))
                err = -EFAULT;
 
        rfcomm_dev_put(dev);
        return err;
 }
 
-int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
+int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
 {
-       BT_DBG("cmd %d arg %ld", cmd, arg);
+       BT_DBG("cmd %d arg %p", cmd, arg);
 
        switch (cmd) {
        case RFCOMMCREATEDEV:
index 58af700..55a2667 100644 (file)
@@ -91,17 +91,13 @@ static void sco_sock_timeout(unsigned long arg)
 static void sco_sock_set_timer(struct sock *sk, long timeout)
 {
        BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout);
-
-       if (!mod_timer(&sk->sk_timer, jiffies + timeout))
-               sock_hold(sk);
+       sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
 }
 
 static void sco_sock_clear_timer(struct sock *sk)
 {
        BT_DBG("sock %p state %d", sk, sk->sk_state);
-
-       if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer))
-               __sock_put(sk);
+       sk_stop_timer(sk, &sk->sk_timer);
 }
 
 static void sco_sock_init_timer(struct sock *sk)
index 06fdee6..675d070 100644 (file)
@@ -33,8 +33,6 @@ static int __init br_init(void)
 {
        br_fdb_init();
 
-       br_sysfs_init();
-
 #ifdef CONFIG_BRIDGE_NETFILTER
        if (br_netfilter_init())
                return 1;
@@ -69,7 +67,6 @@ static void __exit br_deinit(void)
 #endif
 
        br_handle_frame_hook = NULL;
-       br_sysfs_fini();
        br_fdb_fini();
 }
 
index 8a6de04..2027560 100644 (file)
@@ -41,7 +41,7 @@ static int br_initial_port_cost(struct net_device *dev)
        int err;
 
        strncpy(ifr.ifr_name, dev->name, IFNAMSIZ);
-       ifr.ifr_data = (void *) &ecmd;
+       ifr.ifr_data = (void __user *) &ecmd;
 
        old_fs = get_fs();
        set_fs(KERNEL_DS);
index 17c7ee3..cceb018 100644 (file)
@@ -143,7 +143,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                b.gc_timer_value = br_timer_value(&br->gc_timer);
                rcu_read_unlock();
 
-               if (copy_to_user((void *)args[1], &b, sizeof(b)))
+               if (copy_to_user((void __user *)args[1], &b, sizeof(b)))
                        return -EFAULT;
 
                return 0;
@@ -168,7 +168,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                memset(indices, 0, num*sizeof(int));
 
                get_port_ifindices(br, indices, num);
-               if (copy_to_user((void *)args[1], indices, num*sizeof(int)))
+               if (copy_to_user((void __user *)args[1], indices, num*sizeof(int)))
                        num =  -EFAULT;
                kfree(indices);
                return num;
@@ -241,7 +241,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
                rcu_read_unlock();
 
-               if (copy_to_user((void *)args[1], &p, sizeof(p)))
+               if (copy_to_user((void __user *)args[1], &p, sizeof(p)))
                        return -EFAULT;
 
                return 0;
@@ -308,11 +308,11 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        return -EOPNOTSUPP;
 }
 
-static int old_deviceless(unsigned long uarg)
+static int old_deviceless(void __user *uarg)
 {
        unsigned long args[3];
 
-       if (copy_from_user(args, (void *)uarg, sizeof(args)))
+       if (copy_from_user(args, uarg, sizeof(args)))
                return -EFAULT;
 
        switch (args[0]) {
@@ -331,7 +331,7 @@ static int old_deviceless(unsigned long uarg)
                memset(indices, 0, args[2]*sizeof(int));
                args[2] = get_bridge_ifindices(indices, args[2]);
 
-               ret = copy_to_user((void *)args[1], indices, args[2]*sizeof(int))
+               ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int))
                        ? -EFAULT : args[2];
 
                kfree(indices);
@@ -346,7 +346,7 @@ static int old_deviceless(unsigned long uarg)
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
 
-               if (copy_from_user(buf, (void *)args[1], IFNAMSIZ))
+               if (copy_from_user(buf, (void __user *)args[1], IFNAMSIZ))
                        return -EFAULT;
 
                buf[IFNAMSIZ-1] = 0;
@@ -361,7 +361,7 @@ static int old_deviceless(unsigned long uarg)
        return -EOPNOTSUPP;
 }
 
-int br_ioctl_deviceless_stub(unsigned int cmd, unsigned long uarg)
+int br_ioctl_deviceless_stub(unsigned int cmd, void __user *uarg)
 {
        switch (cmd) {
        case SIOCGIFBR:
@@ -376,7 +376,7 @@ int br_ioctl_deviceless_stub(unsigned int cmd, unsigned long uarg)
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
 
-               if (copy_from_user(buf, (void __user *) uarg, IFNAMSIZ))
+               if (copy_from_user(buf, uarg, IFNAMSIZ))
                        return -EFAULT;
 
                buf[IFNAMSIZ-1] = 0;
index 9651cdf..7313d06 100644 (file)
@@ -165,7 +165,7 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
                skb_pull(skb, VLAN_HLEN);
                skb->nh.raw += VLAN_HLEN;
        }
-       skb->dst->output(skb);
+       skb->dst->output(&skb);
        return 0;
 }
 
@@ -800,7 +800,7 @@ static struct nf_hook_ops br_nf_ops[] = {
 #ifdef CONFIG_SYSCTL
 static
 int brnf_sysctl_call_tables(ctl_table *ctl, int write, struct file * filp,
-                       void *buffer, size_t *lenp)
+                       void __user *buffer, size_t *lenp)
 {
        int ret;
 
index 048e761..7cfb82b 100644 (file)
@@ -175,7 +175,7 @@ extern int br_handle_frame(struct sk_buff *skb);
 
 /* br_ioctl.c */
 extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-extern int br_ioctl_deviceless_stub(unsigned int cmd, unsigned long arg);
+extern int br_ioctl_deviceless_stub(unsigned int cmd, void __user *arg);
 
 /* br_netfilter.c */
 extern int br_netfilter_init(void);
@@ -217,9 +217,6 @@ extern void br_sysfs_removeif(struct net_bridge_port *p);
 extern void br_sysfs_freeif(struct net_bridge_port *p);
 
 /* br_sysfs_br.c */
-extern struct subsystem bridge_subsys;
-extern void br_sysfs_init(void);
-extern void br_sysfs_fini(void);
 extern int br_sysfs_addbr(struct net_device *dev);
 extern void br_sysfs_delbr(struct net_device *dev);
 
@@ -228,8 +225,6 @@ extern void br_sysfs_delbr(struct net_device *dev);
 #define br_sysfs_addif(p)      (0)
 #define br_sysfs_removeif(p)   do { } while(0)
 #define br_sysfs_freeif(p)     kfree(p)
-#define br_sysfs_init()                do { } while(0)
-#define br_sysfs_fini()                do { } while(0)
 #define br_sysfs_addbr(dev)    (0)
 #define br_sysfs_delbr(dev)    do { } while(0)
 #endif /* CONFIG_SYSFS */
index 61f00fa..98cf53c 100644 (file)
@@ -300,25 +300,6 @@ static struct bin_attribute bridge_forward = {
        .read = brforward_read,
 };
 
-
-/*
- * This is a dummy kset so bridge objects don't cause
- * hotplug events 
- */
-struct subsystem bridge_subsys = { 
-       .kset = { .hotplug_ops = NULL },
-};
-
-void br_sysfs_init(void)
-{
-       subsystem_register(&bridge_subsys);
-}
-
-void br_sysfs_fini(void)
-{
-       subsystem_unregister(&bridge_subsys);
-}
-
 /*
  * Add entries in sysfs onto the existing network class device
  * for the bridge.
@@ -353,7 +334,7 @@ int br_sysfs_addbr(struct net_device *dev)
        
        kobject_set_name(&br->ifobj, SYSFS_BRIDGE_PORT_SUBDIR);
        br->ifobj.ktype = NULL;
-       br->ifobj.kset = &bridge_subsys.kset;
+       br->ifobj.kset = NULL;
        br->ifobj.parent = brobj;
 
        err = kobject_register(&br->ifobj);
index 1788221..567249b 100644 (file)
@@ -227,7 +227,7 @@ int br_sysfs_addif(struct net_bridge_port *p)
        kobject_set_name(&p->kobj, SYSFS_BRIDGE_PORT_ATTR);
        p->kobj.ktype = &brport_ktype;
        p->kobj.parent = &(p->dev->class_dev.kobj);
-       p->kobj.kset = &bridge_subsys.kset;
+       p->kobj.kset = NULL;
 
        err = kobject_add(&p->kobj);
        if(err)
index a1a8ff3..e9b21b9 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the Linux networking core.
 #
 
-obj-y := sock.o skbuff.o iovec.o datagram.o scm.o
+obj-y := sock.o skbuff.o iovec.o datagram.o stream.o scm.o
 
 obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
 
index dfd505c..27cbb53 100644 (file)
@@ -1180,28 +1180,46 @@ void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
        rcu_read_unlock();
 }
 
-/* Calculate csum in the case, when packet is misrouted.
- * If it failed by some reason, ignore and send skb with wrong
- * checksum.
+/*
+ * Invalidate hardware checksum when packet is to be mangled, and
+ * complete checksum manually on outgoing path.
  */
-struct sk_buff *skb_checksum_help(struct sk_buff *skb)
+int skb_checksum_help(struct sk_buff **pskb, int inward)
 {
        unsigned int csum;
-       int offset = skb->h.raw - skb->data;
+       int ret = 0, offset = (*pskb)->h.raw - (*pskb)->data;
+
+       if (inward) {
+               (*pskb)->ip_summed = CHECKSUM_NONE;
+               goto out;
+       }
 
-       if (offset > (int)skb->len)
+       if (skb_shared(*pskb)  || skb_cloned(*pskb)) {
+               struct sk_buff *newskb = skb_copy(*pskb, GFP_ATOMIC);
+               if (!newskb) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               if ((*pskb)->sk)
+                       skb_set_owner_w(newskb, (*pskb)->sk);
+               kfree_skb(*pskb);
+               *pskb = newskb;
+       }
+
+       if (offset > (int)(*pskb)->len)
                BUG();
-       csum = skb_checksum(skb, offset, skb->len-offset, 0);
+       csum = skb_checksum(*pskb, offset, (*pskb)->len-offset, 0);
 
-       offset = skb->tail - skb->h.raw;
+       offset = (*pskb)->tail - (*pskb)->h.raw;
        if (offset <= 0)
                BUG();
-       if (skb->csum + 2 > offset)
+       if ((*pskb)->csum + 2 > offset)
                BUG();
 
-       *(u16*)(skb->h.raw + skb->csum) = csum_fold(csum);
-       skb->ip_summed = CHECKSUM_NONE;
-       return skb;
+       *(u16*)((*pskb)->h.raw + (*pskb)->csum) = csum_fold(csum);
+       (*pskb)->ip_summed = CHECKSUM_NONE;
+out:   
+       return ret;
 }
 
 #ifdef CONFIG_HIGHMEM
@@ -1326,10 +1344,9 @@ int dev_queue_xmit(struct sk_buff *skb)
        if (skb->ip_summed == CHECKSUM_HW &&
            (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
             (!(dev->features & NETIF_F_IP_CSUM) ||
-             skb->protocol != htons(ETH_P_IP)))) {
-               if ((skb = skb_checksum_help(skb)) == NULL)
-                       goto out;
-       }
+             skb->protocol != htons(ETH_P_IP))))
+               if (skb_checksum_help(&skb, 0))
+                       goto out_kfree_skb;
 
        /* Grab device queue */
        spin_lock_bh(&dev->queue_lock);
@@ -3160,6 +3177,8 @@ int unregister_netdevice(struct net_device *dev)
        /* Finish processing unregister after unlock */
        net_set_todo(dev);
 
+       synchronize_net();
+
        dev_put(dev);
        return 0;
 }
index ba4856c..42aeae5 100644 (file)
@@ -100,15 +100,15 @@ out:
        spin_unlock(&dst_lock);
 }
 
-static int dst_discard(struct sk_buff *skb)
+static int dst_discard_in(struct sk_buff *skb)
 {
        kfree_skb(skb);
        return 0;
 }
 
-static int dst_blackhole(struct sk_buff *skb)
+static int dst_discard_out(struct sk_buff **pskb)
 {
-       kfree_skb(skb);
+       kfree_skb(*pskb);
        return 0;
 }
 
@@ -128,8 +128,8 @@ void * dst_alloc(struct dst_ops * ops)
        dst->ops = ops;
        dst->lastuse = jiffies;
        dst->path = dst;
-       dst->input = dst_discard;
-       dst->output = dst_blackhole;
+       dst->input = dst_discard_in;
+       dst->output = dst_discard_out;
 #if RT_CACHE_DEBUG >= 2 
        atomic_inc(&dst_total);
 #endif
@@ -143,8 +143,8 @@ static void ___dst_free(struct dst_entry * dst)
           protocol module is unloaded.
         */
        if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) {
-               dst->input = dst_discard;
-               dst->output = dst_blackhole;
+               dst->input = dst_discard_in;
+               dst->output = dst_discard_out;
        }
        dst->obsolete = 2;
 }
@@ -210,6 +210,41 @@ again:
        return NULL;
 }
 
+/* Dirty hack. We did it in 2.2 (in __dst_free),
+ * we have _very_ good reasons not to repeat
+ * this mistake in 2.3, but we have no choice
+ * now. _It_ _is_ _explicit_ _deliberate_
+ * _race_ _condition_.
+ *
+ * Commented and originally written by Alexey.
+ */
+static void dst_ifdown(struct dst_entry *dst, int unregister)
+{
+       struct net_device *dev = dst->dev;
+
+       if (!unregister) {
+               dst->input = dst_discard_in;
+               dst->output = dst_discard_out;
+       }
+
+       do {
+               if (unregister) {
+                       dst->dev = &loopback_dev;
+                       dev_hold(&loopback_dev);
+                       dev_put(dev);
+                       if (dst->neighbour && dst->neighbour->dev == dev) {
+                               dst->neighbour->dev = &loopback_dev;
+                               dev_put(dev);
+                               dev_hold(&loopback_dev);
+                       }
+               }
+
+               if (dst->ops->ifdown)
+                       dst->ops->ifdown(dst, unregister);
+       } while ((dst = dst->child) && dst->flags & DST_NOHASH &&
+                dst->dev == dev);
+}
+
 static int dst_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
        struct net_device *dev = ptr;
@@ -220,29 +255,8 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, void
        case NETDEV_DOWN:
                spin_lock_bh(&dst_lock);
                for (dst = dst_garbage_list; dst; dst = dst->next) {
-                       if (dst->dev == dev) {
-                               /* Dirty hack. We did it in 2.2 (in __dst_free),
-                                  we have _very_ good reasons not to repeat
-                                  this mistake in 2.3, but we have no choice
-                                  now. _It_ _is_ _explicit_ _deliberate_
-                                  _race_ _condition_.
-                                */
-                               if (event!=NETDEV_DOWN &&
-                                   dst->output == dst_blackhole) {
-                                       dst->dev = &loopback_dev;
-                                       dev_put(dev);
-                                       dev_hold(&loopback_dev);
-                                       dst->output = dst_discard;
-                                       if (dst->neighbour && dst->neighbour->dev == dev) {
-                                               dst->neighbour->dev = &loopback_dev;
-                                               dev_put(dev);
-                                               dev_hold(&loopback_dev);
-                                       }
-                               } else {
-                                       dst->input = dst_discard;
-                                       dst->output = dst_blackhole;
-                               }
-                       }
+                       if (dst->dev == dev)
+                               dst_ifdown(dst, event != NETDEV_DOWN);
                }
                spin_unlock_bh(&dst_lock);
                break;
index 9925b81..d996db7 100644 (file)
@@ -650,8 +650,9 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
 int dev_ethtool(struct ifreq *ifr)
 {
        struct net_device *dev = __dev_get_by_name(ifr->ifr_name);
-       void __user *useraddr = (void __user *) ifr->ifr_data;
+       void __user *useraddr = ifr->ifr_data;
        u32 ethcmd;
+       int rc;
 
        /*
         * XXX: This can be pushed down into the ethtool_* handlers that
@@ -669,70 +670,109 @@ int dev_ethtool(struct ifreq *ifr)
        if (copy_from_user(&ethcmd, useraddr, sizeof (ethcmd)))
                return -EFAULT;
 
+       if(dev->ethtool_ops->begin)
+               if ((rc = dev->ethtool_ops->begin(dev)) < 0)
+                       return rc;
+
        switch (ethcmd) {
        case ETHTOOL_GSET:
-               return ethtool_get_settings(dev, useraddr);
+               rc = ethtool_get_settings(dev, useraddr);
+               break;
        case ETHTOOL_SSET:
-               return ethtool_set_settings(dev, useraddr);
+               rc = ethtool_set_settings(dev, useraddr);
+               break;
        case ETHTOOL_GDRVINFO:
-               return ethtool_get_drvinfo(dev, useraddr);
+               rc = ethtool_get_drvinfo(dev, useraddr);
+
+               break;
        case ETHTOOL_GREGS:
-               return ethtool_get_regs(dev, useraddr);
+               rc = ethtool_get_regs(dev, useraddr);
+               break;
        case ETHTOOL_GWOL:
-               return ethtool_get_wol(dev, useraddr);
+               rc = ethtool_get_wol(dev, useraddr);
+               break;
        case ETHTOOL_SWOL:
-               return ethtool_set_wol(dev, useraddr);
+               rc = ethtool_set_wol(dev, useraddr);
+               break;
        case ETHTOOL_GMSGLVL:
-               return ethtool_get_msglevel(dev, useraddr);
+               rc = ethtool_get_msglevel(dev, useraddr);
+               break;
        case ETHTOOL_SMSGLVL:
-               return ethtool_set_msglevel(dev, useraddr);
+               rc = ethtool_set_msglevel(dev, useraddr);
+               break;
        case ETHTOOL_NWAY_RST:
-               return ethtool_nway_reset(dev);
+               rc = ethtool_nway_reset(dev);
+               break;
        case ETHTOOL_GLINK:
-               return ethtool_get_link(dev, useraddr);
+               rc = ethtool_get_link(dev, useraddr);
+               break;
        case ETHTOOL_GEEPROM:
-               return ethtool_get_eeprom(dev, useraddr);
+               rc = ethtool_get_eeprom(dev, useraddr);
+               break;
        case ETHTOOL_SEEPROM:
-               return ethtool_set_eeprom(dev, useraddr);
+               rc = ethtool_set_eeprom(dev, useraddr);
+               break;
        case ETHTOOL_GCOALESCE:
-               return ethtool_get_coalesce(dev, useraddr);
+               rc = ethtool_get_coalesce(dev, useraddr);
+               break;
        case ETHTOOL_SCOALESCE:
-               return ethtool_set_coalesce(dev, useraddr);
+               rc = ethtool_set_coalesce(dev, useraddr);
+               break;
        case ETHTOOL_GRINGPARAM:
-               return ethtool_get_ringparam(dev, useraddr);
+               rc = ethtool_get_ringparam(dev, useraddr);
+               break;
        case ETHTOOL_SRINGPARAM:
-               return ethtool_set_ringparam(dev, useraddr);
+               rc = ethtool_set_ringparam(dev, useraddr);
+               break;
        case ETHTOOL_GPAUSEPARAM:
-               return ethtool_get_pauseparam(dev, useraddr);
+               rc = ethtool_get_pauseparam(dev, useraddr);
+               break;
        case ETHTOOL_SPAUSEPARAM:
-               return ethtool_set_pauseparam(dev, useraddr);
+               rc = ethtool_set_pauseparam(dev, useraddr);
+               break;
        case ETHTOOL_GRXCSUM:
-               return ethtool_get_rx_csum(dev, useraddr);
+               rc = ethtool_get_rx_csum(dev, useraddr);
+               break;
        case ETHTOOL_SRXCSUM:
-               return ethtool_set_rx_csum(dev, useraddr);
+               rc = ethtool_set_rx_csum(dev, useraddr);
+               break;
        case ETHTOOL_GTXCSUM:
-               return ethtool_get_tx_csum(dev, useraddr);
+               rc = ethtool_get_tx_csum(dev, useraddr);
+               break;
        case ETHTOOL_STXCSUM:
-               return ethtool_set_tx_csum(dev, useraddr);
+               rc = ethtool_set_tx_csum(dev, useraddr);
+               break;
        case ETHTOOL_GSG:
-               return ethtool_get_sg(dev, useraddr);
+               rc = ethtool_get_sg(dev, useraddr);
+               break;
        case ETHTOOL_SSG:
-               return ethtool_set_sg(dev, useraddr);
+               rc = ethtool_set_sg(dev, useraddr);
+               break;
        case ETHTOOL_GTSO:
-               return ethtool_get_tso(dev, useraddr);
+               rc = ethtool_get_tso(dev, useraddr);
+               break;
        case ETHTOOL_STSO:
-               return ethtool_set_tso(dev, useraddr);
+               rc = ethtool_set_tso(dev, useraddr);
+               break;
        case ETHTOOL_TEST:
-               return ethtool_self_test(dev, useraddr);
+               rc = ethtool_self_test(dev, useraddr);
+               break;
        case ETHTOOL_GSTRINGS:
-               return ethtool_get_strings(dev, useraddr);
+               rc = ethtool_get_strings(dev, useraddr);
+               break;
        case ETHTOOL_PHYS_ID:
-               return ethtool_phys_id(dev, useraddr);
+               rc = ethtool_phys_id(dev, useraddr);
+               break;
        case ETHTOOL_GSTATS:
-               return ethtool_get_stats(dev, useraddr);
+               rc = ethtool_get_stats(dev, useraddr);
+               break;
        default:
-               return -EOPNOTSUPP;
+               rc =  -EOPNOTSUPP;
        }
+       
+       if(dev->ethtool_ops->complete)
+               dev->ethtool_ops->complete(dev);
+       return rc;
 
  ioctl:
        if (dev->do_ioctl)
index 0f3c8b6..89de935 100644 (file)
@@ -157,7 +157,7 @@ int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
        }
 
        while (len > 0) {
-               u8 *base = iov->iov_base + offset;
+               u8 __user *base = iov->iov_base + offset;
                int copy = min_t(unsigned int, len, iov->iov_len - offset);
 
                offset = 0;
index 16baf92..20f1616 100644 (file)
@@ -414,7 +414,7 @@ int netdev_register_sysfs(struct net_device *net)
        if ((ret = class_device_register(class_dev)))
                goto out;
 
-       for (i = 0; (attr = net_class_attributes[i]); i++) {
+       for (i = 0; (attr = net_class_attributes[i]) != NULL; i++) {
                if ((ret = class_device_create_file(class_dev, attr)))
                    goto out_unreg;
        }
index dd8b9a8..58632d1 100644 (file)
@@ -504,14 +504,6 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
        unsigned int verdict;
        int ret = 0;
 
-       if (skb->ip_summed == CHECKSUM_HW) {
-               if (outdev == NULL) {
-                       skb->ip_summed = CHECKSUM_NONE;
-               } else {
-                       skb_checksum_help(skb);
-               }
-       }
-
        /* We may already have this, but read-locks nest anyway */
        rcu_read_lock();
 
index b1b450c..3821caa 100644 (file)
@@ -870,7 +870,7 @@ static int proc_read(char *buf , char **start, off_t offset,
        return p - buf;
 }
 
-static int count_trail_chars(const char *user_buffer, unsigned int maxlen)
+static int count_trail_chars(const char __user *user_buffer, unsigned int maxlen)
 {
        int i;
 
@@ -895,7 +895,7 @@ done:
        return i;
 }
 
-static unsigned long num_arg(const char *user_buffer, unsigned long maxlen,
+static unsigned long num_arg(const char __user *user_buffer, unsigned long maxlen,
                             unsigned long *num)
 {
        int i = 0;
@@ -916,7 +916,7 @@ static unsigned long num_arg(const char *user_buffer, unsigned long maxlen,
        return i;
 }
 
-static int strn_len(const char *user_buffer, unsigned int maxlen)
+static int strn_len(const char __user *user_buffer, unsigned int maxlen)
 {
        int i = 0;
 
@@ -940,7 +940,7 @@ done_str:
        return i;
 }
 
-static int proc_write(struct file *file, const char *user_buffer,
+static int proc_write(struct file *file, const char __user *user_buffer,
                         unsigned long count, void *data)
 {
        int i = 0, max, len;
index 8c433e7..289f582 100644 (file)
@@ -917,6 +917,31 @@ void __release_sock(struct sock *sk)
        } while((skb = sk->sk_backlog.head) != NULL);
 }
 
+/**
+ * sk_wait_data - wait for data to arrive at sk_receive_queue
+ * sk - sock to wait on
+ * timeo - for how long
+ *
+ * Now socket state including sk->sk_err is changed only under lock,
+ * hence we may omit checks after joining wait queue.
+ * We check receive queue before schedule() only as optimization;
+ * it is very likely that release_sock() added new data.
+ */
+int sk_wait_data(struct sock *sk, long *timeo)
+{
+       int rc;
+       DEFINE_WAIT(wait);
+
+       prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+       set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+       rc = sk_wait_event(sk, timeo, !skb_queue_empty(&sk->sk_receive_queue));
+       clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+       finish_wait(sk->sk_sleep, &wait);
+       return rc;
+}
+
+EXPORT_SYMBOL(sk_wait_data);
+
 /*
  * Set of default routines for initialising struct proto_ops when
  * the protocol does not support a particular function. In certain
@@ -1099,6 +1124,23 @@ void sk_send_sigurg(struct sock *sk)
                        sk_wake_async(sk, 3, POLL_PRI);
 }
 
+void sk_reset_timer(struct sock *sk, struct timer_list* timer,
+                   unsigned long expires)
+{
+       if (!mod_timer(timer, expires))
+               sock_hold(sk);
+}
+
+EXPORT_SYMBOL(sk_reset_timer);
+
+void sk_stop_timer(struct sock *sk, struct timer_list* timer)
+{
+       if (timer_pending(timer) && del_timer(timer))
+               __sock_put(sk);
+}
+
+EXPORT_SYMBOL(sk_stop_timer);
+
 void sock_init_data(struct socket *sock, struct sock *sk)
 {
        skb_queue_head_init(&sk->sk_receive_queue);
index 632de2c..c08a80f 100644 (file)
@@ -1212,7 +1212,7 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        {
        case SIOCGIFADDR:
        case SIOCSIFADDR:
-               return dn_dev_ioctl(cmd, (void *)arg);
+               return dn_dev_ioctl(cmd, (void __user *)arg);
 
        case SIOCATMARK:
                lock_sock(sk);
@@ -1226,7 +1226,7 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
                if (amount < 0)
                        amount = 0;
-               err = put_user(amount, (int *)arg);
+               err = put_user(amount, (int __user *)arg);
                break;
 
        case TIOCINQ:
@@ -1244,7 +1244,7 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        }
                }
                release_sock(sk);
-               err = put_user(amount, (int *)arg);
+               err = put_user(amount, (int __user *)arg);
                break;
 
        default:
@@ -1325,7 +1325,7 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char __use
        return err;
 }
 
-static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user __user *optval, int optlen, int flags) 
+static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, int optlen, int flags) 
 {
        struct  sock *sk = sock->sk;
        struct dn_scp *scp = DN_SK(sk);
@@ -1905,7 +1905,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
        unsigned char fctype;
        long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
 
-       if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE))
+       if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE|MSG_CMSG_COMPAT))
                return -EOPNOTSUPP;
 
        if (addr_len && (addr_len != sizeof(struct sockaddr_dn)))
index 6941da9..6b6e49a 100644 (file)
@@ -161,10 +161,10 @@ static int min_priority[1];
 static int max_priority[] = { 127 }; /* From DECnet spec */
 
 static int dn_forwarding_proc(ctl_table *, int, struct file *,
-                       void *, size_t *);
-static int dn_forwarding_sysctl(ctl_table *table, int *name, int nlen,
-                       void *oldval, size_t *oldlenp,
-                       void *newval, size_t newlen,
+                       void __user *, size_t *);
+static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen,
+                       void __user *oldval, size_t __user *oldlenp,
+                       void __user *newval, size_t newlen,
                        void **context);
 
 static struct dn_dev_sysctl_table {
@@ -362,7 +362,7 @@ static void dn_dev_check_default(struct net_device *dev)
 
 static int dn_forwarding_proc(ctl_table *table, int write, 
                                struct file *filep,
-                               void *buffer, size_t *lenp)
+                               void __user *buffer, size_t *lenp)
 {
 #ifdef CONFIG_DECNET_ROUTER
        struct net_device *dev = table->extra1;
@@ -404,9 +404,9 @@ static int dn_forwarding_proc(ctl_table *table, int write,
 #endif
 }
 
-static int dn_forwarding_sysctl(ctl_table *table, int *name, int nlen,
-                       void *oldval, size_t *oldlenp,
-                       void *newval, size_t newlen,
+static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen,
+                       void __user *oldval, size_t __user *oldlenp,
+                       void __user *newval, size_t newlen,
                        void **context)
 {
 #ifdef CONFIG_DECNET_ROUTER
@@ -423,7 +423,7 @@ static int dn_forwarding_sysctl(ctl_table *table, int *name, int nlen,
                if (newlen != sizeof(int))
                        return -EINVAL;
 
-               if (get_user(value, (int *)newval))
+               if (get_user(value, (int __user *)newval))
                        return -EFAULT;
                if (value < 0)
                        return -EINVAL;
@@ -553,7 +553,7 @@ static int dn_dev_set_ifa(struct net_device *dev, struct dn_ifaddr *ifa)
 }
 
 
-int dn_dev_ioctl(unsigned int cmd, void *arg)
+int dn_dev_ioctl(unsigned int cmd, void __user *arg)
 {
        char buffer[DN_IFREQ_SIZE];
        struct ifreq *ifr = (struct ifreq *)buffer;
index d9628db..90d0583 100644 (file)
@@ -684,8 +684,9 @@ out:
        return NET_RX_DROP;
 }
 
-static int dn_output(struct sk_buff *skb)
+static int dn_output(struct sk_buff **pskb)
 {
+       struct sk_buff *skb = *pskb;
        struct dst_entry *dst = skb->dst;
        struct dn_route *rt = (struct dn_route *)dst;
        struct net_device *dev = dst->dev;
@@ -796,6 +797,11 @@ static int dn_rt_bug(struct sk_buff *skb)
        return NET_RX_BAD;
 }
 
+static int dn_rt_bug_out(struct sk_buff **pskb)
+{
+       return dn_rt_bug(*pskb);
+}
+
 static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
 {
        struct dn_fib_info *fi = res->fi;
@@ -1387,7 +1393,7 @@ make_route:
        rt->u.dst.neighbour = neigh;
        rt->u.dst.dev = out_dev;
        rt->u.dst.lastuse = jiffies;
-       rt->u.dst.output = dn_rt_bug;
+       rt->u.dst.output = dn_rt_bug_out;
        switch(res.type) {
                case RTN_UNICAST:
                        rt->u.dst.input = dn_forward;
index 1c692b4..65ce3bb 100644 (file)
@@ -127,9 +127,9 @@ static int parse_addr(dn_address *addr, char *str)
 }
 
 
-static int dn_node_address_strategy(ctl_table *table, int *name, int nlen,
-                               void *oldval, size_t *oldlenp,
-                               void *newval, size_t newlen,
+static int dn_node_address_strategy(ctl_table *table, int __user *name, int nlen,
+                               void __user *oldval, size_t __user *oldlenp,
+                               void __user *newval, size_t newlen,
                                void **context)
 {
        size_t len;
@@ -141,14 +141,14 @@ static int dn_node_address_strategy(ctl_table *table, int *name, int nlen,
                if (len) {
                        if (len != sizeof(unsigned short))
                                return -EINVAL;
-                       if (put_user(decnet_address, (unsigned short *)oldval))
+                       if (put_user(decnet_address, (unsigned short __user *)oldval))
                                return -EFAULT;
                }
        }
        if (newval && newlen) {
                if (newlen != sizeof(unsigned short))
                        return -EINVAL;
-               if (get_user(addr, (unsigned short *)newval))
+               if (get_user(addr, (unsigned short __user *)newval))
                        return -EFAULT;
 
                dn_dev_devices_off();
@@ -162,7 +162,7 @@ static int dn_node_address_strategy(ctl_table *table, int *name, int nlen,
 
 static int dn_node_address_handler(ctl_table *table, int write, 
                                struct file *filp,
-                               void *buffer, size_t *lenp)
+                               void __user *buffer, size_t *lenp)
 {
        char addr[DN_ASCBUF_LEN];
        size_t len;
@@ -212,9 +212,9 @@ static int dn_node_address_handler(ctl_table *table, int write,
 }
 
 
-static int dn_def_dev_strategy(ctl_table *table, int *name, int nlen,
-                               void *oldval, size_t *oldlenp,
-                               void *newval, size_t newlen,
+static int dn_def_dev_strategy(ctl_table *table, int __user *name, int nlen,
+                               void __user *oldval, size_t __user *oldlenp,
+                               void __user *newval, size_t newlen,
                                void **context)
 {
        size_t len;
@@ -273,7 +273,7 @@ static int dn_def_dev_strategy(ctl_table *table, int *name, int nlen,
 
 static int dn_def_dev_handler(ctl_table *table, int write, 
                                struct file * filp,
-                               void *buffer, size_t *lenp)
+                               void __user *buffer, size_t *lenp)
 {
        size_t len;
        struct net_device *dev;
index 00ab04e..93103a3 100644 (file)
@@ -201,6 +201,7 @@ static int econet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len
        return 0;
 }
 
+#ifdef CONFIG_ECONET_NATIVE
 /*
  *     Queue a transmit result for the user to be told about.
  */
@@ -228,7 +229,6 @@ static void tx_result(struct sock *sk, unsigned long cookie, int result)
                kfree_skb(skb);
 }
 
-#ifdef CONFIG_ECONET_NATIVE
 /*
  *     Called by the Econet hardware driver when a packet transmit
  *     has completed.  Tell the user.
@@ -255,11 +255,6 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
        struct ec_addr addr;
        int err;
        unsigned char port, cb;
-       struct sk_buff *skb;
-       struct ec_cb *eb;
-#ifdef CONFIG_ECONET_NATIVE
-       unsigned short proto = 0;
-#endif
 #ifdef CONFIG_ECONET_AUNUDP
        struct msghdr udpmsg;
        struct iovec iov[msg->msg_iovlen+1];
@@ -274,8 +269,8 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
         *      Check the flags. 
         */
 
-       if (msg->msg_flags&~MSG_DONTWAIT
-               return(-EINVAL);
+       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)
+               return -EINVAL;
 
        /*
         *      Get and verify the address. 
@@ -316,6 +311,10 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
        {
                /* Real hardware Econet.  We're not worthy etc. */
 #ifdef CONFIG_ECONET_NATIVE
+               struct ec_cb *eb;
+               struct sk_buff *skb;
+               unsigned short proto = 0;
+
                dev_hold(dev);
                
                skb = sock_alloc_send_skb(sk, len+LL_RESERVED_SPACE(dev), 
@@ -418,10 +417,18 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 
        /* tack our header on the front of the iovec */
        size = sizeof(struct aunhdr);
+       /*
+        * XXX: that is b0rken.  We can't mix userland and kernel pointers
+        * in iovec, since on a lot of platforms copy_from_user() will
+        * *not* work with the kernel and userland ones at the same time,
+        * regardless of what we do with set_fs().  And we are talking about
+        * econet-over-ethernet here, so "it's only ARM anyway" doesn't
+        * apply.  Any suggestions on fixing that code?         -- AV
+        */
        iov[0].iov_base = (void *)&ah;
        iov[0].iov_len = size;
        for (i = 0; i < msg->msg_iovlen; i++) {
-               void *base = msg->msg_iov[i].iov_base;
+               void __user *base = msg->msg_iov[i].iov_base;
                size_t len = msg->msg_iov[i].iov_len;
                /* Check it now since we switch to KERNEL_DS later. */
                if ((err = verify_area(VERIFY_READ, base, len)) < 0)
@@ -589,7 +596,7 @@ out:
  *     Handle Econet specific ioctls
  */
 
-static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void *arg)
+static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
 {
        struct ifreq ifr;
        struct ec_device *edev;
@@ -662,18 +669,19 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void *arg)
 static int econet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
+       void __user *argp = (void __user *)arg;
 
        switch(cmd) {
                case SIOCGSTAMP:
-                       return sock_get_timestamp(sk,(struct timeval __user *)arg);
+                       return sock_get_timestamp(sk, argp);
 
                case SIOCSIFADDR:
                case SIOCGIFADDR:
-                       return ec_dev_ioctl(sock, cmd, (void *)arg);
+                       return ec_dev_ioctl(sock, cmd, argp);
                        break;
 
                default:
-                       return dev_ioctl(cmd,(void __user *) arg);
+                       return dev_ioctl(cmd, argp);
        }
        /*NOTREACHED*/
        return 0;
@@ -709,6 +717,7 @@ static struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
 #include <linux/smp_lock.h>
 SOCKOPS_WRAP(econet, PF_ECONET);
 
+#ifdef CONFIG_ECONET_AUNUDP
 /*
  *     Find the listening socket, if any, for the given data.
  */
@@ -753,8 +762,6 @@ static int ec_queue_packet(struct sock *sk, struct sk_buff *skb,
        return sock_queue_rcv_skb(sk, skb);
 }
 
-#ifdef CONFIG_ECONET_AUNUDP
-
 /*
  *     Send an AUN protocol response. 
  */
index d3395b0..0d62398 100644 (file)
@@ -54,10 +54,10 @@ static int ip_clear_mutable_options(struct iphdr *iph, u32 *daddr)
        return 0;
 }
 
-static int ah_output(struct sk_buff *skb)
+static int ah_output(struct sk_buff **pskb)
 {
        int err;
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = (*pskb)->dst;
        struct xfrm_state *x  = dst->xfrm;
        struct iphdr *iph, *top_iph;
        struct ip_auth_hdr *ah;
@@ -67,23 +67,24 @@ static int ah_output(struct sk_buff *skb)
                char            buf[60];
        } tmp_iph;
 
-       if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
-               err = -EINVAL;
-               goto error_nolock;
+       if ((*pskb)->ip_summed == CHECKSUM_HW) {
+               err = skb_checksum_help(pskb, 0);
+               if (err)
+                       goto error_nolock;
        }
 
        spin_lock_bh(&x->lock);
-       err = xfrm_check_output(x, skb, AF_INET);
+       err = xfrm_check_output(x, *pskb, AF_INET);
        if (err)
                goto error;
 
-       iph = skb->nh.iph;
+       iph = (*pskb)->nh.iph;
        if (x->props.mode) {
-               top_iph = (struct iphdr*)skb_push(skb, x->props.header_len);
+               top_iph = (struct iphdr*)skb_push(*pskb, x->props.header_len);
                top_iph->ihl = 5;
                top_iph->version = 4;
                top_iph->tos = 0;
-               top_iph->tot_len = htons(skb->len);
+               top_iph->tot_len = htons((*pskb)->len);
                top_iph->frag_off = 0;
                if (!(iph->frag_off&htons(IP_DF)))
                        __ip_select_ident(top_iph, dst, 0);
@@ -95,12 +96,12 @@ static int ah_output(struct sk_buff *skb)
                ah = (struct ip_auth_hdr*)(top_iph+1);
                ah->nexthdr = IPPROTO_IPIP;
        } else {
-               memcpy(&tmp_iph, skb->data, iph->ihl*4);
-               top_iph = (struct iphdr*)skb_push(skb, x->props.header_len);
+               memcpy(&tmp_iph, (*pskb)->data, iph->ihl*4);
+               top_iph = (struct iphdr*)skb_push(*pskb, x->props.header_len);
                memcpy(top_iph, &tmp_iph, iph->ihl*4);
                iph = &tmp_iph.iph;
                top_iph->tos = 0;
-               top_iph->tot_len = htons(skb->len);
+               top_iph->tot_len = htons((*pskb)->len);
                top_iph->frag_off = 0;
                top_iph->ttl = 0;
                top_iph->protocol = IPPROTO_AH;
@@ -120,14 +121,14 @@ static int ah_output(struct sk_buff *skb)
        ah->reserved = 0;
        ah->spi = x->id.spi;
        ah->seq_no = htonl(++x->replay.oseq);
-       ahp->icv(ahp, skb, ah->auth_data);
+       ahp->icv(ahp, *pskb, ah->auth_data);
        top_iph->tos = iph->tos;
        top_iph->ttl = iph->ttl;
        if (x->props.mode) {
                if (x->props.flags & XFRM_STATE_NOECN)
                        IP_ECN_clear(top_iph);
                top_iph->frag_off = iph->frag_off&~htons(IP_MF|IP_OFFSET);
-               memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+               memset(&(IPCB(*pskb)->opt), 0, sizeof(struct ip_options));
        } else {
                top_iph->frag_off = iph->frag_off;
                top_iph->daddr = iph->daddr;
@@ -136,12 +137,12 @@ static int ah_output(struct sk_buff *skb)
        }
        ip_send_check(top_iph);
 
-       skb->nh.raw = skb->data;
+       (*pskb)->nh.raw = (*pskb)->data;
 
-       x->curlft.bytes += skb->len;
+       x->curlft.bytes += (*pskb)->len;
        x->curlft.packets++;
        spin_unlock_bh(&x->lock);
-       if ((skb->dst = dst_pop(dst)) == NULL) {
+       if (((*pskb)->dst = dst_pop(dst)) == NULL) {
                err = -EHOSTUNREACH;
                goto error_nolock;
        }
@@ -150,7 +151,7 @@ static int ah_output(struct sk_buff *skb)
 error:
        spin_unlock_bh(&x->lock);
 error_nolock:
-       kfree_skb(skb);
+       kfree_skb(*pskb);
        return err;
 }
 
index d4696c1..4755e0d 100644 (file)
@@ -20,10 +20,10 @@ struct esp_decap_data {
        __u8            proto;
 };
 
-int esp_output(struct sk_buff *skb)
+int esp_output(struct sk_buff **pskb)
 {
        int err;
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = (*pskb)->dst;
        struct xfrm_state *x  = dst->xfrm;
        struct iphdr *iph, *top_iph;
        struct ip_esp_hdr *esph;
@@ -42,28 +42,28 @@ int esp_output(struct sk_buff *skb)
                char            buf[60];
        } tmp_iph;
 
-       /* First, if the skb is not checksummed, complete checksum. */
-       if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
-               err = -EINVAL;
-               goto error_nolock;
+       if ((*pskb)->ip_summed == CHECKSUM_HW) {
+               err = skb_checksum_help(pskb, 0);
+               if (err)
+                       goto error_nolock;
        }
 
        spin_lock_bh(&x->lock);
-       err = xfrm_check_output(x, skb, AF_INET);
+       err = xfrm_check_output(x, *pskb, AF_INET);
        if (err)
                goto error;
        err = -ENOMEM;
 
        /* Strip IP header in transport mode. Save it. */
        if (!x->props.mode) {
-               iph = skb->nh.iph;
+               iph = (*pskb)->nh.iph;
                memcpy(&tmp_iph, iph, iph->ihl*4);
-               __skb_pull(skb, iph->ihl*4);
+               __skb_pull(*pskb, iph->ihl*4);
        }
        /* Now skb is pure payload to encrypt */
 
        /* Round to block size */
-       clen = skb->len;
+       clen = (*pskb)->len;
 
        esp = x->data;
        alen = esp->auth.icv_trunc_len;
@@ -73,23 +73,23 @@ int esp_output(struct sk_buff *skb)
        if (esp->conf.padlen)
                clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1);
 
-       if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0)
+       if ((nfrags = skb_cow_data(*pskb, clen-(*pskb)->len+alen, &trailer)) < 0)
                goto error;
 
        /* Fill padding... */
        do {
                int i;
-               for (i=0; i<clen-skb->len - 2; i++)
+               for (i=0; i<clen-(*pskb)->len - 2; i++)
                        *(u8*)(trailer->tail + i) = i+1;
        } while (0);
-       *(u8*)(trailer->tail + clen-skb->len - 2) = (clen - skb->len)-2;
-       pskb_put(skb, trailer, clen - skb->len);
+       *(u8*)(trailer->tail + clen-(*pskb)->len - 2) = (clen - (*pskb)->len)-2;
+       pskb_put(*pskb, trailer, clen - (*pskb)->len);
 
        encap = x->encap;
 
-       iph = skb->nh.iph;
+       iph = (*pskb)->nh.iph;
        if (x->props.mode) {
-               top_iph = (struct iphdr*)skb_push(skb, x->props.header_len);
+               top_iph = (struct iphdr*)skb_push(*pskb, x->props.header_len);
                esph = (struct ip_esp_hdr*)(top_iph+1);
                if (encap && encap->encap_type) {
                        switch (encap->encap_type) {
@@ -121,7 +121,7 @@ int esp_output(struct sk_buff *skb)
                top_iph->tos = iph->tos;        /* DS disclosed */
                if (x->props.flags & XFRM_STATE_NOECN)
                        IP_ECN_clear(top_iph);
-               top_iph->tot_len = htons(skb->len + alen);
+               top_iph->tot_len = htons((*pskb)->len + alen);
                top_iph->frag_off = iph->frag_off&htons(IP_DF);
                if (!(top_iph->frag_off))
                        ip_select_ident(top_iph, dst, 0);
@@ -129,10 +129,10 @@ int esp_output(struct sk_buff *skb)
                top_iph->check = 0;
                top_iph->saddr = x->props.saddr.a4;
                top_iph->daddr = x->id.daddr.a4;
-               memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+               memset(&(IPCB(*pskb)->opt), 0, sizeof(struct ip_options));
        } else {
-               esph = (struct ip_esp_hdr*)skb_push(skb, x->props.header_len);
-               top_iph = (struct iphdr*)skb_push(skb, iph->ihl*4);
+               esph = (struct ip_esp_hdr*)skb_push(*pskb, x->props.header_len);
+               top_iph = (struct iphdr*)skb_push(*pskb, iph->ihl*4);
                memcpy(top_iph, &tmp_iph, iph->ihl*4);
                if (encap && encap->encap_type) {
                        switch (encap->encap_type) {
@@ -159,7 +159,7 @@ int esp_output(struct sk_buff *skb)
                } else
                        top_iph->protocol = IPPROTO_ESP;
                iph = &tmp_iph.iph;
-               top_iph->tot_len = htons(skb->len + alen);
+               top_iph->tot_len = htons((*pskb)->len + alen);
                top_iph->check = 0;
                top_iph->frag_off = iph->frag_off;
                *(u8*)(trailer->tail - 1) = iph->protocol;
@@ -169,7 +169,7 @@ int esp_output(struct sk_buff *skb)
        if (encap && uh) {
                uh->source = encap->encap_sport;
                uh->dest = encap->encap_dport;
-               uh->len = htons(skb->len + alen - sizeof(struct iphdr));
+               uh->len = htons((*pskb)->len + alen - sizeof(struct iphdr));
                uh->check = 0;
        }
 
@@ -188,7 +188,7 @@ int esp_output(struct sk_buff *skb)
                        if (!sg)
                                goto error;
                }
-               skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
+               skb_to_sgvec(*pskb, sg, esph->enc_data+esp->conf.ivlen-(*pskb)->data, clen);
                crypto_cipher_encrypt(tfm, sg, sg, clen);
                if (unlikely(sg != sgbuf))
                        kfree(sg);
@@ -200,19 +200,19 @@ int esp_output(struct sk_buff *skb)
        }
 
        if (esp->auth.icv_full_len) {
-               esp->auth.icv(esp, skb, (u8*)esph-skb->data,
+               esp->auth.icv(esp, *pskb, (u8*)esph-(*pskb)->data,
                              sizeof(struct ip_esp_hdr) + esp->conf.ivlen+clen, trailer->tail);
-               pskb_put(skb, trailer, alen);
+               pskb_put(*pskb, trailer, alen);
        }
 
        ip_send_check(top_iph);
 
-       skb->nh.raw = skb->data;
+       (*pskb)->nh.raw = (*pskb)->data;
 
-       x->curlft.bytes += skb->len;
+       x->curlft.bytes += (*pskb)->len;
        x->curlft.packets++;
        spin_unlock_bh(&x->lock);
-       if ((skb->dst = dst_pop(dst)) == NULL) {
+       if (((*pskb)->dst = dst_pop(dst)) == NULL) {
                err = -EHOSTUNREACH;
                goto error_nolock;
        }
@@ -221,7 +221,7 @@ int esp_output(struct sk_buff *skb)
 error:
        spin_unlock_bh(&x->lock);
 error_nolock:
-       kfree_skb(skb);
+       kfree_skb(*pskb);
        return err;
 }
 
index 84a3df3..60fc509 100644 (file)
@@ -223,8 +223,9 @@ int ip_finish_output(struct sk_buff *skb)
                       ip_finish_output2);
 }
 
-int ip_mc_output(struct sk_buff *skb)
+int ip_mc_output(struct sk_buff **pskb)
 {
+       struct sk_buff *skb = *pskb;
        struct sock *sk = skb->sk;
        struct rtable *rt = (struct rtable*)skb->dst;
        struct net_device *dev = rt->u.dst.dev;
@@ -255,7 +256,7 @@ int ip_mc_output(struct sk_buff *skb)
                    && ((rt->rt_flags&RTCF_LOCAL) || !(IPCB(skb)->flags&IPSKB_FORWARDED))
 #endif
                ) {
-                       struct sk_buff *newskb = skb_copy(skb, GFP_ATOMIC);
+                       struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
                        if (newskb)
                                NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL,
                                        newskb->dev, 
@@ -271,7 +272,7 @@ int ip_mc_output(struct sk_buff *skb)
        }
 
        if (rt->rt_flags&RTCF_BROADCAST) {
-               struct sk_buff *newskb = skb_copy(skb, GFP_ATOMIC);
+               struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
                if (newskb)
                        NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL,
                                newskb->dev, ip_dev_loopback_xmit);
@@ -283,8 +284,10 @@ int ip_mc_output(struct sk_buff *skb)
                return ip_finish_output(skb);
 }
 
-int ip_output(struct sk_buff *skb)
+int ip_output(struct sk_buff **pskb)
 {
+       struct sk_buff *skb = *pskb;
+
        IP_INC_STATS(OutRequests);
 
        if ((skb->len > dst_pmtu(skb->dst) || skb_shinfo(skb)->frag_list) &&
index 39e435a..58ff4c0 100644 (file)
@@ -759,6 +759,7 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
                                err = ip_mc_join_group(sk, &mreq);
                                if (err)
                                        break;
+                               greqs.gsr_interface = mreq.imr_ifindex;
                                omode = MCAST_INCLUDE;
                                add = 1;
                        } else /* MCAST_LEAVE_SOURCE_GROUP */ {
index 57d84fa..e20c7e4 100644 (file)
@@ -143,10 +143,10 @@ static void ipcomp_tunnel_encap(struct xfrm_state *x, struct sk_buff *skb)
        skb->nh.raw = skb->data;
 }
 
-static int ipcomp_output(struct sk_buff *skb)
+static int ipcomp_output(struct sk_buff **pskb)
 {
        int err;
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = (*pskb)->dst;
        struct xfrm_state *x = dst->xfrm;
        struct iphdr *iph, *top_iph;
        struct ip_comp_hdr *ipch;
@@ -157,25 +157,26 @@ static int ipcomp_output(struct sk_buff *skb)
        } tmp_iph;
        int hdr_len = 0;
 
-       if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
-               err = -EINVAL;
-               goto error_nolock;
+       if ((*pskb)->ip_summed == CHECKSUM_HW) {
+               err = skb_checksum_help(pskb, 0);
+               if (err)
+                       goto error_nolock;
        }
 
        spin_lock_bh(&x->lock);
-       err = xfrm_check_output(x, skb, AF_INET);
+       err = xfrm_check_output(x, *pskb, AF_INET);
        if (err)
                goto error;
 
        /* Don't bother compressing */
        if (!x->props.mode) {
-               iph = skb->nh.iph;
+               iph = (*pskb)->nh.iph;
                hdr_len = iph->ihl * 4;
        }
-       if ((skb->len - hdr_len) < ipcd->threshold) {
+       if (((*pskb)->len - hdr_len) < ipcd->threshold) {
                if (x->props.mode) {
-                       ipcomp_tunnel_encap(x, skb);
-                       iph = skb->nh.iph;
+                       ipcomp_tunnel_encap(x, *pskb);
+                       iph = (*pskb)->nh.iph;
                        iph->protocol = IPPROTO_IPIP;
                        ip_send_check(iph);
                }
@@ -183,19 +184,19 @@ static int ipcomp_output(struct sk_buff *skb)
        }
 
        if (x->props.mode) 
-               ipcomp_tunnel_encap(x, skb);
+               ipcomp_tunnel_encap(x, *pskb);
 
-       if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
-           skb_linearize(skb, GFP_ATOMIC) != 0) {
+       if ((skb_is_nonlinear(*pskb) || skb_cloned(*pskb)) &&
+           skb_linearize(*pskb, GFP_ATOMIC) != 0) {
                err = -ENOMEM;
                goto error;
        }
        
-       err = ipcomp_compress(x, skb);
+       err = ipcomp_compress(x, *pskb);
        if (err) {
                if (err == -EMSGSIZE) {
                        if (x->props.mode) {
-                               iph = skb->nh.iph;
+                               iph = (*pskb)->nh.iph;
                                iph->protocol = IPPROTO_IPIP;
                                ip_send_check(iph);
                        }
@@ -205,14 +206,14 @@ static int ipcomp_output(struct sk_buff *skb)
        }
 
        /* Install ipcomp header, convert into ipcomp datagram. */
-       iph = skb->nh.iph;
+       iph = (*pskb)->nh.iph;
        memcpy(&tmp_iph, iph, iph->ihl * 4);
-       top_iph = (struct iphdr *)skb_push(skb, sizeof(struct ip_comp_hdr));
+       top_iph = (struct iphdr *)skb_push(*pskb, sizeof(struct ip_comp_hdr));
        memcpy(top_iph, &tmp_iph, iph->ihl * 4);
        iph = top_iph;
        if (x->props.mode && (x->props.flags & XFRM_STATE_NOECN))
                IP_ECN_clear(iph);
-       iph->tot_len = htons(skb->len);
+       iph->tot_len = htons((*pskb)->len);
        iph->protocol = IPPROTO_COMP;
        iph->check = 0;
        ipch = (struct ip_comp_hdr *)((char *)iph + iph->ihl * 4);
@@ -220,14 +221,14 @@ static int ipcomp_output(struct sk_buff *skb)
        ipch->flags = 0;
        ipch->cpi = htons((u16 )ntohl(x->id.spi));
        ip_send_check(iph);
-       skb->nh.raw = skb->data;
+       (*pskb)->nh.raw = (*pskb)->data;
 
 out_ok:
-       x->curlft.bytes += skb->len;
+       x->curlft.bytes += (*pskb)->len;
        x->curlft.packets++;
        spin_unlock_bh(&x->lock);
        
-       if ((skb->dst = dst_pop(dst)) == NULL) {
+       if (((*pskb)->dst = dst_pop(dst)) == NULL) {
                err = -EHOSTUNREACH;
                goto error_nolock;
        }
@@ -238,7 +239,7 @@ out_exit:
 error:
        spin_unlock_bh(&x->lock);
 error_nolock:
-       kfree_skb(skb);
+       kfree_skb(*pskb);
        goto out_exit;
 }
 
index 64ccce5..a25e560 100644 (file)
@@ -1008,7 +1008,7 @@ int ip_mroute_getsockopt(struct sock *sk,int optname,char __user *optval,int __u
  *     The IP multicast ioctl support routines.
  */
  
-int ipmr_ioctl(struct sock *sk, int cmd, unsigned long arg)
+int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
 {
        struct sioc_sg_req sr;
        struct sioc_vif_req vr;
@@ -1018,7 +1018,7 @@ int ipmr_ioctl(struct sock *sk, int cmd, unsigned long arg)
        switch(cmd)
        {
                case SIOCGETVIFCNT:
-                       if (copy_from_user(&vr,(void *)arg,sizeof(vr)))
+                       if (copy_from_user(&vr,arg,sizeof(vr)))
                                return -EFAULT; 
                        if(vr.vifi>=maxvif)
                                return -EINVAL;
@@ -1031,14 +1031,14 @@ int ipmr_ioctl(struct sock *sk, int cmd, unsigned long arg)
                                vr.obytes=vif->bytes_out;
                                read_unlock(&mrt_lock);
 
-                               if (copy_to_user((void *)arg,&vr,sizeof(vr)))
+                               if (copy_to_user(arg,&vr,sizeof(vr)))
                                        return -EFAULT;
                                return 0;
                        }
                        read_unlock(&mrt_lock);
                        return -EADDRNOTAVAIL;
                case SIOCGETSGCNT:
-                       if (copy_from_user(&sr,(void *)arg,sizeof(sr)))
+                       if (copy_from_user(&sr,arg,sizeof(sr)))
                                return -EFAULT;
 
                        read_lock(&mrt_lock);
@@ -1049,7 +1049,7 @@ int ipmr_ioctl(struct sock *sk, int cmd, unsigned long arg)
                                sr.wrong_if = c->mfc_un.res.wrong_if;
                                read_unlock(&mrt_lock);
 
-                               if (copy_to_user((void *)arg,&sr,sizeof(sr)))
+                               if (copy_to_user(arg,&sr,sizeof(sr)))
                                        return -EFAULT;
                                return 0;
                        }
index a3aa641..9f4b94f 100644 (file)
@@ -735,6 +735,13 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
        if (skb->nfcache & NFC_IPVS_PROPERTY)
                return NF_ACCEPT;
 
+       if (skb->ip_summed == CHECKSUM_HW) {
+               if (skb_checksum_help(pskb, (out == NULL)))
+                       return NF_DROP;
+               if (skb != *pskb)
+                       skb = *pskb;
+       }
+
        iph = skb->nh.iph;
        if (unlikely(iph->protocol == IPPROTO_ICMP)) {
                int related, verdict = ip_vs_out_icmp(pskb, &related);
@@ -974,6 +981,13 @@ ip_vs_in(unsigned int hooknum, struct sk_buff **pskb,
                return NF_ACCEPT;
        }
 
+       if (skb->ip_summed == CHECKSUM_HW) {
+               if (skb_checksum_help(pskb, (out == NULL)))
+                       return NF_DROP;
+               if (skb != *pskb)
+                       skb = *pskb;
+       }
+
        iph = skb->nh.iph;
        if (unlikely(iph->protocol == IPPROTO_ICMP)) {
                int related, verdict = ip_vs_in_icmp(pskb, &related);
index 8f2d43f..5df55ca 100644 (file)
@@ -1347,7 +1347,7 @@ static int ip_vs_zero_all(void)
 
 static int
 proc_do_defense_mode(ctl_table *table, int write, struct file * filp,
-                    void *buffer, size_t *lenp)
+                    void __user *buffer, size_t *lenp)
 {
        int *valp = table->data;
        int val = *valp;
@@ -1370,7 +1370,7 @@ proc_do_defense_mode(ctl_table *table, int write, struct file * filp,
 
 static int
 proc_do_sync_threshold(ctl_table *table, int write, struct file *filp,
-                      void *buffer, size_t *lenp)
+                      void __user *buffer, size_t *lenp)
 {
        int *valp = table->data;
        int val[2];
index 19bc813..65230e5 100644 (file)
@@ -179,11 +179,10 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
                return 0;
        }
 
-       /* Look for ifname matches; this should unroll nicely. */
-       for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
-               ret |= (((const unsigned long *)indev)[i]
-                       ^ ((const unsigned long *)arpinfo->iniface)[i])
-                       & ((const unsigned long *)arpinfo->iniface_mask)[i];
+       /* Look for ifname matches.  */
+       for (i = 0, ret = 0; i < IFNAMSIZ; i++) {
+               ret |= (indev[i] ^ arpinfo->iniface[i])
+                       & arpinfo->iniface_mask[i];
        }
 
        if (FWINV(ret != 0, ARPT_INV_VIA_IN)) {
@@ -388,12 +387,12 @@ find_inlist_lock(struct list_head *head,
 }
 #endif
 
-static inline struct arpt_table *find_table_lock(const char *name, int *error, struct semaphore *mutex)
+static inline struct arpt_table *arpt_find_table_lock(const char *name, int *error, struct semaphore *mutex)
 {
        return find_inlist_lock(&arpt_tables, name, "arptable_", error, mutex);
 }
 
-static inline struct arpt_target *find_target_lock(const char *name, int *error, struct semaphore *mutex)
+struct arpt_target *arpt_find_target_lock(const char *name, int *error, struct semaphore *mutex)
 {
        return find_inlist_lock(&arpt_target, name, "arpt_", error, mutex);
 }
@@ -543,7 +542,7 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i
        }
 
        t = arpt_get_target(e);
-       target = find_target_lock(t->u.user.name, &ret, &arpt_mutex);
+       target = arpt_find_target_lock(t->u.user.name, &ret, &arpt_mutex);
        if (!target) {
                duprintf("check_entry: `%s' not found\n", t->u.user.name);
                goto out;
@@ -843,7 +842,7 @@ static int get_entries(const struct arpt_get_entries *entries,
        int ret;
        struct arpt_table *t;
 
-       t = find_table_lock(entries->name, &ret, &arpt_mutex);
+       t = arpt_find_table_lock(entries->name, &ret, &arpt_mutex);
        if (t) {
                duprintf("t->private->number = %u\n",
                         t->private->number);
@@ -909,7 +908,7 @@ static int do_replace(void __user *user, unsigned int len)
 
        duprintf("arp_tables: Translated table\n");
 
-       t = find_table_lock(tmp.name, &ret, &arpt_mutex);
+       t = arpt_find_table_lock(tmp.name, &ret, &arpt_mutex);
        if (!t)
                goto free_newinfo_counters_untrans;
 
@@ -1002,7 +1001,7 @@ static int do_add_counters(void __user *user, unsigned int len)
                goto free;
        }
 
-       t = find_table_lock(tmp.name, &ret, &arpt_mutex);
+       t = arpt_find_table_lock(tmp.name, &ret, &arpt_mutex);
        if (!t)
                goto free;
 
@@ -1075,7 +1074,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
                        break;
                }
                name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
-               t = find_table_lock(name, &ret, &arpt_mutex);
+               t = arpt_find_table_lock(name, &ret, &arpt_mutex);
                if (t) {
                        struct arpt_getinfo info;
 
@@ -1323,6 +1322,7 @@ static void __exit fini(void)
 EXPORT_SYMBOL(arpt_register_table);
 EXPORT_SYMBOL(arpt_unregister_table);
 EXPORT_SYMBOL(arpt_do_table);
+EXPORT_SYMBOL(arpt_find_target_lock);
 EXPORT_SYMBOL(arpt_register_target);
 EXPORT_SYMBOL(arpt_unregister_target);
 
index 50a4678..67c2fd2 100644 (file)
@@ -324,8 +324,9 @@ destroy_conntrack(struct nf_conntrack *nfct)
                ip_conntrack_destroyed(ct);
 
        WRITE_LOCK(&ip_conntrack_lock);
-       /* Delete us from our own list to prevent corruption later */
-       list_del(&ct->sibling_list);
+       /* Make sure don't leave any orphaned expectations lying around */
+       if (ct->expecting)
+               remove_expectations(ct, 1);
 
        /* Delete our master expectation */
        if (ct->master) {
@@ -1127,10 +1128,8 @@ int ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
        DUMP_TUPLE(newreply);
 
        conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
-       if (!conntrack->master)
-               conntrack->helper = LIST_FIND(&helpers, helper_cmp,
-                                             struct ip_conntrack_helper *,
-                                             newreply);
+       if (!conntrack->master && list_empty(&conntrack->sibling_list))
+               conntrack->helper = ip_ct_find_helper(newreply);
        WRITE_UNLOCK(&ip_conntrack_lock);
 
        return 1;
index 9bcb718..1cc7965 100644 (file)
@@ -177,6 +177,8 @@ static int tcp_packet(struct ip_conntrack *conntrack,
 
        if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &tcph, sizeof(tcph)) != 0)
                return -1;
+       if (skb->len < skb->nh.iph->ihl * 4 + tcph.doff * 4)
+               return -1;
 
        /* If only reply is a RST, we can consider ourselves not to
           have an established connection: this is a fairly common
index 0b26447..f7146f3 100644 (file)
@@ -69,7 +69,8 @@ fw_in(unsigned int hooknum,
        /* Assume worse case: any hook could change packet */
        (*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED;
        if ((*pskb)->ip_summed == CHECKSUM_HW)
-               (*pskb)->ip_summed = CHECKSUM_NONE;
+               if (skb_checksum_help(pskb, (out == NULL)))
+                       return NF_DROP;
 
        switch (hooknum) {
        case NF_IP_PRE_ROUTING:
index c4fe69b..a84453f 100644 (file)
@@ -85,7 +85,8 @@ ip_nat_fn(unsigned int hooknum,
 
        /* If we had a hardware checksum before, it's now invalid */
        if ((*pskb)->ip_summed == CHECKSUM_HW)
-               (*pskb)->ip_summed = CHECKSUM_NONE;
+               if (skb_checksum_help(pskb, (out == NULL)))
+                       return NF_DROP;
 
        ct = ip_conntrack_get(*pskb, &ctinfo);
        /* Can't track?  It's not due to stress, or conntrack would
index 66316da..2d433b6 100644 (file)
@@ -61,9 +61,6 @@ do {                                                          \
 #endif
 #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
 
-/* Mutex protects lists (only traversed in user context). */
-static DECLARE_MUTEX(ipt_mutex);
-
 /* Must have mutex */
 #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0)
 #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0)
@@ -418,7 +415,7 @@ find_inlist_lock_noload(struct list_head *head,
 {
        void *ret;
 
-#if 0
+#if 0 
        duprintf("find_inlist: searching for `%s' in %s.\n",
                 name, head == &ipt_target ? "ipt_target"
                 : head == &ipt_match ? "ipt_match"
@@ -461,7 +458,7 @@ find_inlist_lock(struct list_head *head,
 #endif
 
 static inline struct ipt_table *
-find_table_lock(const char *name, int *error, struct semaphore *mutex)
+ipt_find_table_lock(const char *name, int *error, struct semaphore *mutex)
 {
        return find_inlist_lock(&ipt_tables, name, "iptable_", error, mutex);
 }
@@ -472,8 +469,8 @@ find_match_lock(const char *name, int *error, struct semaphore *mutex)
        return find_inlist_lock(&ipt_match, name, "ipt_", error, mutex);
 }
 
-static inline struct ipt_target *
-find_target_lock(const char *name, int *error, struct semaphore *mutex)
+struct ipt_target *
+ipt_find_target_lock(const char *name, int *error, struct semaphore *mutex)
 {
        return find_inlist_lock(&ipt_target, name, "ipt_", error, mutex);
 }
@@ -688,7 +685,7 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size,
                goto cleanup_matches;
 
        t = ipt_get_target(e);
-       target = find_target_lock(t->u.user.name, &ret, &ipt_mutex);
+       target = ipt_find_target_lock(t->u.user.name, &ret, &ipt_mutex);
        if (!target) {
                duprintf("check_entry: `%s' not found\n", t->u.user.name);
                goto cleanup_matches;
@@ -1025,7 +1022,7 @@ get_entries(const struct ipt_get_entries *entries,
        int ret;
        struct ipt_table *t;
 
-       t = find_table_lock(entries->name, &ret, &ipt_mutex);
+       t = ipt_find_table_lock(entries->name, &ret, &ipt_mutex);
        if (t) {
                duprintf("t->private->number = %u\n",
                         t->private->number);
@@ -1092,7 +1089,7 @@ do_replace(void __user *user, unsigned int len)
 
        duprintf("ip_tables: Translated table\n");
 
-       t = find_table_lock(tmp.name, &ret, &ipt_mutex);
+       t = ipt_find_table_lock(tmp.name, &ret, &ipt_mutex);
        if (!t)
                goto free_newinfo_counters_untrans;
 
@@ -1195,7 +1192,7 @@ do_add_counters(void __user *user, unsigned int len)
                goto free;
        }
 
-       t = find_table_lock(tmp.name, &ret, &ipt_mutex);
+       t = ipt_find_table_lock(tmp.name, &ret, &ipt_mutex);
        if (!t)
                goto free;
 
@@ -1270,7 +1267,7 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
                        break;
                }
                name[IPT_TABLE_MAXNAMELEN-1] = '\0';
-               t = find_table_lock(name, &ret, &ipt_mutex);
+               t = ipt_find_table_lock(name, &ret, &ipt_mutex);
                if (t) {
                        struct ipt_getinfo info;
 
@@ -1855,6 +1852,7 @@ EXPORT_SYMBOL(ipt_unregister_match);
 EXPORT_SYMBOL(ipt_do_table);
 EXPORT_SYMBOL(ipt_register_target);
 EXPORT_SYMBOL(ipt_unregister_target);
+EXPORT_SYMBOL(ipt_find_target_lock);
 
 module_init(init);
 module_exit(fini);
index 341e845..8ca4025 100644 (file)
@@ -50,7 +50,7 @@ set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
 
 /* Return 0 if there was an error. */
 static inline int
-set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
+set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo, int inward)
 {
        struct tcphdr tcph;
        u_int16_t diffs[2];
@@ -74,11 +74,15 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
                if (!skb_ip_make_writable(pskb,
                                          (*pskb)->nh.iph->ihl*4+sizeof(tcph)))
                        return 0;
-               tcph.check = csum_fold(csum_partial((char *)diffs,
-                                                   sizeof(diffs),
-                                                   tcph.check^0xFFFF));
+               if ((*pskb)->ip_summed != CHECKSUM_HW)
+                       tcph.check = csum_fold(csum_partial((char *)diffs,
+                                              sizeof(diffs),
+                                              tcph.check^0xFFFF));
                memcpy((*pskb)->data + (*pskb)->nh.iph->ihl*4,
                       &tcph, sizeof(tcph));
+               if ((*pskb)->ip_summed == CHECKSUM_HW)
+                       if (skb_checksum_help(pskb, inward))
+                               return 0;
                (*pskb)->nfcache |= NFC_ALTERED;
        }
        return 1;
@@ -100,7 +104,7 @@ target(struct sk_buff **pskb,
 
        if (einfo->operation & (IPT_ECN_OP_SET_ECE | IPT_ECN_OP_SET_CWR)
            && (*pskb)->nh.iph->protocol == IPPROTO_TCP)
-               if (!set_ect_tcp(pskb, einfo))
+               if (!set_ect_tcp(pskb, einfo, (out == NULL)))
                        return NF_DROP;
 
        return IPT_CONTINUE;
index 369f84b..4ef4782 100644 (file)
@@ -186,8 +186,9 @@ ipt_tcpmss_target(struct sk_buff **pskb,
               newmss);
 
  retmodified:
-       /* If we had a hardware checksum before, it's now invalid */
-       (*pskb)->ip_summed = CHECKSUM_NONE;
+       /* We never hw checksum SYN packets.  */
+       BUG_ON((*pskb)->ip_summed == CHECKSUM_HW);
+
        (*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED;
        return IPT_CONTINUE;
 }
index eda86a2..08b786a 100644 (file)
@@ -175,7 +175,7 @@ static int ip_recent_get_info(char *buffer, char **start, off_t offset, int leng
  * clear         -- Flush table, remove all entries
  */
 
-static int ip_recent_ctrl(struct file *file, const char *input, unsigned long size, void *data)
+static int ip_recent_ctrl(struct file *file, const char __user *input, unsigned long size, void *data)
 {
        static const u_int32_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
        u_int32_t val;
index 8bae6ee..b941c00 100644 (file)
@@ -647,7 +647,7 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
 
                default:
 #ifdef CONFIG_IP_MROUTE
-                       return ipmr_ioctl(sk, cmd, arg);
+                       return ipmr_ioctl(sk, cmd, (void __user *)arg);
 #else
                        return -ENOIOCTLCMD;
 #endif
index 6e7cbd3..a570e70 100644 (file)
@@ -138,6 +138,7 @@ static struct timer_list rt_secret_timer;
 
 static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
 static void             ipv4_dst_destroy(struct dst_entry *dst);
+static void             ipv4_dst_ifdown(struct dst_entry *dst, int how);
 static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
 static void             ipv4_link_failure(struct sk_buff *skb);
 static void             ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
@@ -150,6 +151,7 @@ static struct dst_ops ipv4_dst_ops = {
        .gc =                   rt_garbage_collect,
        .check =                ipv4_dst_check,
        .destroy =              ipv4_dst_destroy,
+       .ifdown =               ipv4_dst_ifdown,
        .negative_advice =      ipv4_negative_advice,
        .link_failure =         ipv4_link_failure,
        .update_pmtu =          ip_rt_update_pmtu,
@@ -1336,6 +1338,16 @@ static void ipv4_dst_destroy(struct dst_entry *dst)
        }
 }
 
+static void ipv4_dst_ifdown(struct dst_entry *dst, int how)
+{
+       struct rtable *rt = (struct rtable *) dst;
+       struct in_device *idev = rt->idev;
+       if (idev) {
+               rt->idev = NULL;
+               in_dev_put(idev);
+       }
+}
+
 static void ipv4_link_failure(struct sk_buff *skb)
 {
        struct rtable *rt;
@@ -1347,8 +1359,10 @@ static void ipv4_link_failure(struct sk_buff *skb)
                dst_set_expires(&rt->u.dst, 0);
 }
 
-static int ip_rt_bug(struct sk_buff *skb)
+static int ip_rt_bug(struct sk_buff **pskb)
 {
+       struct sk_buff *skb = *pskb;
+
        printk(KERN_DEBUG "ip_rt_bug: %u.%u.%u.%u -> %u.%u.%u.%u, %s\n",
                NIPQUAD(skb->nh.iph->saddr), NIPQUAD(skb->nh.iph->daddr),
                skb->dev ? skb->dev->name : "?");
index 9ab752f..6cf8487 100644 (file)
@@ -276,7 +276,7 @@ kmem_cache_t *tcp_timewait_cachep;
 
 atomic_t tcp_orphan_count = ATOMIC_INIT(0);
 
-int sysctl_tcp_default_win_scale;
+int sysctl_tcp_default_win_scale = 7;
 
 int sysctl_tcp_mem[3];
 int sysctl_tcp_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 };
@@ -447,7 +447,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
                        mask |= POLLIN | POLLRDNORM;
 
                if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
-                       if (tcp_wspace(sk) >= tcp_min_write_space(sk)) {
+                       if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) {
                                mask |= POLLOUT | POLLWRNORM;
                        } else {  /* send SIGIO later */
                                set_bit(SOCK_ASYNC_NOSPACE,
@@ -458,7 +458,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
                                 * wspace test but before the flags are set,
                                 * IO signal will be lost.
                                 */
-                               if (tcp_wspace(sk) >= tcp_min_write_space(sk))
+                               if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk))
                                        mask |= POLLOUT | POLLWRNORM;
                        }
                }
@@ -469,24 +469,6 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
        return mask;
 }
 
-/*
- *     TCP socket write_space callback.
- */
-void tcp_write_space(struct sock *sk)
-{
-       struct socket *sock = sk->sk_socket;
-
-       if (tcp_wspace(sk) >= tcp_min_write_space(sk) && sock) {
-               clear_bit(SOCK_NOSPACE, &sock->flags);
-
-               if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
-                       wake_up_interruptible(sk->sk_sleep);
-
-               if (sock->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN))
-                       sock_wake_async(sock, 2, POLL_OUT);
-       }
-}
-
 int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
 {
        struct tcp_opt *tp = tcp_sk(sk);
@@ -648,7 +630,7 @@ static void tcp_listen_stop (struct sock *sk)
                local_bh_enable();
                sock_put(child);
 
-               tcp_acceptq_removed(sk);
+               sk_acceptq_removed(sk);
                tcp_openreq_fastfree(req);
        }
        BUG_TRAP(!sk->sk_ack_backlog);
@@ -796,7 +778,7 @@ static inline void skb_entail(struct sock *sk, struct tcp_opt *tp,
        TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK;
        TCP_SKB_CB(skb)->sacked = 0;
        __skb_queue_tail(&sk->sk_write_queue, skb);
-       tcp_charge_skb(sk, skb);
+       sk_charge_skb(sk, skb);
        if (!tp->send_head)
                tp->send_head = skb;
        else if (tp->nonagle&TCP_NAGLE_PUSH)
@@ -1296,18 +1278,6 @@ static int tcp_recv_urg(struct sock *sk, long timeo,
        return -EAGAIN;
 }
 
-/*
- *     Release a skb if it is no longer needed. This routine
- *     must be called with interrupts disabled or with the
- *     socket locked so that the sk_buff queue operation is ok.
- */
-
-static inline void tcp_eat_skb(struct sock *sk, struct sk_buff *skb)
-{
-       __skb_unlink(skb, &sk->sk_receive_queue);
-       __kfree_skb(skb);
-}
-
 /* Clean up the receive buffer for full frames taken by the user,
  * then send an ACK if necessary.  COPIED is the number of bytes
  * tcp_recvmsg has given to the user so far, it speeds up the
@@ -1368,31 +1338,6 @@ void cleanup_rbuf(struct sock *sk, int copied)
                tcp_send_ack(sk);
 }
 
-/* Now socket state including sk->sk_err is changed only under lock,
- * hence we may omit checks after joining wait queue.
- * We check receive queue before schedule() only as optimization;
- * it is very likely that release_sock() added new data.
- */
-
-static long tcp_data_wait(struct sock *sk, long timeo)
-{
-       DEFINE_WAIT(wait);
-
-       prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
-
-       set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
-       release_sock(sk);
-
-       if (skb_queue_empty(&sk->sk_receive_queue))
-               timeo = schedule_timeout(timeo);
-
-       lock_sock(sk);
-       clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
-
-       finish_wait(sk->sk_sleep, &wait);
-       return timeo;
-}
-
 static void tcp_prequeue_process(struct sock *sk)
 {
        struct sk_buff *skb;
@@ -1473,11 +1418,11 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
                                break;
                }
                if (skb->h.th->fin) {
-                       tcp_eat_skb(sk, skb);
+                       sk_eat_skb(sk, skb);
                        ++seq;
                        break;
                }
-               tcp_eat_skb(sk, skb);
+               sk_eat_skb(sk, skb);
                if (!desc->count)
                        break;
        }
@@ -1672,9 +1617,8 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                        /* Do not sleep, just process backlog. */
                        release_sock(sk);
                        lock_sock(sk);
-               } else {
-                       timeo = tcp_data_wait(sk, timeo);
-               }
+               } else
+                       sk_wait_data(sk, &timeo);
 
                if (user_recv) {
                        int chunk;
@@ -1758,14 +1702,14 @@ skip_copy:
                if (skb->h.th->fin)
                        goto found_fin_ok;
                if (!(flags & MSG_PEEK))
-                       tcp_eat_skb(sk, skb);
+                       sk_eat_skb(sk, skb);
                continue;
 
        found_fin_ok:
                /* Process the FIN. */
                ++*seq;
                if (!(flags & MSG_PEEK))
-                       tcp_eat_skb(sk, skb);
+                       sk_eat_skb(sk, skb);
                break;
        } while (len > 0);
 
@@ -2263,7 +2207,7 @@ struct sock *tcp_accept(struct sock *sk, int flags, int *err)
                tp->accept_queue_tail = NULL;
 
        newsk = req->sk;
-       tcp_acceptq_removed(sk);
+       sk_acceptq_removed(sk);
        tcp_openreq_fastfree(req);
        BUG_TRAP(newsk->sk_state != TCP_SYN_RECV);
        release_sock(sk);
@@ -2498,56 +2442,11 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
                break;
        case TCP_INFO: {
                struct tcp_info info;
-               u32 now = tcp_time_stamp;
 
                if (get_user(len, optlen))
                        return -EFAULT;
-               info.tcpi_state = sk->sk_state;
-               info.tcpi_ca_state = tp->ca_state;
-               info.tcpi_retransmits = tp->retransmits;
-               info.tcpi_probes = tp->probes_out;
-               info.tcpi_backoff = tp->backoff;
-               info.tcpi_options = 0;
-               if (tp->tstamp_ok)
-                       info.tcpi_options |= TCPI_OPT_TIMESTAMPS;
-               if (tp->sack_ok)
-                       info.tcpi_options |= TCPI_OPT_SACK;
-               if (tp->wscale_ok) {
-                       info.tcpi_options |= TCPI_OPT_WSCALE;
-                       info.tcpi_snd_wscale = tp->snd_wscale;
-                       info.tcpi_rcv_wscale = tp->rcv_wscale;
-               } else {
-                       info.tcpi_snd_wscale = 0;
-                       info.tcpi_rcv_wscale = 0;
-               }
-               if (tp->ecn_flags & TCP_ECN_OK)
-                       info.tcpi_options |= TCPI_OPT_ECN;
-
-               info.tcpi_rto = (1000000 * tp->rto) / HZ;
-               info.tcpi_ato = (1000000 * tp->ack.ato) / HZ;
-               info.tcpi_snd_mss = tp->mss_cache_std;
-               info.tcpi_rcv_mss = tp->ack.rcv_mss;
-
-               info.tcpi_unacked = tp->packets_out;
-               info.tcpi_sacked = tp->sacked_out;
-               info.tcpi_lost = tp->lost_out;
-               info.tcpi_retrans = tp->retrans_out;
-               info.tcpi_fackets = tp->fackets_out;
-
-               info.tcpi_last_data_sent = ((now - tp->lsndtime) * 1000) / HZ;
-               info.tcpi_last_ack_sent = 0;
-               info.tcpi_last_data_recv = ((now -
-                                            tp->ack.lrcvtime) * 1000) / HZ;
-               info.tcpi_last_ack_recv = ((now - tp->rcv_tstamp) * 1000) / HZ;
-
-               info.tcpi_pmtu = tp->pmtu_cookie;
-               info.tcpi_rcv_ssthresh = tp->rcv_ssthresh;
-               info.tcpi_rtt = ((1000000 * tp->srtt) / HZ) >> 3;
-               info.tcpi_rttvar = ((1000000 * tp->mdev) / HZ) >> 2;
-               info.tcpi_snd_ssthresh = tp->snd_ssthresh;
-               info.tcpi_snd_cwnd = tp->snd_cwnd;
-               info.tcpi_advmss = tp->advmss;
-               info.tcpi_reordering = tp->reordering;
+
+               tcp_get_info(sk, &info);
 
                len = min_t(unsigned int, len, sizeof(info));
                if (put_user(len, optlen))
@@ -2718,5 +2617,4 @@ EXPORT_SYMBOL(tcp_shutdown);
 EXPORT_SYMBOL(tcp_sockets_allocated);
 EXPORT_SYMBOL(tcp_statistics);
 EXPORT_SYMBOL(tcp_timewait_cachep);
-EXPORT_SYMBOL(tcp_write_space);
 EXPORT_SYMBOL_GPL(cleanup_rbuf);
index 305fe2e..5506944 100644 (file)
@@ -41,6 +41,61 @@ static struct sock *tcpnl;
    rta->rta_len = rtalen;                   \
    RTA_DATA(rta); })
 
+/* Return information about state of tcp endpoint in API format. */
+void tcp_get_info(struct sock *sk, struct tcp_info *info)
+{
+       struct tcp_opt *tp = tcp_sk(sk);
+       u32 now = tcp_time_stamp;
+
+       memset(info, 0, sizeof(*info));
+
+       info->tcpi_state = sk->sk_state;
+       info->tcpi_ca_state = tp->ca_state;
+       info->tcpi_retransmits = tp->retransmits;
+       info->tcpi_probes = tp->probes_out;
+       info->tcpi_backoff = tp->backoff;
+
+       if (tp->tstamp_ok)
+               info->tcpi_options |= TCPI_OPT_TIMESTAMPS;
+       if (tp->sack_ok)
+               info->tcpi_options |= TCPI_OPT_SACK;
+       if (tp->wscale_ok) {
+               info->tcpi_options |= TCPI_OPT_WSCALE;
+               info->tcpi_snd_wscale = tp->snd_wscale;
+               info->tcpi_rcv_wscale = tp->rcv_wscale;
+       } 
+
+       if (tp->ecn_flags&TCP_ECN_OK)
+               info->tcpi_options |= TCPI_OPT_ECN;
+
+       info->tcpi_rto = (1000000*tp->rto)/HZ;
+       info->tcpi_ato = (1000000*tp->ack.ato)/HZ;
+       info->tcpi_snd_mss = tp->mss_cache;
+       info->tcpi_rcv_mss = tp->ack.rcv_mss;
+
+       info->tcpi_unacked = tp->packets_out;
+       info->tcpi_sacked = tp->sacked_out;
+       info->tcpi_lost = tp->lost_out;
+       info->tcpi_retrans = tp->retrans_out;
+       info->tcpi_fackets = tp->fackets_out;
+
+       info->tcpi_last_data_sent = ((now - tp->lsndtime)*1000)/HZ;
+       info->tcpi_last_data_recv = ((now - tp->ack.lrcvtime)*1000)/HZ;
+       info->tcpi_last_ack_recv = ((now - tp->rcv_tstamp)*1000)/HZ;
+
+       info->tcpi_pmtu = tp->pmtu_cookie;
+       info->tcpi_rcv_ssthresh = tp->rcv_ssthresh;
+       info->tcpi_rtt = ((1000000*tp->srtt)/HZ)>>3;
+       info->tcpi_rttvar = ((1000000*tp->mdev)/HZ)>>2;
+       info->tcpi_snd_ssthresh = tp->snd_ssthresh;
+       info->tcpi_snd_cwnd = tp->snd_cwnd;
+       info->tcpi_advmss = tp->advmss;
+       info->tcpi_reordering = tp->reordering;
+
+       info->tcpi_rcv_rtt = ((1000000*tp->rcv_rtt_est.rtt)/HZ)>>3;
+       info->tcpi_rcv_space = tp->rcvq_space.space;
+}
+
 static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
                        int ext, u32 pid, u32 seq)
 {
@@ -150,55 +205,8 @@ static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
                minfo->tcpdiag_tmem = atomic_read(&sk->sk_wmem_alloc);
        }
 
-       if (info) {
-               u32 now = tcp_time_stamp;
-
-               info->tcpi_state = sk->sk_state;
-               info->tcpi_ca_state = tp->ca_state;
-               info->tcpi_retransmits = tp->retransmits;
-               info->tcpi_probes = tp->probes_out;
-               info->tcpi_backoff = tp->backoff;
-               info->tcpi_options = 0;
-               if (tp->tstamp_ok)
-                       info->tcpi_options |= TCPI_OPT_TIMESTAMPS;
-               if (tp->sack_ok)
-                       info->tcpi_options |= TCPI_OPT_SACK;
-               if (tp->wscale_ok) {
-                       info->tcpi_options |= TCPI_OPT_WSCALE;
-                       info->tcpi_snd_wscale = tp->snd_wscale;
-                       info->tcpi_rcv_wscale = tp->rcv_wscale;
-               } else {
-                       info->tcpi_snd_wscale = 0;
-                       info->tcpi_rcv_wscale = 0;
-               }
-               if (tp->ecn_flags&TCP_ECN_OK)
-                       info->tcpi_options |= TCPI_OPT_ECN;
-
-               info->tcpi_rto = (1000000*tp->rto)/HZ;
-               info->tcpi_ato = (1000000*tp->ack.ato)/HZ;
-               info->tcpi_snd_mss = tp->mss_cache;
-               info->tcpi_rcv_mss = tp->ack.rcv_mss;
-
-               info->tcpi_unacked = tp->packets_out;
-               info->tcpi_sacked = tp->sacked_out;
-               info->tcpi_lost = tp->lost_out;
-               info->tcpi_retrans = tp->retrans_out;
-               info->tcpi_fackets = tp->fackets_out;
-
-               info->tcpi_last_data_sent = ((now - tp->lsndtime)*1000)/HZ;
-               info->tcpi_last_ack_sent = 0;
-               info->tcpi_last_data_recv = ((now - tp->ack.lrcvtime)*1000)/HZ;
-               info->tcpi_last_ack_recv = ((now - tp->rcv_tstamp)*1000)/HZ;
-
-               info->tcpi_pmtu = tp->pmtu_cookie;
-               info->tcpi_rcv_ssthresh = tp->rcv_ssthresh;
-               info->tcpi_rtt = ((1000000*tp->srtt)/HZ)>>3;
-               info->tcpi_rttvar = ((1000000*tp->mdev)/HZ)>>2;
-               info->tcpi_snd_ssthresh = tp->snd_ssthresh;
-               info->tcpi_snd_cwnd = tp->snd_cwnd;
-               info->tcpi_advmss = tp->advmss;
-               info->tcpi_reordering = tp->reordering;
-       }
+       if (info) 
+               tcp_get_info(sk, info);
 
        if (vinfo) {
                vinfo->tcpv_enabled = tp->vegas.doing_vegas_now;
index 708005f..cd72986 100644 (file)
@@ -90,7 +90,7 @@ int sysctl_tcp_nometrics_save;
 int sysctl_tcp_westwood;
 int sysctl_tcp_vegas_cong_avoid;
 
-int sysctl_tcp_moderate_rcvbuf;
+int sysctl_tcp_moderate_rcvbuf = 1;
 
 /* Default values of the Vegas variables, in fixed-point representation
  * with V_PARAM_SHIFT bits to the right of the binary point.
@@ -99,7 +99,7 @@ int sysctl_tcp_moderate_rcvbuf;
 int sysctl_tcp_vegas_alpha = 1<<V_PARAM_SHIFT;
 int sysctl_tcp_vegas_beta  = 3<<V_PARAM_SHIFT;
 int sysctl_tcp_vegas_gamma = 1<<V_PARAM_SHIFT;
-int sysctl_tcp_bic;
+int sysctl_tcp_bic = 1;
 int sysctl_tcp_bic_fast_convergence = 1;
 int sysctl_tcp_bic_low_window = 14;
 
@@ -463,6 +463,8 @@ void tcp_rcv_space_adjust(struct sock *sk)
                tp->rcvq_space.space = space;
 
                if (sysctl_tcp_moderate_rcvbuf) {
+                       int new_clamp = space;
+
                        /* Receive space grows, normalize in order to
                         * take into account packet headers and sk_buff
                         * structure overhead.
@@ -472,10 +474,16 @@ void tcp_rcv_space_adjust(struct sock *sk)
                                space = 1;
                        rcvmem = (tp->advmss + MAX_TCP_HEADER +
                                  16 + sizeof(struct sk_buff));
+                       while (tcp_win_from_space(rcvmem) < tp->advmss)
+                               rcvmem += 128;
                        space *= rcvmem;
                        space = min(space, sysctl_tcp_rmem[2]);
-                       if (space > sk->sk_rcvbuf)
+                       if (space > sk->sk_rcvbuf) {
                                sk->sk_rcvbuf = space;
+
+                               /* Make the window clamp follow along.  */
+                               tp->window_clamp = new_clamp;
+                       }
                }
        }
        
index 5eeae6d..a487ef2 100644 (file)
@@ -1442,7 +1442,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
         * clogging syn queue with openreqs with exponentially increasing
         * timeout.
         */
-       if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
+       if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
                goto drop;
 
        req = tcp_openreq_alloc();
@@ -1567,7 +1567,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
        struct tcp_opt *newtp;
        struct sock *newsk;
 
-       if (tcp_acceptq_is_full(sk))
+       if (sk_acceptq_is_full(sk))
                goto exit_overflow;
 
        if (!dst && (dst = tcp_v4_route_req(sk, req)) == NULL)
@@ -2081,7 +2081,7 @@ static int tcp_v4_init_sock(struct sock *sk)
 
        sk->sk_state = TCP_CLOSE;
 
-       sk->sk_write_space = tcp_write_space;
+       sk->sk_write_space = sk_stream_write_space;
        sk->sk_use_write_queue = 1;
 
        tp->af_specific = &ipv4_specific;
index 61c77cc..755424a 100644 (file)
@@ -720,7 +720,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
                newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL;
                newsk->sk_callback_lock = RW_LOCK_UNLOCKED;
                skb_queue_head_init(&newsk->sk_error_queue);
-               newsk->sk_write_space = tcp_write_space;
+               newsk->sk_write_space = sk_stream_write_space;
 
                if ((filter = newsk->sk_filter) != NULL)
                        sk_filter_charge(newsk, filter);
index 7cae8de..ac6c552 100644 (file)
@@ -326,7 +326,7 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb)
        /* Advance write_seq and place onto the write_queue. */
        tp->write_seq = TCP_SKB_CB(skb)->end_seq;
        __skb_queue_tail(&sk->sk_write_queue, skb);
-       tcp_charge_skb(sk, skb);
+       sk_charge_skb(sk, skb);
 
        /* Queue it, remembering where we must start sending. */
        if (tp->send_head == NULL)
@@ -439,7 +439,7 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
        buff = tcp_alloc_skb(sk, nsize, GFP_ATOMIC);
        if (buff == NULL)
                return -ENOMEM; /* We'll just try again later. */
-       tcp_charge_skb(sk, buff);
+       sk_charge_skb(sk, buff);
 
        /* Correct the sequence numbers. */
        TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len;
@@ -1169,7 +1169,7 @@ int tcp_send_synack(struct sock *sk)
                        __skb_unlink(skb, &sk->sk_write_queue);
                        __skb_queue_head(&sk->sk_write_queue, nskb);
                        tcp_free_skb(sk, skb);
-                       tcp_charge_skb(sk, nskb);
+                       sk_charge_skb(sk, nskb);
                        skb = nskb;
                }
 
@@ -1329,7 +1329,7 @@ int tcp_connect(struct sock *sk)
        TCP_SKB_CB(buff)->when = tcp_time_stamp;
        tp->retrans_stamp = TCP_SKB_CB(buff)->when;
        __skb_queue_tail(&sk->sk_write_queue, buff);
-       tcp_charge_skb(sk, buff);
+       sk_charge_skb(sk, buff);
        tp->packets_out++;
        tcp_transmit_skb(sk, skb_clone(buff, GFP_KERNEL));
        TCP_INC_STATS(TcpActiveOpens);
@@ -1389,8 +1389,7 @@ void tcp_send_delayed_ack(struct sock *sk)
        }
        tp->ack.pending |= TCP_ACK_SCHED|TCP_ACK_TIMER;
        tp->ack.timeout = timeout;
-       if (!mod_timer(&tp->delack_timer, timeout))
-               sock_hold(sk);
+       sk_reset_timer(sk, &tp->delack_timer, timeout);
 }
 
 /* This routine sends an ack and also updates the window. */
index 58796c6..cab2678 100644 (file)
@@ -68,18 +68,13 @@ void tcp_clear_xmit_timers(struct sock *sk)
        struct tcp_opt *tp = tcp_sk(sk);
 
        tp->pending = 0;
-       if (timer_pending(&tp->retransmit_timer) &&
-           del_timer(&tp->retransmit_timer))
-               __sock_put(sk);
+       sk_stop_timer(sk, &tp->retransmit_timer);
 
        tp->ack.pending = 0;
        tp->ack.blocked = 0;
-       if (timer_pending(&tp->delack_timer) &&
-           del_timer(&tp->delack_timer))
-               __sock_put(sk);
+       sk_stop_timer(sk, &tp->delack_timer);
 
-       if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer))
-               __sock_put(sk);
+       sk_stop_timer(sk, &sk->sk_timer);
 }
 
 static void tcp_write_err(struct sock *sk)
@@ -218,8 +213,7 @@ static void tcp_delack_timer(unsigned long data)
                /* Try again later. */
                tp->ack.blocked = 1;
                NET_INC_STATS_BH(DelayedACKLocked);
-               if (!mod_timer(&tp->delack_timer, jiffies + TCP_DELACK_MIN))
-                       sock_hold(sk);
+               sk_reset_timer(sk, &tp->delack_timer, jiffies + TCP_DELACK_MIN);
                goto out_unlock;
        }
 
@@ -229,8 +223,7 @@ static void tcp_delack_timer(unsigned long data)
                goto out;
 
        if (time_after(tp->ack.timeout, jiffies)) {
-               if (!mod_timer(&tp->delack_timer, tp->ack.timeout))
-                       sock_hold(sk);
+               sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout);
                goto out;
        }
        tp->ack.pending &= ~TCP_ACK_TIMER;
@@ -429,8 +422,7 @@ static void tcp_write_timer(unsigned long data)
        bh_lock_sock(sk);
        if (sock_owned_by_user(sk)) {
                /* Try again later */
-               if (!mod_timer(&tp->retransmit_timer, jiffies + (HZ/20)))
-                       sock_hold(sk);
+               sk_reset_timer(sk, &tp->retransmit_timer, jiffies + (HZ / 20));
                goto out_unlock;
        }
 
@@ -438,8 +430,7 @@ static void tcp_write_timer(unsigned long data)
                goto out;
 
        if (time_after(tp->timeout, jiffies)) {
-               if (!mod_timer(&tp->retransmit_timer, tp->timeout))
-                       sock_hold(sk);
+               sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout);
                goto out;
        }
 
@@ -557,14 +548,12 @@ static void tcp_synack_timer(struct sock *sk)
 
 void tcp_delete_keepalive_timer (struct sock *sk)
 {
-       if (timer_pending(&sk->sk_timer) && del_timer (&sk->sk_timer))
-               __sock_put(sk);
+       sk_stop_timer(sk, &sk->sk_timer);
 }
 
 void tcp_reset_keepalive_timer (struct sock *sk, unsigned long len)
 {
-       if (!mod_timer(&sk->sk_timer, jiffies + len))
-               sock_hold(sk);
+       sk_reset_timer(sk, &sk->sk_timer, jiffies + len);
 }
 
 void tcp_set_keepalive(struct sock *sk, int val)
index 900d7fd..a583751 100644 (file)
@@ -294,7 +294,7 @@ static inline struct sock *udp_v4_mcast_next(struct sock *sk,
                    ipv6_only_sock(s)                                   ||
                    (s->sk_bound_dev_if && s->sk_bound_dev_if != dif))
                        continue;
-               if (!ip_mc_sf_allow(sk, loc_addr, rmt_addr, dif))
+               if (!ip_mc_sf_allow(s, loc_addr, rmt_addr, dif))
                        continue;
                goto found;
        }
index accc0c8..3c9d4aa 100644 (file)
@@ -33,8 +33,9 @@ out:
        return ret;
 }
 
-static int ipip_output(struct sk_buff *skb)
+static int ipip_output(struct sk_buff **pskb)
 {
+       struct sk_buff *skb = *pskb;
        struct dst_entry *dst = skb->dst;
        struct xfrm_state *x = dst->xfrm;
        struct iphdr *iph, *top_iph;
index 81c5d97..185092c 100644 (file)
@@ -144,11 +144,11 @@ static int ipv6_clear_mutable_options(struct sk_buff *skb, u16 *nh_offset, int d
        return nexthdr;
 }
 
-int ah6_output(struct sk_buff *skb)
+int ah6_output(struct sk_buff **pskb)
 {
        int err;
        int hdr_len = sizeof(struct ipv6hdr);
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = (*pskb)->dst;
        struct xfrm_state *x  = dst->xfrm;
        struct ipv6hdr *iph = NULL;
        struct ip_auth_hdr *ah;
@@ -156,54 +156,55 @@ int ah6_output(struct sk_buff *skb)
        u16 nh_offset = 0;
        u8 nexthdr;
 
-       if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
-               err = -EINVAL;
-               goto error_nolock;
+       if ((*pskb)->ip_summed == CHECKSUM_HW) {
+               err = skb_checksum_help(pskb, 0);
+               if (err)
+                       goto error_nolock;
        }
 
        spin_lock_bh(&x->lock);
-       err = xfrm_check_output(x, skb, AF_INET6);
+       err = xfrm_check_output(x, *pskb, AF_INET6);
        if (err)
                goto error;
 
        if (x->props.mode) {
-               iph = skb->nh.ipv6h;
-               skb->nh.ipv6h = (struct ipv6hdr*)skb_push(skb, x->props.header_len);
-               skb->nh.ipv6h->version = 6;
-               skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
-               skb->nh.ipv6h->nexthdr = IPPROTO_AH;
-               ipv6_addr_copy(&skb->nh.ipv6h->saddr,
+               iph = (*pskb)->nh.ipv6h;
+               (*pskb)->nh.ipv6h = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len);
+               (*pskb)->nh.ipv6h->version = 6;
+               (*pskb)->nh.ipv6h->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
+               (*pskb)->nh.ipv6h->nexthdr = IPPROTO_AH;
+               ipv6_addr_copy(&(*pskb)->nh.ipv6h->saddr,
                               (struct in6_addr *) &x->props.saddr);
-               ipv6_addr_copy(&skb->nh.ipv6h->daddr,
+               ipv6_addr_copy(&(*pskb)->nh.ipv6h->daddr,
                               (struct in6_addr *) &x->id.daddr);
-               ah = (struct ip_auth_hdr*)(skb->nh.ipv6h+1);
+               ah = (struct ip_auth_hdr*)((*pskb)->nh.ipv6h+1);
                ah->nexthdr = IPPROTO_IPV6;
        } else {
-               hdr_len = skb->h.raw - skb->nh.raw;
+               hdr_len = (*pskb)->h.raw - (*pskb)->nh.raw;
                iph = kmalloc(hdr_len, GFP_ATOMIC);
                if (!iph) {
                        err = -ENOMEM;
                        goto error;
                }
-               memcpy(iph, skb->data, hdr_len);
-               skb->nh.ipv6h = (struct ipv6hdr*)skb_push(skb, x->props.header_len);
-               memcpy(skb->nh.ipv6h, iph, hdr_len);
-               nexthdr = ipv6_clear_mutable_options(skb, &nh_offset, XFRM_POLICY_OUT);
+               memcpy(iph, (*pskb)->data, hdr_len);
+               (*pskb)->nh.ipv6h = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len);
+               memcpy((*pskb)->nh.ipv6h, iph, hdr_len);
+               nexthdr = ipv6_clear_mutable_options(*pskb, &nh_offset, XFRM_POLICY_OUT);
                if (nexthdr == 0)
                        goto error_free_iph;
 
-               skb->nh.raw[nh_offset] = IPPROTO_AH;
-               skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
-               ah = (struct ip_auth_hdr*)(skb->nh.raw+hdr_len);
-               skb->h.raw = (unsigned char*) ah;
+               (*pskb)->nh.raw[nh_offset] = IPPROTO_AH;
+               (*pskb)->nh.ipv6h->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
+               ah = (struct ip_auth_hdr*)((*pskb)->nh.raw+hdr_len);
+               (*pskb)->h.raw = (unsigned char*) ah;
                ah->nexthdr = nexthdr;
        }
 
-       skb->nh.ipv6h->priority    = 0;
-       skb->nh.ipv6h->flow_lbl[0] = 0;
-       skb->nh.ipv6h->flow_lbl[1] = 0;
-       skb->nh.ipv6h->flow_lbl[2] = 0;
-       skb->nh.ipv6h->hop_limit    = 0;
+       (*pskb)->nh.ipv6h->priority    = 0;
+       (*pskb)->nh.ipv6h->flow_lbl[0] = 0;
+       (*pskb)->nh.ipv6h->flow_lbl[1] = 0;
+       (*pskb)->nh.ipv6h->flow_lbl[2] = 0;
+       (*pskb)->nh.ipv6h->hop_limit    = 0;
 
        ahp = x->data;
        ah->hdrlen  = (XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + 
@@ -212,29 +213,29 @@ int ah6_output(struct sk_buff *skb)
        ah->reserved = 0;
        ah->spi = x->id.spi;
        ah->seq_no = htonl(++x->replay.oseq);
-       ahp->icv(ahp, skb, ah->auth_data);
+       ahp->icv(ahp, *pskb, ah->auth_data);
 
        if (x->props.mode) {
-               skb->nh.ipv6h->hop_limit   = iph->hop_limit;
-               skb->nh.ipv6h->priority    = iph->priority;     
-               skb->nh.ipv6h->flow_lbl[0] = iph->flow_lbl[0];
-               skb->nh.ipv6h->flow_lbl[1] = iph->flow_lbl[1];
-               skb->nh.ipv6h->flow_lbl[2] = iph->flow_lbl[2];
+               (*pskb)->nh.ipv6h->hop_limit   = iph->hop_limit;
+               (*pskb)->nh.ipv6h->priority    = iph->priority;         
+               (*pskb)->nh.ipv6h->flow_lbl[0] = iph->flow_lbl[0];
+               (*pskb)->nh.ipv6h->flow_lbl[1] = iph->flow_lbl[1];
+               (*pskb)->nh.ipv6h->flow_lbl[2] = iph->flow_lbl[2];
                if (x->props.flags & XFRM_STATE_NOECN)
-                       IP6_ECN_clear(skb->nh.ipv6h);
+                       IP6_ECN_clear((*pskb)->nh.ipv6h);
        } else {
-               memcpy(skb->nh.ipv6h, iph, hdr_len);
-               skb->nh.raw[nh_offset] = IPPROTO_AH;
-               skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
+               memcpy((*pskb)->nh.ipv6h, iph, hdr_len);
+               (*pskb)->nh.raw[nh_offset] = IPPROTO_AH;
+               (*pskb)->nh.ipv6h->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
                kfree (iph);
        }
 
-       skb->nh.raw = skb->data;
+       (*pskb)->nh.raw = (*pskb)->data;
 
-       x->curlft.bytes += skb->len;
+       x->curlft.bytes += (*pskb)->len;
        x->curlft.packets++;
        spin_unlock_bh(&x->lock);
-       if ((skb->dst = dst_pop(dst)) == NULL) {
+       if (((*pskb)->dst = dst_pop(dst)) == NULL) {
                err = -EHOSTUNREACH;
                goto error_nolock;
        }
@@ -244,7 +245,7 @@ error_free_iph:
 error:
        spin_unlock_bh(&x->lock);
 error_nolock:
-       kfree_skb(skb);
+       kfree_skb(*pskb);
        return err;
 }
 
@@ -362,7 +363,7 @@ void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset);
        struct xfrm_state *x;
 
-       if (type != ICMPV6_DEST_UNREACH ||
+       if (type != ICMPV6_DEST_UNREACH &&
            type != ICMPV6_PKT_TOOBIG)
                return;
 
index fef31fb..8bd7899 100644 (file)
@@ -145,10 +145,8 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
                          (struct in6_addr *)(skb->nh.raw + serr->addr_offset));
                        if (np->sndflow)
                                sin->sin6_flowinfo = *(u32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK;
-                       if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
-                               struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
-                               sin->sin6_scope_id = opt->iif;
-                       }
+                       if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+                               sin->sin6_scope_id = IP6CB(skb)->iif;
                } else {
                        ipv6_addr_set(&sin->sin6_addr, 0, 0,
                                      htonl(0xffff),
@@ -167,10 +165,8 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
                        ipv6_addr_copy(&sin->sin6_addr, &skb->nh.ipv6h->saddr);
                        if (np->rxopt.all)
                                datagram_recv_ctl(sk, msg, skb);
-                       if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
-                               struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
-                               sin->sin6_scope_id = opt->iif;
-                       }
+                       if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+                               sin->sin6_scope_id = IP6CB(skb)->iif;
                } else {
                        struct inet_opt *inet = inet_sk(sk);
 
@@ -211,7 +207,7 @@ out:
 int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
-       struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
+       struct inet6_skb_parm *opt = IP6CB(skb);
 
        if (np->rxopt.bits.rxinfo) {
                struct in6_pktinfo src_info;
index dc8bfac..8156942 100644 (file)
 
 #define MAX_SG_ONSTACK 4
 
-int esp6_output(struct sk_buff *skb)
+int esp6_output(struct sk_buff **pskb)
 {
        int err;
        int hdr_len = 0;
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = (*pskb)->dst;
        struct xfrm_state *x  = dst->xfrm;
        struct ipv6hdr *iph = NULL, *top_iph;
        struct ipv6_esp_hdr *esph;
@@ -58,14 +58,14 @@ int esp6_output(struct sk_buff *skb)
        u8 *prevhdr;
        u8 nexthdr = 0;
 
-       /* First, if the skb is not checksummed, complete checksum. */
-       if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
-               err = -EINVAL;
-               goto error_nolock;
+       if ((*pskb)->ip_summed == CHECKSUM_HW) {
+               err = skb_checksum_help(pskb, 0);
+               if (err)
+                       goto error_nolock;
        }
 
        spin_lock_bh(&x->lock);
-       err = xfrm_check_output(x, skb, AF_INET6);
+       err = xfrm_check_output(x, *pskb, AF_INET6);
        if (err)
                goto error;
        err = -ENOMEM;
@@ -73,7 +73,7 @@ int esp6_output(struct sk_buff *skb)
        /* Strip IP header in transport mode. Save it. */
 
        if (!x->props.mode) {
-               hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
+               hdr_len = ip6_find_1stfragopt(*pskb, &prevhdr);
                nexthdr = *prevhdr;
                *prevhdr = IPPROTO_ESP;
                iph = kmalloc(hdr_len, GFP_ATOMIC);
@@ -81,14 +81,14 @@ int esp6_output(struct sk_buff *skb)
                        err = -ENOMEM;
                        goto error;
                }
-               memcpy(iph, skb->nh.raw, hdr_len);
-               __skb_pull(skb, hdr_len);
+               memcpy(iph, (*pskb)->nh.raw, hdr_len);
+               __skb_pull(*pskb, hdr_len);
        }
 
        /* Now skb is pure payload to encrypt */
 
        /* Round to block size */
-       clen = skb->len;
+       clen = (*pskb)->len;
 
        esp = x->data;
        alen = esp->auth.icv_trunc_len;
@@ -98,7 +98,7 @@ int esp6_output(struct sk_buff *skb)
        if (esp->conf.padlen)
                clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1);
 
-       if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0) {
+       if ((nfrags = skb_cow_data(*pskb, clen-(*pskb)->len+alen, &trailer)) < 0) {
                if (!x->props.mode && iph) kfree(iph);
                goto error;
        }
@@ -106,15 +106,15 @@ int esp6_output(struct sk_buff *skb)
        /* Fill padding... */
        do {
                int i;
-               for (i=0; i<clen-skb->len - 2; i++)
+               for (i=0; i<clen-(*pskb)->len - 2; i++)
                        *(u8*)(trailer->tail + i) = i+1;
        } while (0);
-       *(u8*)(trailer->tail + clen-skb->len - 2) = (clen - skb->len)-2;
-       pskb_put(skb, trailer, clen - skb->len);
+       *(u8*)(trailer->tail + clen-(*pskb)->len - 2) = (clen - (*pskb)->len)-2;
+       pskb_put(*pskb, trailer, clen - (*pskb)->len);
 
        if (x->props.mode) {
-               iph = skb->nh.ipv6h;
-               top_iph = (struct ipv6hdr*)skb_push(skb, x->props.header_len);
+               iph = (*pskb)->nh.ipv6h;
+               top_iph = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len);
                esph = (struct ipv6_esp_hdr*)(top_iph+1);
                *(u8*)(trailer->tail - 1) = IPPROTO_IPV6;
                top_iph->version = 6;
@@ -125,19 +125,19 @@ int esp6_output(struct sk_buff *skb)
                if (x->props.flags & XFRM_STATE_NOECN)
                        IP6_ECN_clear(top_iph);
                top_iph->nexthdr = IPPROTO_ESP;
-               top_iph->payload_len = htons(skb->len + alen - sizeof(struct ipv6hdr));
+               top_iph->payload_len = htons((*pskb)->len + alen - sizeof(struct ipv6hdr));
                top_iph->hop_limit = iph->hop_limit;
                ipv6_addr_copy(&top_iph->saddr,
                               (struct in6_addr *)&x->props.saddr);
                ipv6_addr_copy(&top_iph->daddr,
                               (struct in6_addr *)&x->id.daddr);
        } else { 
-               esph = (struct ipv6_esp_hdr*)skb_push(skb, x->props.header_len);
-               skb->h.raw = (unsigned char*)esph;
-               top_iph = (struct ipv6hdr*)skb_push(skb, hdr_len);
+               esph = (struct ipv6_esp_hdr*)skb_push(*pskb, x->props.header_len);
+               (*pskb)->h.raw = (unsigned char*)esph;
+               top_iph = (struct ipv6hdr*)skb_push(*pskb, hdr_len);
                memcpy(top_iph, iph, hdr_len);
                kfree(iph);
-               top_iph->payload_len = htons(skb->len + alen - sizeof(struct ipv6hdr));
+               top_iph->payload_len = htons((*pskb)->len + alen - sizeof(struct ipv6hdr));
                *(u8*)(trailer->tail - 1) = nexthdr;
        }
 
@@ -156,7 +156,7 @@ int esp6_output(struct sk_buff *skb)
                        if (!sg)
                                goto error;
                }
-               skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
+               skb_to_sgvec(*pskb, sg, esph->enc_data+esp->conf.ivlen-(*pskb)->data, clen);
                crypto_cipher_encrypt(tfm, sg, sg, clen);
                if (unlikely(sg != sgbuf))
                        kfree(sg);
@@ -168,17 +168,17 @@ int esp6_output(struct sk_buff *skb)
        }
 
        if (esp->auth.icv_full_len) {
-               esp->auth.icv(esp, skb, (u8*)esph-skb->data,
+               esp->auth.icv(esp, *pskb, (u8*)esph-(*pskb)->data,
                        sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen+clen, trailer->tail);
-               pskb_put(skb, trailer, alen);
+               pskb_put(*pskb, trailer, alen);
        }
 
-       skb->nh.raw = skb->data;
+       (*pskb)->nh.raw = (*pskb)->data;
 
-       x->curlft.bytes += skb->len;
+       x->curlft.bytes += (*pskb)->len;
        x->curlft.packets++;
        spin_unlock_bh(&x->lock);
-       if ((skb->dst = dst_pop(dst)) == NULL) {
+       if (((*pskb)->dst = dst_pop(dst)) == NULL) {
                err = -EHOSTUNREACH;
                goto error_nolock;
        }
@@ -187,7 +187,7 @@ int esp6_output(struct sk_buff *skb)
 error:
        spin_unlock_bh(&x->lock);
 error_nolock:
-       kfree_skb(skb);
+       kfree_skb(*pskb);
        return err;
 }
 
@@ -324,7 +324,7 @@ void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        struct ipv6_esp_hdr *esph = (struct ipv6_esp_hdr*)(skb->data+offset);
        struct xfrm_state *x;
 
-       if (type != ICMPV6_DEST_UNREACH ||
+       if (type != ICMPV6_DEST_UNREACH && 
            type != ICMPV6_PKT_TOOBIG)
                return;
 
index a5fd7d6..ff12dcf 100644 (file)
@@ -155,7 +155,7 @@ static struct tlvtype_proc tlvprocdestopt_lst[] = {
 static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
 {
        struct sk_buff *skb = *skbp;
-       struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
+       struct inet6_skb_parm *opt = IP6CB(skb);
 
        if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
            !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
@@ -217,7 +217,7 @@ void __init ipv6_nodata_init(void)
 static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
 {
        struct sk_buff *skb = *skbp;
-       struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
+       struct inet6_skb_parm *opt = IP6CB(skb);
        struct in6_addr *addr;
        struct in6_addr daddr;
        int n, i;
@@ -288,7 +288,7 @@ looped_back:
                        return -1;
                }
                *skbp = skb = skb2;
-               opt = (struct inet6_skb_parm *)skb2->cb;
+               opt = IP6CB(skb2);
                hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
        }
 
@@ -418,7 +418,7 @@ ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
 static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
 {
        if (skb->nh.raw[optoff+1] == 2) {
-               ((struct inet6_skb_parm*)skb->cb)->ra = optoff;
+               IP6CB(skb)->ra = optoff;
                return 1;
        }
        LIMIT_NETDEBUG(
@@ -482,7 +482,7 @@ static struct tlvtype_proc tlvprochopopt_lst[] = {
 
 int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff)
 {
-       ((struct inet6_skb_parm*)skb->cb)->hop = sizeof(struct ipv6hdr);
+       IP6CB(skb)->hop = sizeof(struct ipv6hdr);
        if (ip6_parse_tlv(tlvprochopopt_lst, skb))
                return sizeof(struct ipv6hdr);
        return -1;
index 61695f3..0be5945 100644 (file)
@@ -74,7 +74,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
        /* Store incoming device index. When the packet will
           be queued, we cannot refer to skb->dev anymore.
         */
-       ((struct inet6_skb_parm *)skb->cb)->iif = dev->ifindex;
+       IP6CB(skb)->iif = dev->ifindex;
 
        if (skb->len < sizeof(struct ipv6hdr))
                goto err;
index 4f48168..777b15f 100644 (file)
@@ -55,7 +55,7 @@
 #include <net/icmp.h>
 #include <net/xfrm.h>
 
-static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*));
+static int ip6_fragment(struct sk_buff **pskb, int (*output)(struct sk_buff**));
 
 static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *fhdr)
 {
@@ -107,8 +107,9 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
 }
 
 
-int ip6_output2(struct sk_buff *skb)
+static int ip6_output2(struct sk_buff **pskb)
 {
+       struct sk_buff *skb = *pskb;
        struct dst_entry *dst = skb->dst;
        struct net_device *dev = dst->dev;
 
@@ -121,7 +122,7 @@ int ip6_output2(struct sk_buff *skb)
                if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) &&
                    ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr,
                                &skb->nh.ipv6h->saddr)) {
-                       struct sk_buff *newskb = skb_copy(skb, GFP_ATOMIC);
+                       struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
 
                        /* Do not check for IFF_ALLMULTI; multicast routing
                           is not supported in any case.
@@ -144,12 +145,14 @@ int ip6_output2(struct sk_buff *skb)
        return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish);
 }
 
-int ip6_output(struct sk_buff *skb)
+int ip6_output(struct sk_buff **pskb)
 {
+       struct sk_buff *skb = *pskb;
+
        if ((skb->len > dst_pmtu(skb->dst) || skb_shinfo(skb)->frag_list))
-               return ip6_fragment(skb, ip6_output2);
+               return ip6_fragment(pskb, ip6_output2);
        else
-               return ip6_output2(skb);
+               return ip6_output2(pskb);
 }
 
 #ifdef CONFIG_NETFILTER
@@ -346,7 +349,7 @@ int ip6_forward(struct sk_buff *skb)
 {
        struct dst_entry *dst = skb->dst;
        struct ipv6hdr *hdr = skb->nh.ipv6h;
-       struct inet6_skb_parm *opt =(struct inet6_skb_parm*)skb->cb;
+       struct inet6_skb_parm *opt = IP6CB(skb);
        
        if (ipv6_devconf.forwarding == 0)
                goto error;
@@ -513,11 +516,11 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
        return offset;
 }
 
-static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
+static int ip6_fragment(struct sk_buff **pskb, int (*output)(struct sk_buff**))
 {
        struct net_device *dev;
+       struct sk_buff *frag, *skb = *pskb;
        struct rt6_info *rt = (struct rt6_info*)skb->dst;
-       struct sk_buff *frag;
        struct ipv6hdr *tmp_hdr;
        struct frag_hdr *fh;
        unsigned int mtu, hlen, left, len;
@@ -604,8 +607,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
                                frag->nh.ipv6h->payload_len = htons(frag->len - sizeof(struct ipv6hdr));
                                ip6_copy_metadata(frag, skb);
                        }
-                       err = output(skb);
-
+                       
+                       err = output(&skb);
                        if (err || !frag)
                                break;
 
@@ -721,7 +724,7 @@ slow_path:
 
                IP6_INC_STATS(FragCreates);
 
-               err = output(frag);
+               err = output(&frag);
                if (err)
                        goto fail;
        }
index 97db913..b357db4 100644 (file)
@@ -118,10 +118,10 @@ error_out:
        return err;
 }
 
-static int ipcomp6_output(struct sk_buff *skb)
+static int ipcomp6_output(struct sk_buff **pskb)
 {
        int err;
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = (*pskb)->dst;
        struct xfrm_state *x = dst->xfrm;
        struct ipv6hdr *tmp_iph = NULL, *iph, *top_iph;
        int hdr_len = 0;
@@ -132,54 +132,55 @@ static int ipcomp6_output(struct sk_buff *skb)
        int plen, dlen;
        u8 *start, *scratch = ipcd->scratch;
 
-       if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
-               err = -EINVAL;
-               goto error_nolock;
+       if ((*pskb)->ip_summed == CHECKSUM_HW) {
+               err = skb_checksum_help(pskb, 0);
+               if (err)
+                       goto error_nolock;
        }
 
        spin_lock_bh(&x->lock);
 
-       err = xfrm_check_output(x, skb, AF_INET6);
+       err = xfrm_check_output(x, *pskb, AF_INET6);
        if (err)
                goto error;
 
        if (x->props.mode) {
                hdr_len = sizeof(struct ipv6hdr);
                nexthdr = IPPROTO_IPV6;
-               iph = skb->nh.ipv6h;
-               top_iph = (struct ipv6hdr *)skb_push(skb, sizeof(struct ipv6hdr));
+               iph = (*pskb)->nh.ipv6h;
+               top_iph = (struct ipv6hdr *)skb_push(*pskb, sizeof(struct ipv6hdr));
                top_iph->version = 6;
                top_iph->priority = iph->priority;
                top_iph->flow_lbl[0] = iph->flow_lbl[0];
                top_iph->flow_lbl[1] = iph->flow_lbl[1];
                top_iph->flow_lbl[2] = iph->flow_lbl[2];
                top_iph->nexthdr = IPPROTO_IPV6; /* initial */
-               top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
+               top_iph->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
                top_iph->hop_limit = iph->hop_limit;
                memcpy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr, sizeof(struct in6_addr));
                memcpy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr, sizeof(struct in6_addr));
-               skb->nh.raw = skb->data; /* == top_iph */
-               skb->h.raw = skb->nh.raw + hdr_len;
+               (*pskb)->nh.raw = (*pskb)->data; /* == top_iph */
+               (*pskb)->h.raw = (*pskb)->nh.raw + hdr_len;
        } else {
-               hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
+               hdr_len = ip6_find_1stfragopt(*pskb, &prevhdr);
                nexthdr = *prevhdr;
        }
 
        /* check whether datagram len is larger than threshold */
-       if ((skb->len - hdr_len) < ipcd->threshold) {
+       if (((*pskb)->len - hdr_len) < ipcd->threshold) {
                goto out_ok;
        }
 
-       if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
-               skb_linearize(skb, GFP_ATOMIC) != 0) {
+       if ((skb_is_nonlinear(*pskb) || skb_cloned(*pskb)) &&
+               skb_linearize(*pskb, GFP_ATOMIC) != 0) {
                err = -ENOMEM;
                goto error;
        }
 
        /* compression */
-       plen = skb->len - hdr_len;
+       plen = (*pskb)->len - hdr_len;
        dlen = IPCOMP_SCRATCH_SIZE;
-       start = skb->data + hdr_len;
+       start = (*pskb)->data + hdr_len;
 
        err = crypto_comp_compress(ipcd->tfm, start, plen, scratch, &dlen);
        if (err) {
@@ -189,7 +190,7 @@ static int ipcomp6_output(struct sk_buff *skb)
                goto out_ok;
        }
        memcpy(start, scratch, dlen);
-       pskb_trim(skb, hdr_len+dlen);
+       pskb_trim(*pskb, hdr_len+dlen);
 
        /* insert ipcomp header and replace datagram */
        tmp_iph = kmalloc(hdr_len, GFP_ATOMIC);
@@ -197,16 +198,16 @@ static int ipcomp6_output(struct sk_buff *skb)
                err = -ENOMEM;
                goto error;
        }
-       memcpy(tmp_iph, skb->nh.raw, hdr_len);
-       top_iph = (struct ipv6hdr*)skb_push(skb, sizeof(struct ipv6_comp_hdr));
+       memcpy(tmp_iph, (*pskb)->nh.raw, hdr_len);
+       top_iph = (struct ipv6hdr*)skb_push(*pskb, sizeof(struct ipv6_comp_hdr));
        memcpy(top_iph, tmp_iph, hdr_len);
        kfree(tmp_iph);
 
        if (x->props.mode && (x->props.flags & XFRM_STATE_NOECN))
                IP6_ECN_clear(top_iph);
-       top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
-       skb->nh.raw = skb->data; /* top_iph */
-       ip6_find_1stfragopt(skb, &prevhdr); 
+       top_iph->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
+       (*pskb)->nh.raw = (*pskb)->data; /* top_iph */
+       ip6_find_1stfragopt(*pskb, &prevhdr); 
        *prevhdr = IPPROTO_COMP;
 
        ipch = (struct ipv6_comp_hdr *)((unsigned char *)top_iph + hdr_len);
@@ -214,13 +215,13 @@ static int ipcomp6_output(struct sk_buff *skb)
        ipch->flags = 0;
        ipch->cpi = htons((u16 )ntohl(x->id.spi));
 
-       skb->h.raw = (unsigned char*)ipch;
+       (*pskb)->h.raw = (unsigned char*)ipch;
 out_ok:
-       x->curlft.bytes += skb->len;
+       x->curlft.bytes += (*pskb)->len;
        x->curlft.packets++;
        spin_unlock_bh(&x->lock);
 
-       if ((skb->dst = dst_pop(dst)) == NULL) {
+       if (((*pskb)->dst = dst_pop(dst)) == NULL) {
                err = -EHOSTUNREACH;
                goto error_nolock;
        }
@@ -231,7 +232,7 @@ out_exit:
 error:
        spin_unlock_bh(&x->lock);
 error_nolock:
-       kfree_skb(skb);
+       kfree_skb(*pskb);
        goto out_exit;
 }
 
index b351145..1f2896b 100644 (file)
@@ -365,7 +365,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
        err = -EADDRNOTAVAIL;
 
        for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
-               if (pmc->ifindex != pgsr->gsr_interface)
+               if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface)
                        continue;
                if (ipv6_addr_cmp(&pmc->addr, group) == 0)
                        break;
index aa6b74d..245dac7 100644 (file)
@@ -395,7 +395,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
 
        ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
 
-       dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
+       dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
        if (!dst)
                return;
 
@@ -486,7 +486,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
 
        ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
 
-       dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
+       dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
        if (!dst)
                return;
 
@@ -562,7 +562,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
 
        ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
 
-       dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output2);
+       dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
        if (!dst)
                return;
 
index c84fd8e..2232128 100644 (file)
@@ -66,8 +66,6 @@ do {                                                          \
 #endif
 #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
 
-/* Mutex protects lists (only traversed in user context). */
-static DECLARE_MUTEX(ip6t_mutex);
 
 /* Must have mutex */
 #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0)
@@ -544,7 +542,7 @@ find_inlist_lock(struct list_head *head,
 #endif
 
 static inline struct ip6t_table *
-find_table_lock(const char *name, int *error, struct semaphore *mutex)
+ip6t_find_table_lock(const char *name, int *error, struct semaphore *mutex)
 {
        return find_inlist_lock(&ip6t_tables, name, "ip6table_", error, mutex);
 }
@@ -555,8 +553,8 @@ find_match_lock(const char *name, int *error, struct semaphore *mutex)
        return find_inlist_lock(&ip6t_match, name, "ip6t_", error, mutex);
 }
 
-static inline struct ip6t_target *
-find_target_lock(const char *name, int *error, struct semaphore *mutex)
+struct ip6t_target *
+ip6t_find_target_lock(const char *name, int *error, struct semaphore *mutex)
 {
        return find_inlist_lock(&ip6t_target, name, "ip6t_", error, mutex);
 }
@@ -771,7 +769,7 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
                goto cleanup_matches;
 
        t = ip6t_get_target(e);
-       target = find_target_lock(t->u.user.name, &ret, &ip6t_mutex);
+       target = ip6t_find_target_lock(t->u.user.name, &ret, &ip6t_mutex);
        if (!target) {
                duprintf("check_entry: `%s' not found\n", t->u.user.name);
                goto cleanup_matches;
@@ -1028,7 +1026,7 @@ get_counters(const struct ip6t_table_info *t,
 static int
 copy_entries_to_user(unsigned int total_size,
                     struct ip6t_table *table,
-                    void *userptr)
+                    void __user *userptr)
 {
        unsigned int off, num, countersize;
        struct ip6t_entry *e;
@@ -1111,7 +1109,7 @@ get_entries(const struct ip6t_get_entries *entries,
        int ret;
        struct ip6t_table *t;
 
-       t = find_table_lock(entries->name, &ret, &ip6t_mutex);
+       t = ip6t_find_table_lock(entries->name, &ret, &ip6t_mutex);
        if (t) {
                duprintf("t->private->number = %u\n",
                         t->private->number);
@@ -1174,7 +1172,7 @@ do_replace(void __user *user, unsigned int len)
 
        duprintf("ip_tables: Translated table\n");
 
-       t = find_table_lock(tmp.name, &ret, &ip6t_mutex);
+       t = ip6t_find_table_lock(tmp.name, &ret, &ip6t_mutex);
        if (!t)
                goto free_newinfo_counters_untrans;
 
@@ -1276,7 +1274,7 @@ do_add_counters(void __user *user, unsigned int len)
                goto free;
        }
 
-       t = find_table_lock(tmp.name, &ret, &ip6t_mutex);
+       t = ip6t_find_table_lock(tmp.name, &ret, &ip6t_mutex);
        if (!t)
                goto free;
 
@@ -1351,7 +1349,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
                        break;
                }
                name[IP6T_TABLE_MAXNAMELEN-1] = '\0';
-               t = find_table_lock(name, &ret, &ip6t_mutex);
+               t = ip6t_find_table_lock(name, &ret, &ip6t_mutex);
                if (t) {
                        struct ip6t_getinfo info;
 
@@ -1964,6 +1962,7 @@ static void __exit fini(void)
 EXPORT_SYMBOL(ip6t_register_table);
 EXPORT_SYMBOL(ip6t_unregister_table);
 EXPORT_SYMBOL(ip6t_do_table);
+EXPORT_SYMBOL(ip6t_find_target_lock);
 EXPORT_SYMBOL(ip6t_register_match);
 EXPORT_SYMBOL(ip6t_unregister_match);
 EXPORT_SYMBOL(ip6t_register_target);
index 3d2961c..0e1b275 100644 (file)
@@ -409,10 +409,8 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
                ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
                sin6->sin6_flowinfo = 0;
                sin6->sin6_scope_id = 0;
-               if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
-                       struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
-                       sin6->sin6_scope_id = opt->iif;
-               }
+               if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+                       sin6->sin6_scope_id = IP6CB(skb)->iif;
        }
 
        sock_recv_timestamp(msg, sk, skb);
index 18057ed..541f243 100644 (file)
@@ -84,9 +84,11 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort);
 static struct dst_entry        *ip6_dst_check(struct dst_entry *dst, u32 cookie);
 static struct dst_entry *ip6_negative_advice(struct dst_entry *);
 static void            ip6_dst_destroy(struct dst_entry *);
+static void            ip6_dst_ifdown(struct dst_entry *, int how);
 static int              ip6_dst_gc(void);
 
 static int             ip6_pkt_discard(struct sk_buff *skb);
+static int             ip6_pkt_discard_out(struct sk_buff **pskb);
 static void            ip6_link_failure(struct sk_buff *skb);
 static void            ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
 
@@ -97,6 +99,7 @@ static struct dst_ops ip6_dst_ops = {
        .gc_thresh              =       1024,
        .check                  =       ip6_dst_check,
        .destroy                =       ip6_dst_destroy,
+       .ifdown                 =       ip6_dst_ifdown,
        .negative_advice        =       ip6_negative_advice,
        .link_failure           =       ip6_link_failure,
        .update_pmtu            =       ip6_rt_update_pmtu,
@@ -113,7 +116,7 @@ struct rt6_info ip6_null_entry = {
                        .error          = -ENETUNREACH,
                        .metrics        = { [RTAX_HOPLIMIT - 1] = 255, },
                        .input          = ip6_pkt_discard,
-                       .output         = ip6_pkt_discard,
+                       .output         = ip6_pkt_discard_out,
                        .ops            = &ip6_dst_ops,
                        .path           = (struct dst_entry*)&ip6_null_entry,
                }
@@ -142,9 +145,17 @@ static __inline__ struct rt6_info *ip6_dst_alloc(void)
 static void ip6_dst_destroy(struct dst_entry *dst)
 {
        struct rt6_info *rt = (struct rt6_info *)dst;
-       if (rt->rt6i_idev != NULL)
-               in6_dev_put(rt->rt6i_idev);
-       
+       struct inet6_dev *idev = rt->rt6i_idev;
+
+       if (idev != NULL) {
+               rt->rt6i_idev = NULL;
+               in6_dev_put(idev);
+       }       
+}
+
+static void ip6_dst_ifdown(struct dst_entry *dst, int how)
+{
+       ip6_dst_destroy(dst);
 }
 
 /*
@@ -572,11 +583,13 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
 
 /* Protected by rt6_lock.  */
 static struct dst_entry *ndisc_dst_gc_list;
+static int ipv6_get_mtu(struct net_device *dev);
+static inline unsigned int ipv6_advmss(unsigned int mtu);
 
 struct dst_entry *ndisc_dst_alloc(struct net_device *dev, 
                                  struct neighbour *neigh,
                                  struct in6_addr *addr,
-                                 int (*output)(struct sk_buff *))
+                                 int (*output)(struct sk_buff **))
 {
        struct rt6_info *rt = ip6_dst_alloc();
 
@@ -597,6 +610,8 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
        rt->rt6i_metric   = 0;
        atomic_set(&rt->u.dst.__refcnt, 1);
        rt->u.dst.metrics[RTAX_HOPLIMIT-1] = 255;
+       rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
+       rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&rt->u.dst));
        rt->u.dst.output  = output;
 
        write_lock_bh(&rt6_lock);
@@ -778,7 +793,7 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
                        dev_put(dev);
                dev = &loopback_dev;
                dev_hold(dev);
-               rt->u.dst.output = ip6_pkt_discard;
+               rt->u.dst.output = ip6_pkt_discard_out;
                rt->u.dst.input = ip6_pkt_discard;
                rt->u.dst.error = -ENETUNREACH;
                rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP;
@@ -1278,6 +1293,11 @@ int ip6_pkt_discard(struct sk_buff *skb)
        return 0;
 }
 
+int ip6_pkt_discard_out(struct sk_buff **pskb)
+{
+       return ip6_pkt_discard(*pskb);
+}
+
 /*
  *     Add address
  */
index 332c897..7492301 100644 (file)
@@ -536,8 +536,7 @@ static int tcp_v6_hash_connect(struct sock *sk)
 
 static __inline__ int tcp_v6_iif(struct sk_buff *skb)
 {
-       struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
-       return opt->iif;
+       return IP6CB(skb)->iif;
 }
 
 static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 
@@ -879,7 +878,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
                    np->rxopt.bits.srcrt == 2 &&
                    req->af.v6_req.pktopts) {
                        struct sk_buff *pktopts = req->af.v6_req.pktopts;
-                       struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)pktopts->cb;
+                       struct inet6_skb_parm *rxopt = IP6CB(pktopts);
                        if (rxopt->srcrt)
                                opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt));
                }
@@ -932,7 +931,7 @@ static struct or_calltable or_ipv6 = {
 static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
-       struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
+       struct inet6_skb_parm *opt = IP6CB(skb);
 
        if (np->rxopt.all) {
                if ((opt->hop && np->rxopt.bits.hopopts) ||
@@ -1183,7 +1182,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
                goto drop;              
        }
 
-       if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
+       if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
                goto drop;
 
        req = tcp_openreq_alloc();
@@ -1300,12 +1299,12 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 
        opt = np->opt;
 
-       if (tcp_acceptq_is_full(sk))
+       if (sk_acceptq_is_full(sk))
                goto out_overflow;
 
        if (np->rxopt.bits.srcrt == 2 &&
            opt == NULL && req->af.v6_req.pktopts) {
-               struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)req->af.v6_req.pktopts->cb;
+               struct inet6_skb_parm *rxopt = IP6CB(req->af.v6_req.pktopts);
                if (rxopt->srcrt)
                        opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(req->af.v6_req.pktopts->nh.raw+rxopt->srcrt));
        }
@@ -1879,7 +1878,7 @@ static int tcp_v6_init_sock(struct sock *sk)
 
        tp->af_specific = &ipv6_specific;
 
-       sk->sk_write_space = tcp_write_space;
+       sk->sk_write_space = sk_stream_write_space;
        sk->sk_use_write_queue = 1;
 
        sk->sk_sndbuf = sysctl_tcp_wmem[1];
index 63ef593..e251408 100644 (file)
@@ -432,10 +432,8 @@ try_again:
 
                        if (np->rxopt.all)
                                datagram_recv_ctl(sk, msg, skb);
-                       if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
-                               struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
-                               sin6->sin6_scope_id = opt->iif;
-                       }
+                       if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+                               sin6->sin6_scope_id = IP6CB(skb)->iif;
                }
        }
        err = copied;
@@ -509,7 +507,7 @@ static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
                return -1;
        }
 
-       if (sk->sk_filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
+       if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
                if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
                        UDP6_INC_STATS_BH(UdpInErrors);
                        kfree_skb(skb);
@@ -574,34 +572,26 @@ static void udpv6_mcast_deliver(struct udphdr *uh,
                                struct sk_buff *skb)
 {
        struct sock *sk, *sk2;
-       struct sk_buff *buff;
        int dif;
 
        read_lock(&udp_hash_lock);
        sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
        dif = skb->dev->ifindex;
        sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
-       if (!sk)
-               goto free_skb;
+       if (!sk) {
+               kfree_skb(skb);
+               goto out;
+       }
 
-       buff = NULL;
        sk2 = sk;
        while ((sk2 = udp_v6_mcast_next(sk_next(sk2), uh->dest, daddr,
                                        uh->source, saddr, dif))) {
-               if (!buff) {
-                       buff = skb_clone(skb, GFP_ATOMIC);
-                       if (!buff)
-                               continue;
-               }
-               if (udpv6_queue_rcv_skb(sk2, buff) >= 0)
-                       buff = NULL;
-       }
-       if (buff)
-               kfree_skb(buff);
-       if (udpv6_queue_rcv_skb(sk, skb) < 0) {
-free_skb:
-               kfree_skb(skb);
+               struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
+               if (buff)
+                       udpv6_queue_rcv_skb(sk2, buff);
        }
+       udpv6_queue_rcv_skb(sk, skb);
+out:
        read_unlock(&udp_hash_lock);
 }
 
index 1c3e4f5..163223d 100644 (file)
@@ -90,7 +90,7 @@ extern int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
                               struct iovec *iov, int len, int noblock);
 extern int ipxrtr_route_skb(struct sk_buff *skb);
 extern struct ipx_route *ipxrtr_lookup(__u32 net);
-extern int ipxrtr_ioctl(unsigned int cmd, void *arg);
+extern int ipxrtr_ioctl(unsigned int cmd, void __user *arg);
 
 #undef IPX_REFCNT_DEBUG
 #ifdef IPX_REFCNT_DEBUG
@@ -114,7 +114,7 @@ static void ipxcfg_set_auto_select(char val)
                ipx_primary_net = ipx_interfaces_head();
 }
 
-static int ipxcfg_get_config_data(struct ipx_config_data *arg)
+static int ipxcfg_get_config_data(struct ipx_config_data __user *arg)
 {
        struct ipx_config_data vals;
 
@@ -1141,7 +1141,7 @@ out:
        return intrfc;
 }
 
-static int ipxitf_ioctl(unsigned int cmd, void *arg)
+static int ipxitf_ioctl(unsigned int cmd, void __user *arg)
 {
        int rc = -EINVAL;
        struct ifreq ifr;
@@ -1204,14 +1204,14 @@ static int ipxitf_ioctl(unsigned int cmd, void *arg)
        }
        case SIOCAIPXITFCRT: 
                rc = -EFAULT;
-               if (get_user(val, (unsigned char *) arg))
+               if (get_user(val, (unsigned char __user *) arg))
                        break;
                rc = 0;
                ipxcfg_auto_create_interfaces = val;
                break;
        case SIOCAIPXPRISLT: 
                rc = -EFAULT;
-               if (get_user(val, (unsigned char *) arg))
+               if (get_user(val, (unsigned char __user *) arg))
                        break;
                rc = 0;
                ipxcfg_set_auto_select(val);
@@ -1695,7 +1695,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock,
        /* Socket gets bound below anyway */
 /*     if (sk->sk_zapped)
                return -EIO; */ /* Socket not bound */
-       if (flags & ~MSG_DONTWAIT)
+       if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
                goto out;
 
        /* Max possible packet size limited by 16 bit pktsize in header */
@@ -1823,13 +1823,14 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        int rc = 0;
        long amount = 0;
        struct sock *sk = sock->sk;
+       void __user *argp = (void __user *)arg;
 
        switch (cmd) {
        case TIOCOUTQ:
                amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
                if (amount < 0)
                        amount = 0;
-               rc = put_user(amount, (int *)arg);
+               rc = put_user(amount, (int __user *)argp);
                break;
        case TIOCINQ: {
                struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
@@ -1837,14 +1838,14 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                 * user tasks fiddle here */
                if (skb)
                        amount = skb->len - sizeof(struct ipxhdr);
-               rc = put_user(amount, (int *)arg);
+               rc = put_user(amount, (int __user *)argp);
                break;
        }
        case SIOCADDRT:
        case SIOCDELRT:
                rc = -EPERM;
                if (capable(CAP_NET_ADMIN))
-                       rc = ipxrtr_ioctl(cmd, (void *)arg);
+                       rc = ipxrtr_ioctl(cmd, argp);
                break;
        case SIOCSIFADDR:
        case SIOCAIPXITFCRT:
@@ -1853,10 +1854,10 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                if (!capable(CAP_NET_ADMIN))
                        break;
        case SIOCGIFADDR:
-               rc = ipxitf_ioctl(cmd, (void *)arg);
+               rc = ipxitf_ioctl(cmd, argp);
                break;
        case SIOCIPXCFGDATA:
-               rc = ipxcfg_get_config_data((void *)arg);
+               rc = ipxcfg_get_config_data(argp);
                break;
        case SIOCIPXNCPCONN:
                /*
@@ -1867,12 +1868,12 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                if (!capable(CAP_NET_ADMIN))
                        break;
                rc = get_user(ipx_sk(sk)->ipx_ncp_conn,
-                             (const unsigned short *)(arg));
+                             (const unsigned short __user *)argp);
                break;
        case SIOCGSTAMP:
                rc = -EINVAL;
                if (sk) 
-                       rc = sock_get_timestamp(sk, (struct timeval __user *)arg);
+                       rc = sock_get_timestamp(sk, argp);
                break;
        case SIOCGIFDSTADDR:
        case SIOCSIFDSTADDR:
@@ -1883,7 +1884,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                rc = -EINVAL;
                break;
        default:
-               rc = dev_ioctl(cmd,(void __user *) arg);
+               rc = dev_ioctl(cmd, argp);
                break;
        }
 
index 6350510..57faf8c 100644 (file)
@@ -256,7 +256,7 @@ out:
 /*
  * We use a normal struct rtentry for route handling
  */
-int ipxrtr_ioctl(unsigned int cmd, void *arg)
+int ipxrtr_ioctl(unsigned int cmd, void __user *arg)
 {
        struct rtentry rt;      /* Use these to behave like 'other' stacks */
        struct sockaddr_ipx *sg, *st;
index 6d6c65a..c90c505 100644 (file)
@@ -1269,7 +1269,7 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
        IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);
 
        /* Note : socket.c set MSG_EOR on SEQPACKET sockets */
-       if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR))
+       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
                return -EINVAL;
 
        if (sk->sk_shutdown & SEND_SHUTDOWN) {
@@ -1521,7 +1521,7 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
 
        IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);
 
-       if (msg->msg_flags & ~MSG_DONTWAIT)
+       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
                return -EINVAL;
 
        if (sk->sk_shutdown & SEND_SHUTDOWN) {
@@ -1593,7 +1593,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
 
        IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);
 
-       if (msg->msg_flags & ~MSG_DONTWAIT)
+       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
                return -EINVAL;
 
        if (sk->sk_shutdown & SEND_SHUTDOWN) {
@@ -1779,7 +1779,7 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
                if (amount < 0)
                        amount = 0;
-               if (put_user(amount, (unsigned int *)arg))
+               if (put_user(amount, (unsigned int __user *)arg))
                        return -EFAULT;
                return 0;
        }
@@ -1790,7 +1790,7 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                /* These two are safe on a single CPU system as only user tasks fiddle here */
                if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
                        amount = skb->len;
-               if (put_user(amount, (unsigned int *)arg))
+               if (put_user(amount, (unsigned int __user *)arg))
                        return -EFAULT;
                return 0;
        }
index cf57786..4096515 100644 (file)
@@ -260,7 +260,7 @@ int ircomm_tty_tiocmset(struct tty_struct *tty, struct file *file,
  *
  */
 static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self,
-                                     struct serial_struct *retinfo)
+                                     struct serial_struct __user *retinfo)
 {
        struct serial_struct info;
    
@@ -297,7 +297,7 @@ static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self,
  *
  */
 static int ircomm_tty_set_serial_info(struct ircomm_tty_cb *self,
-                                     struct serial_struct *new_info)
+                                     struct serial_struct __user *new_info)
 {
 #if 0
        struct serial_struct new_serial;
@@ -388,10 +388,10 @@ int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file,
 
        switch (cmd) {
        case TIOCGSERIAL:
-               ret = ircomm_tty_get_serial_info(self, (struct serial_struct *) arg);
+               ret = ircomm_tty_get_serial_info(self, (struct serial_struct __user *) arg);
                break;
        case TIOCSSERIAL:
-               ret = ircomm_tty_set_serial_info(self, (struct serial_struct *) arg);
+               ret = ircomm_tty_set_serial_info(self, (struct serial_struct __user *) arg);
                break;
        case TIOCMIWAIT:
                IRDA_DEBUG(0, "(), TIOCMIWAIT, not impl!\n");
@@ -403,7 +403,7 @@ int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file,
                save_flags(flags); cli();
                cnow = driver->icount;
                restore_flags(flags);
-               p_cuser = (struct serial_icounter_struct *) arg;
+               p_cuser = (struct serial_icounter_struct __user *) arg;
                if (put_user(cnow.cts, &p_cuser->cts) ||
                    put_user(cnow.dsr, &p_cuser->dsr) ||
                    put_user(cnow.rng, &p_cuser->rng) ||
index 8e7493f..80a6648 100644 (file)
@@ -536,7 +536,7 @@ int irda_device_set_mode(struct net_device* dev, int mode)
  *    Setup the DMA channel. Commonly used by ISA FIR drivers
  *
  */
-void irda_setup_dma(int channel, char *buffer, int count, int mode)
+void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode)
 {
        unsigned long flags;
 
@@ -545,7 +545,7 @@ void irda_setup_dma(int channel, char *buffer, int count, int mode)
        disable_dma(channel);
        clear_dma_ff(channel);
        set_dma_mode(channel, mode);
-       set_dma_addr(channel, isa_virt_to_bus(buffer));
+       set_dma_addr(channel, buffer);
        set_dma_count(channel, count);
        enable_dma(channel);
 
index 0a9b1ca..d16ce9b 100644 (file)
@@ -804,7 +804,7 @@ void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason,
  * Note : separate from irlmp_do_discovery() so that we can handle
  * passive discovery properly.
  */
-void irlmp_do_expiry()
+void irlmp_do_expiry(void)
 {
        struct lap_cb *lap;
 
@@ -1078,7 +1078,7 @@ void irlmp_discovery_expiry(discinfo_t *expiries, int number)
  *    Used by IrLAP to get the discovery info it needs when answering
  *    discovery requests by other devices.
  */
-discovery_t *irlmp_get_discovery_response()
+discovery_t *irlmp_get_discovery_response(void)
 {
        IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
index 98afb0a..b81d56c 100644 (file)
@@ -35,7 +35,7 @@
  */
 static inline ssize_t
 irnet_ctrl_write(irnet_socket *        ap,
-                const char *   buf,
+                const char __user *buf,
                 size_t         count)
 {
   char         command[IRNET_MAX_COMMAND];
@@ -254,7 +254,7 @@ irnet_read_discovery_log(irnet_socket *     ap,
 static inline ssize_t
 irnet_ctrl_read(irnet_socket * ap,
                struct file *   file,
-               char *          buf,
+               char __user *   buf,
                size_t          count)
 {
   DECLARE_WAITQUEUE(wait, current);
@@ -529,7 +529,7 @@ dev_irnet_close(struct inode *      inode,
  */
 static ssize_t
 dev_irnet_write(struct file *  file,
-               const char *    buf,
+               const char __user *buf,
                size_t          count,
                loff_t *        ppos)
 {
@@ -553,7 +553,7 @@ dev_irnet_write(struct file *       file,
  */
 static ssize_t
 dev_irnet_read(struct file *   file,
-              char *           buf,
+              char __user *    buf,
               size_t           count,
               loff_t *         ppos)
 {
@@ -610,6 +610,7 @@ dev_irnet_ioctl(struct inode *      inode,
   irnet_socket *       ap = (struct irnet_socket *) file->private_data;
   int                  err;
   int                  val;
+  void __user *argp = (void __user *)arg;
 
   DENTER(FS_TRACE, "(file=0x%p, ap=0x%p, cmd=0x%X)\n",
         file, ap, cmd);
@@ -626,7 +627,7 @@ dev_irnet_ioctl(struct inode *      inode,
     {
       /* Set discipline (should be N_SYNC_PPP or N_TTY) */
     case TIOCSETD:
-      if(get_user(val, (int *) arg))
+      if(get_user(val, (int __user *)argp))
        break;
       if((val == N_SYNC_PPP) || (val == N_PPP))
        {
@@ -665,7 +666,7 @@ dev_irnet_ioctl(struct inode *      inode,
     case PPPIOCGCHAN:
       if(!ap->ppp_open)
        break;
-      if(put_user(ppp_channel_index(&ap->chan), (int *) arg))
+      if(put_user(ppp_channel_index(&ap->chan), (int __user *)argp))
        break;
       DEBUG(FS_INFO, "Query channel.\n");
       err = 0;
@@ -673,7 +674,7 @@ dev_irnet_ioctl(struct inode *      inode,
     case PPPIOCGUNIT:
       if(!ap->ppp_open)
        break;
-      if(put_user(ppp_unit_number(&ap->chan), (int *) arg))
+      if(put_user(ppp_unit_number(&ap->chan), (int __user *)argp))
        break;
       DEBUG(FS_INFO, "Query unit number.\n");
       err = 0;
@@ -703,14 +704,14 @@ dev_irnet_ioctl(struct inode *    inode,
       /* Get termios */
     case TCGETS:
       DEBUG(FS_INFO, "Get termios.\n");
-      if(kernel_termios_to_user_termios((struct termios *)arg, &ap->termios))
+      if(kernel_termios_to_user_termios((struct termios __user *)argp, &ap->termios))
        break;
       err = 0;
       break;
       /* Set termios */
     case TCSETSF:
       DEBUG(FS_INFO, "Set termios.\n");
-      if(user_termios_to_kernel_termios(&ap->termios, (struct termios *) arg))
+      if(user_termios_to_kernel_termios(&ap->termios, (struct termios __user *)argp))
        break;
       err = 0;
       break;
@@ -743,7 +744,7 @@ dev_irnet_ioctl(struct inode *      inode,
     case FIONREAD:
       DEBUG(FS_INFO, "FIONREAD\n");
       val = 0;
-      if(put_user(val, (int *) arg))
+      if(put_user(val, (int __user *)argp))
        break;
       err = 0;
       break;
@@ -950,6 +951,7 @@ ppp_irnet_ioctl(struct ppp_channel *        chan,
   int                  err;
   int                  val;
   u32                  accm[8];
+  void __user *argp = (void __user *)arg;
 
   DENTER(PPP_TRACE, "(channel=0x%p, ap=0x%p, cmd=0x%X)\n",
         chan, ap, cmd);
@@ -963,12 +965,12 @@ ppp_irnet_ioctl(struct ppp_channel *      chan,
       /* PPP flags */
     case PPPIOCGFLAGS:
       val = ap->flags | ap->rbits;
-      if(put_user(val, (int *) arg))
+      if(put_user(val, (int __user *) argp))
        break;
       err = 0;
       break;
     case PPPIOCSFLAGS:
-      if(get_user(val, (int *) arg))
+      if(get_user(val, (int __user *) argp))
        break;
       ap->flags = val & ~SC_RCV_BITS;
       ap->rbits = val & SC_RCV_BITS;
@@ -977,32 +979,32 @@ ppp_irnet_ioctl(struct ppp_channel *      chan,
 
       /* Async map stuff - all dummy to please pppd */
     case PPPIOCGASYNCMAP:
-      if(put_user(ap->xaccm[0], (u32 *) arg))
+      if(put_user(ap->xaccm[0], (u32 __user *) argp))
        break;
       err = 0;
       break;
     case PPPIOCSASYNCMAP:
-      if(get_user(ap->xaccm[0], (u32 *) arg))
+      if(get_user(ap->xaccm[0], (u32 __user *) argp))
        break;
       err = 0;
       break;
     case PPPIOCGRASYNCMAP:
-      if(put_user(ap->raccm, (u32 *) arg))
+      if(put_user(ap->raccm, (u32 __user *) argp))
        break;
       err = 0;
       break;
     case PPPIOCSRASYNCMAP:
-      if(get_user(ap->raccm, (u32 *) arg))
+      if(get_user(ap->raccm, (u32 __user *) argp))
        break;
       err = 0;
       break;
     case PPPIOCGXASYNCMAP:
-      if(copy_to_user((void *) arg, ap->xaccm, sizeof(ap->xaccm)))
+      if(copy_to_user(argp, ap->xaccm, sizeof(ap->xaccm)))
        break;
       err = 0;
       break;
     case PPPIOCSXASYNCMAP:
-      if(copy_from_user(accm, (void *) arg, sizeof(accm)))
+      if(copy_from_user(accm, argp, sizeof(accm)))
        break;
       accm[2] &= ~0x40000000U;         /* can't escape 0x5e */
       accm[3] |= 0x60000000U;          /* must escape 0x7d, 0x7e */
@@ -1012,12 +1014,12 @@ ppp_irnet_ioctl(struct ppp_channel *    chan,
 
       /* Max PPP frame size */
     case PPPIOCGMRU:
-      if(put_user(ap->mru, (int *) arg))
+      if(put_user(ap->mru, (int __user *) argp))
        break;
       err = 0;
       break;
     case PPPIOCSMRU:
-      if(get_user(val, (int *) arg))
+      if(get_user(val, (int __user *) argp))
        break;
       if(val < PPP_MRU)
        val = PPP_MRU;
@@ -1097,7 +1099,7 @@ void __exit
 irnet_cleanup(void)
 {
   irda_irnet_cleanup();
-  return ppp_irnet_cleanup();
+  ppp_irnet_cleanup();
 }
 
 /*------------------------------------------------------------------*/
index 0c84c82..8b4e06c 100644 (file)
@@ -66,11 +66,11 @@ static int
                        struct file *);
 static ssize_t
        dev_irnet_write(struct file *,
-                       const char *,
+                       const char __user *,
                        size_t,
                        loff_t *),
        dev_irnet_read(struct file *,
-                      char *,
+                      char __user *,
                       size_t,
                       loff_t *);
 static unsigned int
index ae25dc3..995f4e1 100644 (file)
@@ -78,7 +78,7 @@ static int min_lap_keepalive_time = 100;      /* 100us */
  * us on that - Jean II */
 
 static int do_devname(ctl_table *table, int write, struct file *filp,
-                     void *buffer, size_t *lenp)
+                     void __user *buffer, size_t *lenp)
 {
        int ret;
 
index 419f673..645b425 100644 (file)
@@ -2726,7 +2726,7 @@ static int pfkey_recvmsg(struct kiocb *kiocb,
        int copied, err;
 
        err = -EINVAL;
-       if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
+       if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
                goto out;
 
        msg->msg_namelen = 0;
index 4c90113..04fb045 100644 (file)
@@ -728,14 +728,14 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
           to corresponding kernel module.   --ANK (980802)
         */
 
-       err = security_netlink_send(skb);
-       if (err) {
+       err = -EFAULT;
+       if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
                kfree_skb(skb);
                goto out;
        }
 
-       err = -EFAULT;
-       if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
+       err = security_netlink_send(sk, skb);
+       if (err) {
                kfree_skb(skb);
                goto out;
        }
index bf5d86a..72059f1 100644 (file)
@@ -54,7 +54,7 @@ static unsigned int netlink_poll(struct file *file, poll_table * wait)
  *     Write a message to the kernel side of a communication link
  */
  
-static ssize_t netlink_write(struct file * file, const char * buf,
+static ssize_t netlink_write(struct file * file, const char __user * buf,
                             size_t count, loff_t *pos)
 {
        struct inode *inode = file->f_dentry->d_inode;
@@ -62,7 +62,7 @@ static ssize_t netlink_write(struct file * file, const char * buf,
        struct msghdr msg;
        struct iovec iov;
 
-       iov.iov_base = (void*)buf;
+       iov.iov_base = (void __user*)buf;
        iov.iov_len = count;
        msg.msg_name=NULL;
        msg.msg_namelen=0;
@@ -78,7 +78,7 @@ static ssize_t netlink_write(struct file * file, const char * buf,
  *     Read a message from the kernel side of the communication link
  */
 
-static ssize_t netlink_read(struct file * file, char * buf,
+static ssize_t netlink_read(struct file * file, char __user * buf,
                            size_t count, loff_t *pos)
 {
        struct inode *inode = file->f_dentry->d_inode;
index 1e3fe72..fbb97bf 100644 (file)
@@ -1021,7 +1021,7 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
        unsigned char *asmptr;
        int size;
 
-       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR))
+       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
                return -EINVAL;
 
        lock_sock(sk);
@@ -1176,6 +1176,7 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
 static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
+       void __user *argp = (void __user *)arg;
        int ret;
 
        lock_sock(sk);
@@ -1186,7 +1187,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                if (amount < 0)
                        amount = 0;
                release_sock(sk);
-               return put_user(amount, (int *)arg);
+               return put_user(amount, (int __user *)argp);
        }
 
        case TIOCINQ: {
@@ -1196,13 +1197,13 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
                        amount = skb->len;
                release_sock(sk);
-               return put_user(amount, (int *)arg);
+               return put_user(amount, (int __user *)argp);
        }
 
        case SIOCGSTAMP:
                ret = -EINVAL;
                if (sk != NULL)
-                       ret = sock_get_timestamp(sk, (struct timeval __user *)arg);
+                       ret = sock_get_timestamp(sk, argp);
                release_sock(sk);
                return ret;
 
@@ -1224,11 +1225,11 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        case SIOCNRDECOBS:
                release_sock(sk);
                if (!capable(CAP_NET_ADMIN)) return -EPERM;
-               return nr_rt_ioctl(cmd, (void *)arg);
+               return nr_rt_ioctl(cmd, argp);
 
        default:
                release_sock(sk);
-               return dev_ioctl(cmd, (void __user *)arg);
+               return dev_ioctl(cmd, argp);
        }
        release_sock(sk);
 
index 0505c00..dac2e36 100644 (file)
@@ -647,7 +647,7 @@ static ax25_digi *nr_call_to_digi(int ndigis, ax25_address *digipeaters)
 /*
  *     Handle the ioctls that control the routing functions.
  */
-int nr_rt_ioctl(unsigned int cmd, void *arg)
+int nr_rt_ioctl(unsigned int cmd, void __user *arg)
 {
        struct nr_route_struct nr_route;
        struct net_device *dev;
index 91e57eb..93ac3b3 100644 (file)
@@ -1037,7 +1037,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
        int copied, err;
 
        err = -EINVAL;
-       if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
+       if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
                goto out;
 
 #if 0
index 315e4a9..a5555c3 100644 (file)
@@ -1021,7 +1021,7 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock,
        unsigned char *asmptr;
        int n, size, qbit = 0;
 
-       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR))
+       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
                return -EINVAL;
 
        if (sk->sk_zapped)
@@ -1249,6 +1249,7 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
        rose_cb *rose = rose_sk(sk);
+       void __user *argp = (void __user *)arg;
 
        switch (cmd) {
        case TIOCOUTQ: {
@@ -1256,7 +1257,7 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
                if (amount < 0)
                        amount = 0;
-               return put_user(amount, (unsigned int *)arg);
+               return put_user(amount, (unsigned int __user *)argp);
        }
 
        case TIOCINQ: {
@@ -1265,12 +1266,12 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                /* These two are safe on a single CPU system as only user tasks fiddle here */
                if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
                        amount = skb->len;
-               return put_user(amount, (unsigned int *)arg);
+               return put_user(amount, (unsigned int __user *)argp);
        }
 
        case SIOCGSTAMP:
                if (sk != NULL) 
-                       return sock_get_timestamp(sk, (struct timeval __user *)arg);
+                       return sock_get_timestamp(sk, (struct timeval __user *)argp);
                return -EINVAL;
 
        case SIOCGIFADDR:
@@ -1290,18 +1291,18 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        case SIOCRSCLRRT:
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
-               return rose_rt_ioctl(cmd, (void *)arg);
+               return rose_rt_ioctl(cmd, argp);
 
        case SIOCRSGCAUSE: {
                struct rose_cause_struct rose_cause;
                rose_cause.cause      = rose->cause;
                rose_cause.diagnostic = rose->diagnostic;
-               return copy_to_user((void *)arg, &rose_cause, sizeof(struct rose_cause_struct)) ? -EFAULT : 0;
+               return copy_to_user(argp, &rose_cause, sizeof(struct rose_cause_struct)) ? -EFAULT : 0;
        }
 
        case SIOCRSSCAUSE: {
                struct rose_cause_struct rose_cause;
-               if (copy_from_user(&rose_cause, (void *)arg, sizeof(struct rose_cause_struct)))
+               if (copy_from_user(&rose_cause, argp, sizeof(struct rose_cause_struct)))
                        return -EFAULT;
                rose->cause      = rose_cause.cause;
                rose->diagnostic = rose_cause.diagnostic;
@@ -1312,14 +1313,14 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                if (!capable(CAP_NET_ADMIN)) return -EPERM;
                if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
                        ax25_listen_release(&rose_callsign, NULL);
-               if (copy_from_user(&rose_callsign, (void *)arg, sizeof(ax25_address)))
+               if (copy_from_user(&rose_callsign, argp, sizeof(ax25_address)))
                        return -EFAULT;
                if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
                        ax25_listen_register(&rose_callsign, NULL);
                return 0;
 
        case SIOCRSGL2CALL:
-               return copy_to_user((void *)arg, &rose_callsign, sizeof(ax25_address)) ? -EFAULT : 0;
+               return copy_to_user(argp, &rose_callsign, sizeof(ax25_address)) ? -EFAULT : 0;
 
        case SIOCRSACCEPT:
                if (rose->state == ROSE_STATE_5) {
@@ -1335,7 +1336,7 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                return 0;
 
        default:
-               return dev_ioctl(cmd, (void __user *)arg);
+               return dev_ioctl(cmd, argp);
        }
 
        return 0;
index 47664dc..0cd8810 100644 (file)
@@ -710,7 +710,7 @@ out:
 /*
  *     Handle the ioctls that control the routing functions.
  */
-int rose_rt_ioctl(unsigned int cmd, void *arg)
+int rose_rt_ioctl(unsigned int cmd, void __user *arg)
 {
        struct rose_route_struct rose_route;
        struct net_device *dev;
index 04d05a2..16089ce 100644 (file)
@@ -1054,7 +1054,7 @@ cbq_dequeue(struct Qdisc *sch)
 
        if (sch->q.qlen) {
                sch->stats.overlimits++;
-               if (q->wd_expires && !netif_queue_stopped(sch->dev)) {
+               if (q->wd_expires) {
                        long delay = PSCHED_US2JIFFIE(q->wd_expires);
                        if (delay <= 0)
                                delay = 1;
index c1a4210..a97d7be 100644 (file)
@@ -40,6 +40,7 @@
 struct dly_sched_data {
        u32     latency;
        u32     limit;
+       u32     loss;
        struct timer_list timer;
        struct Qdisc *qdisc;
 };
@@ -58,6 +59,12 @@ static int dly_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        struct dly_skb_cb *cb = (struct dly_skb_cb *)skb->cb;
        int ret;
 
+       /* Random packet drop 0 => none, ~0 => all */
+       if (q->loss >= net_random()) {
+               sch->stats.drops++;
+               return 0;       /* lie about loss so TCP doesn't know */
+       }
+
        PSCHED_GET_TIME(cb->queuetime);
 
        /* Queue to underlying scheduler */
@@ -69,7 +76,7 @@ static int dly_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                sch->stats.bytes += skb->len;
                sch->stats.packets++;
        }
-       return 0;
+       return ret;
 }
 
 /* Requeue packets but don't change time stamp */
@@ -104,12 +111,14 @@ static unsigned int dly_drop(struct Qdisc *sch)
 static struct sk_buff *dly_dequeue(struct Qdisc *sch)
 {
        struct dly_sched_data *q = (struct dly_sched_data *)sch->data;
-       struct sk_buff *skb = q->qdisc->dequeue(q->qdisc);
+       struct sk_buff *skb;
 
+ retry:
+       skb = q->qdisc->dequeue(q->qdisc);
        if (skb) {
                struct dly_skb_cb *cb = (struct dly_skb_cb *)skb->cb;
                psched_time_t now;
-               long diff;
+               long diff, delay;
 
                PSCHED_GET_TIME(now);
                diff = q->latency - PSCHED_TDIFF(now, cb->queuetime);
@@ -120,17 +129,17 @@ static struct sk_buff *dly_dequeue(struct Qdisc *sch)
                        return skb;
                }
 
-               if (!netif_queue_stopped(sch->dev)) {
-                       long delay = PSCHED_US2JIFFIE(diff);
-                       if (delay <= 0)
-                               delay = 1;
-                       mod_timer(&q->timer, jiffies+delay);
-               }
-
                if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
                        sch->q.qlen--;
                        sch->stats.drops++;
+                       goto retry;
                }
+
+               delay = PSCHED_US2JIFFIE(diff);
+               if (delay <= 0)
+                 delay = 1;
+               mod_timer(&q->timer, jiffies+delay);
+
                sch->flags |= TCQ_F_THROTTLED;
        }
        return NULL;
@@ -195,6 +204,7 @@ static int dly_change(struct Qdisc *sch, struct rtattr *opt)
        } else {
                q->latency = qopt->latency;
                q->limit = qopt->limit;
+               q->loss = qopt->loss;
        }
        return err;
 }
@@ -231,6 +241,7 @@ static int dly_dump(struct Qdisc *sch, struct sk_buff *skb)
 
        qopt.latency = q->latency;
        qopt.limit = q->limit;
+       qopt.loss = q->loss;
 
        RTA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt);
 
index 151c841..ec0ae43 100644 (file)
@@ -1721,8 +1721,7 @@ hfsc_dequeue(struct Qdisc *sch)
                cl = actlist_get_minvt(&q->root, cur_time);
                if (cl == NULL) {
                        sch->stats.overlimits++;
-                       if (!netif_queue_stopped(sch->dev))
-                               hfsc_schedule_watchdog(sch, cur_time);
+                       hfsc_schedule_watchdog(sch, cur_time);
                        return NULL;
                }
        }
index a9e5c8c..d581cad 100644 (file)
@@ -1008,7 +1008,6 @@ next:
 static void htb_delay_by(struct Qdisc *sch,long delay)
 {
        struct htb_sched *q = (struct htb_sched *)sch->data;
-       if (netif_queue_stopped(sch->dev)) return;
        if (delay <= 0) delay = 1;
        if (unlikely(delay > 5*HZ)) {
                if (net_ratelimit())
index 7854980..79c4aff 100644 (file)
@@ -201,7 +201,7 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
 
        if (skb) {
                psched_time_t now;
-               long toks;
+               long toks, delay;
                long ptoks = 0;
                unsigned int len = skb->len;
 
@@ -229,14 +229,12 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
                        return skb;
                }
 
-               if (!netif_queue_stopped(sch->dev)) {
-                       long delay = PSCHED_US2JIFFIE(max_t(long, -toks, -ptoks));
+               delay = PSCHED_US2JIFFIE(max_t(long, -toks, -ptoks));
 
-                       if (delay == 0)
-                               delay = 1;
+               if (delay == 0)
+                       delay = 1;
 
-                       mod_timer(&q->wd_timer, jiffies+delay);
-               }
+               mod_timer(&q->wd_timer, jiffies+delay);
 
                /* Maybe we have a shorter packet in the queue,
                   which can be sent now. It sounds cool,
index b80ea90..bd27e0e 100644 (file)
@@ -1834,23 +1834,28 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
        /* Allocate storage for the negotiated streams if it is not a temporary          * association.
         */
        if (!asoc->temp) {
-               sctp_assoc_t assoc_id;
+               int assoc_id;
+               int error;
 
                asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
                                               asoc->c.sinit_num_ostreams, gfp);
                if (!asoc->ssnmap)
                        goto clean_up;
 
-               do {
-                       if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
-                               goto clean_up;
-                       spin_lock_bh(&sctp_assocs_id_lock);
-                       assoc_id = (sctp_assoc_t)idr_get_new(&sctp_assocs_id,
-                                                            (void *)asoc);
-                       spin_unlock_bh(&sctp_assocs_id_lock);
-               } while (unlikely((int)assoc_id == -1));
+       retry:
+               if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
+                       goto clean_up;
+               spin_lock_bh(&sctp_assocs_id_lock);
+               error = idr_get_new(&sctp_assocs_id,
+                                   (void *)asoc,
+                                   &assoc_id);
+               spin_unlock_bh(&sctp_assocs_id_lock);
+               if (error == -EAGAIN)
+                       goto retry;
+               else if (error)
+                       goto clean_up;
 
-               asoc->assoc_id = assoc_id;
+               asoc->assoc_id = (sctp_assoc_t) assoc_id;
        }
 
        /* ADDIP Section 4.1 ASCONF Chunk Procedures
index 79f072a..83cee2a 100644 (file)
@@ -429,6 +429,9 @@ static void sctp_cmd_init_failed(sctp_cmd_seq_t *commands,
                sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
                                SCTP_ULPEVENT(event));
 
+       sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+                       SCTP_STATE(SCTP_STATE_CLOSED));
+
        /* SEND_FAILED sent later when cleaning up the association. */
        asoc->outqueue.error = error;
        sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
@@ -457,6 +460,10 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands,
        sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
                        SCTP_STATE(SCTP_STATE_CLOSED));
 
+       /* Set sk_err to ECONNRESET on a 1-1 style socket. */
+       if (!sctp_style(asoc->base.sk, UDP))
+               asoc->base.sk->sk_err = ECONNRESET; 
+
        /* SEND_FAILED sent later when cleaning up the association. */
        asoc->outqueue.error = error;
        sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
@@ -1272,6 +1279,9 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
                case SCTP_CMD_PROCESS_OPERR:
                        sctp_cmd_process_operr(commands, asoc, chunk);
                        break;
+               case SCTP_CMD_CLEAR_INIT_TAG:
+                       asoc->peer.i.init_tag = 0;
+                       break;
                default:
                        printk(KERN_WARNING "Impossible command: %u, %p\n",
                               cmd->verb, cmd->obj.ptr);
index 3804123..30849b0 100644 (file)
@@ -171,7 +171,7 @@ nomem:
  *    Verification Tag field to Tag_A, and also provide its own
  *    Verification Tag (Tag_Z) in the Initiate Tag field.
  *
- * Verification Tag: No checking.
+ * Verification Tag: Must be 0. 
  *
  * Inputs
  * (endpoint, asoc, chunk)
@@ -219,6 +219,12 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
             (sk->sk_ack_backlog >= sk->sk_max_ack_backlog)))
                return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
 
+       /* 3.1 A packet containing an INIT chunk MUST have a zero Verification
+        * Tag. 
+        */
+       if (chunk->sctp_hdr->vtag != 0)
+               return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+
        /* Verify the INIT chunk before processing it. */
        err_chunk = NULL;
        if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
@@ -377,6 +383,9 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
        if (!chunk->singleton)
                return SCTP_DISPOSITION_VIOLATION;
 
+       if (!sctp_vtag_verify(chunk, asoc))
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
        /* Grab the INIT header.  */
        chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
 
@@ -659,8 +668,12 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
                                      const sctp_subtype_t type, void *arg,
                                      sctp_cmd_seq_t *commands)
 {
+       struct sctp_chunk *chunk = arg;
        struct sctp_ulpevent *ev;
 
+       if (!sctp_vtag_verify(chunk, asoc))
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
        /* RFC 2960 5.1 Normal Establishment of an Association
         *
         * E) Upon reception of the COOKIE ACK, endpoint "A" will move
@@ -807,13 +820,7 @@ sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep,
        struct sctp_chunk *reply;
        size_t paylen = 0;
 
-       /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
-        * that the value in the Verification Tag field of the
-        * received SCTP packet matches its own Tag. If the received
-        * Verification Tag value does not match the receiver's own
-        * tag value, the receiver shall silently discard the packet...
-        */
-       if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+       if (!sctp_vtag_verify(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
        /* 8.3 The receiver of the HEARTBEAT should immediately
@@ -876,11 +883,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
        sctp_sender_hb_info_t *hbinfo;
        unsigned long max_interval;
 
-       /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
-        * that the value in the Verification Tag field of the
-        * received SCTP packet matches its own Tag. ...
-        */
-       if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+       if (!sctp_vtag_verify(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
        hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
@@ -1130,6 +1133,12 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
        if (!chunk->singleton)
                return SCTP_DISPOSITION_VIOLATION;
 
+       /* 3.1 A packet containing an INIT chunk MUST have a zero Verification
+        * Tag. 
+        */
+       if (chunk->sctp_hdr->vtag != 0)
+               return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+
        /* Grab the INIT header.  */
        chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
 
@@ -1386,6 +1395,8 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
        sctp_init_chunk_t *peer_init;
        struct sctp_ulpevent *ev;
        struct sctp_chunk *repl;
+       struct sctp_chunk *err;
+       sctp_disposition_t disposition;
 
        /* new_asoc is a brand-new association, so these are not yet
         * side effects--it is safe to run them here.
@@ -1405,6 +1416,29 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
                return SCTP_DISPOSITION_CONSUME;
        }
 
+       /* If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes
+        * the peer has restarted (Action A), it MUST NOT setup a new
+        * association but instead resend the SHUTDOWN ACK and send an ERROR
+        * chunk with a "Cookie Received while Shutting Down" error cause to
+        * its peer.
+       */
+       if (sctp_state(asoc, SHUTDOWN_ACK_SENT)) {
+               disposition = sctp_sf_do_9_2_reshutack(ep, asoc,
+                               SCTP_ST_CHUNK(chunk->chunk_hdr->type),
+                               chunk, commands);
+               if (SCTP_DISPOSITION_NOMEM == disposition)
+                       goto nomem;
+
+               err = sctp_make_op_error(asoc, chunk,
+                                        SCTP_ERROR_COOKIE_IN_SHUTDOWN,
+                                        NULL, 0);
+               if (err)
+                       sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
+                                       SCTP_CHUNK(err));
+
+               return SCTP_DISPOSITION_CONSUME;
+       }
+
        /* For now, fail any unsent/unacked data.  Consider the optional
         * choice of resending of this data.
         */
@@ -1883,6 +1917,9 @@ sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
 
        sctp_addto_chunk(reply, sizeof(bht), &bht);
 
+       /* Clear peer's init_tag cached in assoc as we are sending a new INIT */
+       sctp_add_cmd_sf(commands, SCTP_CMD_CLEAR_INIT_TAG, SCTP_NULL());
+
        /* Cast away the const modifier, as we want to just
         * rerun it through as a sideffect.
         */
@@ -2071,13 +2108,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
        skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t));
        chunk->subh.shutdown_hdr = sdh;
 
-       /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
-        * that the value in the Verification Tag field of the
-        * received SCTP packet matches its own Tag. If the received
-        * Verification Tag value does not match the receiver's own
-        * tag value, the receiver shall silently discard the packet...
-        */
-       if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+       if (!sctp_vtag_verify(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
        /* Upon the reception of the SHUTDOWN, the peer endpoint shall
@@ -2190,13 +2221,7 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(const struct sctp_endpoint *ep,
        sctp_cwrhdr_t *cwr;
        struct sctp_chunk *chunk = arg;
 
-       /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
-        * that the value in the Verification Tag field of the
-        * received SCTP packet matches its own Tag. If the received
-        * Verification Tag value does not match the receiver's own
-        * tag value, the receiver shall silently discard the packet...
-        */
-       if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+       if (!sctp_vtag_verify(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
        cwr = (sctp_cwrhdr_t *) chunk->skb->data;
@@ -2246,13 +2271,7 @@ sctp_disposition_t sctp_sf_do_ecne(const struct sctp_endpoint *ep,
        sctp_ecnehdr_t *ecne;
        struct sctp_chunk *chunk = arg;
 
-       /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
-        * that the value in the Verification Tag field of the
-        * received SCTP packet matches its own Tag. If the received
-        * Verification Tag value does not match the receiver's own
-        * tag value, the receiver shall silently discard the packet...
-        */
-       if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+       if (!sctp_vtag_verify(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
        ecne = (sctp_ecnehdr_t *) chunk->skb->data;
@@ -2309,13 +2328,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
        int tmp;
        __u32 tsn;
 
-       /* RFC 2960 8.5 Verification Tag
-        *
-        * When receiving an SCTP packet, the endpoint MUST ensure
-        * that the value in the Verification Tag field of the
-        * received SCTP packet matches its own Tag.
-        */
-       if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
+       if (!sctp_vtag_verify(chunk, asoc)) {
                sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
                                SCTP_NULL());
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -2569,13 +2582,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const struct sctp_endpoint *ep,
        int tmp;
        __u32 tsn;
 
-       /* RFC 2960 8.5 Verification Tag
-        *
-        * When receiving an SCTP packet, the endpoint MUST ensure
-        * that the value in the Verification Tag field of the
-        * received SCTP packet matches its own Tag.
-        */
-       if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
+       if (!sctp_vtag_verify(chunk, asoc)) {
                sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
                                SCTP_NULL());
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -2745,11 +2752,7 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
        sctp_sackhdr_t *sackh;
        __u32 ctsn;
 
-       /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
-        * that the value in the Verification Tag field of the
-        * received SCTP packet matches its own Tag. ...
-        */
-       if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+       if (!sctp_vtag_verify(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
        /* Pull the SACK chunk from the data buffer */
@@ -2895,6 +2898,9 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep,
        struct sctp_chunk *reply;
        struct sctp_ulpevent *ev;
 
+       if (!sctp_vtag_verify(chunk, asoc))
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
        /* 10.2 H) SHUTDOWN COMPLETE notification
         *
         * When SCTP completes the shutdown procedures (section 9.2) this
@@ -3229,13 +3235,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep,
        __u16 len;
        __u32 tsn;
 
-       /* RFC 2960 8.5 Verification Tag
-        *
-        * When receiving an SCTP packet, the endpoint MUST ensure
-        * that the value in the Verification Tag field of the
-        * received SCTP packet matches its own Tag.
-        */
-       if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
+       if (!sctp_vtag_verify(chunk, asoc)) {
                sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
                                SCTP_NULL());
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -3293,13 +3293,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast(
        __u16 len;
        __u32 tsn;
 
-       /* RFC 2960 8.5 Verification Tag
-        *
-        * When receiving an SCTP packet, the endpoint MUST ensure
-        * that the value in the Verification Tag field of the
-        * received SCTP packet matches its own Tag.
-        */
-       if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
+       if (!sctp_vtag_verify(chunk, asoc)) {
                sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
                                SCTP_NULL());
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -3376,13 +3370,7 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
 
        SCTP_DEBUG_PRINTK("Processing the unknown chunk id %d.\n", type.chunk);
 
-       /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
-        * that the value in the Verification Tag field of the
-        * received SCTP packet matches its own Tag.  If the received
-        * Verification Tag value does not match the receiver's own
-        * tag value, the receiver shall silently discard the packet.
-        */
-       if (ntohl(unk_chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+       if (!sctp_vtag_verify(unk_chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
        switch (type.chunk & SCTP_CID_ACTION_MASK) {
index a3c0350..491b510 100644 (file)
@@ -1164,6 +1164,11 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
        if (!asoc) {
                SCTP_DEBUG_PRINTK("There is no association yet.\n");
 
+               if (sinfo_flags & (MSG_EOF | MSG_ABORT)) {
+                       err = -EINVAL;
+                       goto out_unlock;
+               }
+
                /* Check for invalid stream against the stream counts,
                 * either the default or the user specified stream counts.
                 */
@@ -2799,7 +2804,7 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
 
        if (len != sizeof(struct sctp_paddrparams))
                return -EINVAL;
-       if (copy_from_user(&params, optval, *optlen))   /* XXXXXX */
+       if (copy_from_user(&params, optval, len))
                return -EFAULT;
 
        trans = sctp_addr_id2transport(sk, &params.spp_address,
@@ -2969,7 +2974,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
        int cnt = 0;
        struct sctp_getaddrs getaddrs;
        struct sctp_sockaddr_entry *from;
-       void *to;
+       void __user *to;
        union sctp_addr temp;
        struct sctp_opt *sp = sctp_sk(sk);
        int addrlen;
@@ -2996,7 +3001,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
                bp = &asoc->base.bind_addr;
        }
 
-       to = (void *)getaddrs.addrs;
+       to = getaddrs.addrs;
        list_for_each(pos, &bp->address_list) {
                from = list_entry(pos,
                                struct sctp_sockaddr_entry,
@@ -4388,7 +4393,11 @@ out:
        return err;
 
 do_error:
-       err = -ECONNREFUSED;
+       if (asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1 >=
+                                               asoc->max_init_attempts)
+               err = -ETIMEDOUT;
+       else
+               err = -ECONNREFUSED;
        goto out;
 
 do_interrupted:
index 16f84b1..89fa20c 100644 (file)
@@ -232,7 +232,7 @@ static int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
                                return -EINVAL;
                }
                if (put_user((*(int *)(table->data) * 1000) / HZ,
-                       (int *)oldval) ||
+                       (int __user *)oldval) ||
                    (oldlenp && put_user(sizeof (int), oldlenp)))
                        return -EFAULT;
        }
@@ -242,7 +242,7 @@ static int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
                if (newlen != sizeof (int))
                        return -EINVAL;
 
-               if (get_user(new, (int *)newval))
+               if (get_user(new, (int __user *)newval))
                        return -EFAULT;
 
                *(int *)(table->data) = (new * HZ) / 1000;
index 3549ae8..4e948dc 100644 (file)
@@ -741,9 +741,9 @@ static ssize_t sock_writev(struct file *file, const struct iovec *vector,
  */
 
 static DECLARE_MUTEX(br_ioctl_mutex);
-static int (*br_ioctl_hook)(unsigned int cmd, unsigned long arg) = NULL;
+static int (*br_ioctl_hook)(unsigned int cmd, void __user *arg) = NULL;
 
-void brioctl_set(int (*hook)(unsigned int, unsigned long))
+void brioctl_set(int (*hook)(unsigned int, void __user *))
 {
        down(&br_ioctl_mutex);
        br_ioctl_hook = hook;
@@ -752,9 +752,9 @@ void brioctl_set(int (*hook)(unsigned int, unsigned long))
 EXPORT_SYMBOL(brioctl_set);
 
 static DECLARE_MUTEX(vlan_ioctl_mutex);
-static int (*vlan_ioctl_hook)(unsigned long arg);
+static int (*vlan_ioctl_hook)(void __user *arg);
 
-void vlan_ioctl_set(int (*hook)(unsigned long))
+void vlan_ioctl_set(int (*hook)(void __user *))
 {
        down(&vlan_ioctl_mutex);
        vlan_ioctl_hook = hook;
@@ -763,9 +763,9 @@ void vlan_ioctl_set(int (*hook)(unsigned long))
 EXPORT_SYMBOL(vlan_ioctl_set);
 
 static DECLARE_MUTEX(dlci_ioctl_mutex);
-static int (*dlci_ioctl_hook)(unsigned int, void *);
+static int (*dlci_ioctl_hook)(unsigned int, void __user *);
 
-void dlci_ioctl_set(int (*hook)(unsigned int, void *))
+void dlci_ioctl_set(int (*hook)(unsigned int, void __user *))
 {
        down(&dlci_ioctl_mutex);
        dlci_ioctl_hook = hook;
@@ -782,29 +782,30 @@ static int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                      unsigned long arg)
 {
        struct socket *sock;
+       void __user *argp = (void __user *)arg;
        int pid, err;
 
        unlock_kernel();
        sock = SOCKET_I(inode);
        if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
-               err = dev_ioctl(cmd, (void __user *)arg);
+               err = dev_ioctl(cmd, argp);
        } else
 #ifdef WIRELESS_EXT
        if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
-               err = dev_ioctl(cmd, (void __user *)arg);
+               err = dev_ioctl(cmd, argp);
        } else
 #endif /* WIRELESS_EXT */
        switch (cmd) {
                case FIOSETOWN:
                case SIOCSPGRP:
                        err = -EFAULT;
-                       if (get_user(pid, (int __user *)arg))
+                       if (get_user(pid, (int __user *)argp))
                                break;
                        err = f_setown(sock->file, pid, 1);
                        break;
                case FIOGETOWN:
                case SIOCGPGRP:
-                       err = put_user(sock->file->f_owner.pid, (int __user *)arg);
+                       err = put_user(sock->file->f_owner.pid, (int __user *)argp);
                        break;
                case SIOCGIFBR:
                case SIOCSIFBR:
@@ -816,7 +817,7 @@ static int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
                        down(&br_ioctl_mutex);
                        if (br_ioctl_hook) 
-                               err = br_ioctl_hook(cmd, arg);
+                               err = br_ioctl_hook(cmd, argp);
                        up(&br_ioctl_mutex);
                        break;
                case SIOCGIFVLAN:
@@ -827,13 +828,13 @@ static int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
                        down(&vlan_ioctl_mutex);
                        if (vlan_ioctl_hook)
-                               err = vlan_ioctl_hook(arg);
+                               err = vlan_ioctl_hook(argp);
                        up(&vlan_ioctl_mutex);
                        break;
                case SIOCGIFDIVERT:
                case SIOCSIFDIVERT:
                /* Convert this to call through a hook */
-                       err = divert_ioctl(cmd, (struct divert_cf *)arg);
+                       err = divert_ioctl(cmd, argp);
                        break;
                case SIOCADDDLCI:
                case SIOCDELDLCI:
@@ -843,7 +844,7 @@ static int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
                        if (dlci_ioctl_hook) {
                                down(&dlci_ioctl_mutex);
-                               err = dlci_ioctl_hook(cmd, (void *)arg);
+                               err = dlci_ioctl_hook(cmd, argp);
                                up(&dlci_ioctl_mutex);
                        }
                        break;
index 06aa0a3..60bca99 100644 (file)
@@ -493,7 +493,7 @@ gss_pipe_downcall(struct file *filp, const char *src, size_t mlen)
                spin_unlock(&gss_auth->lock);
        rpc_release_client(clnt);
        kfree(obj.data);
-       dprintk("RPC:      gss_pipe_downcall returning length %u\n", mlen);
+       dprintk("RPC:      gss_pipe_downcall returning length %Zu\n", mlen);
        return mlen;
 err:
        if (ctx)
index 03bd7bd..55b2fd1 100644 (file)
@@ -333,6 +333,7 @@ rsc_init(struct rsc *new, struct rsc *tmp)
        new->handle.data = tmp->handle.data;
        tmp->handle.data = NULL;
        new->mechctx = NULL;
+       new->cred.cr_group_info = NULL;
 }
 
 static inline void
@@ -453,8 +454,11 @@ gss_svc_searchbyctx(struct xdr_netobj *handle)
        struct rsc rsci;
        struct rsc *found;
 
-       rsci.handle = *handle;
+       memset(&rsci, 0, sizeof(rsci));
+       if (dup_to_netobj(&rsci.handle, handle->data, handle->len))
+               return NULL;
        found = rsc_lookup(&rsci, 0);
+       rsc_free(&rsci);
        if (!found)
                return NULL;
        if (cache_check(&rsc_cache, &found->h, NULL))
@@ -1045,6 +1049,7 @@ svcauth_gss_domain_release(struct auth_domain *dom)
 
 struct auth_ops svcauthops_gss = {
        .name           = "rpcsec_gss",
+       .owner          = THIS_MODULE,
        .flavour        = RPC_AUTH_GSS,
        .accept         = svcauth_gss_accept,
        .release        = svcauth_gss_release,
@@ -1054,10 +1059,12 @@ struct auth_ops svcauthops_gss = {
 int
 gss_svc_init(void)
 {
-       cache_register(&rsc_cache);
-       cache_register(&rsi_cache);
-       svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
-       return 0;
+       int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
+       if (rv == 0) {
+               cache_register(&rsc_cache);
+               cache_register(&rsi_cache);
+       }
+       return rv;
 }
 
 void
@@ -1065,4 +1072,5 @@ gss_svc_shutdown(void)
 {
        cache_unregister(&rsc_cache);
        cache_unregister(&rsi_cache);
+       svc_auth_unregister(RPC_AUTH_GSS);
 }
index db78e72..54ea896 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/types.h>
 #include <linux/sched.h>
+#include <linux/module.h>
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
 #include <linux/sunrpc/svcsock.h>
@@ -27,6 +28,7 @@
 extern struct auth_ops svcauth_null;
 extern struct auth_ops svcauth_unix;
 
+static spinlock_t authtab_lock = SPIN_LOCK_UNLOCKED;
 static struct auth_ops *authtab[RPC_AUTH_MAXFLAVOR] = {
        [0] = &svcauth_null,
        [1] = &svcauth_unix,
@@ -43,10 +45,15 @@ svc_authenticate(struct svc_rqst *rqstp, u32 *authp)
        flavor = ntohl(svc_getu32(&rqstp->rq_arg.head[0]));
 
        dprintk("svc: svc_authenticate (%d)\n", flavor);
-       if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor])) {
+
+       spin_lock(&authtab_lock);
+       if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor])
+                       || !try_module_get(aops->owner)) {
+               spin_unlock(&authtab_lock);
                *authp = rpc_autherr_badcred;
                return SVC_DENIED;
        }
+       spin_unlock(&authtab_lock);
 
        rqstp->rq_authop = aops;
        return aops->accept(rqstp, authp);
@@ -63,28 +70,35 @@ int svc_authorise(struct svc_rqst *rqstp)
 
        rqstp->rq_authop = NULL;
        
-       if (aops) 
+       if (aops) {
                rv = aops->release(rqstp);
-
-       /* FIXME should I count and release authops */
+               module_put(aops->owner);
+       }
        return rv;
 }
 
 int
 svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops)
 {
-       if (flavor >= RPC_AUTH_MAXFLAVOR || authtab[flavor])
-               return -EINVAL;
-       authtab[flavor] = aops;
-       return 0;
+       int rv = -EINVAL;
+       spin_lock(&authtab_lock);
+       if (flavor < RPC_AUTH_MAXFLAVOR && authtab[flavor] == NULL) {
+               authtab[flavor] = aops;
+               rv = 0;
+       }
+       spin_unlock(&authtab_lock);
+       return rv;
 }
 
 void
 svc_auth_unregister(rpc_authflavor_t flavor)
 {
+       spin_lock(&authtab_lock);
        if (flavor < RPC_AUTH_MAXFLAVOR)
                authtab[flavor] = NULL;
+       spin_unlock(&authtab_lock);
 }
+EXPORT_SYMBOL(svc_auth_unregister);
 
 /**************************************************
  * cache for domain name to auth_domain
index 082684d..ab5164b 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/types.h>
 #include <linux/sched.h>
+#include <linux/module.h>
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
 #include <linux/sunrpc/svcsock.h>
@@ -411,6 +412,7 @@ svcauth_null_release(struct svc_rqst *rqstp)
 
 struct auth_ops svcauth_null = {
        .name           = "null",
+       .owner          = THIS_MODULE,
        .flavour        = RPC_AUTH_NULL,
        .accept         = svcauth_null_accept,
        .release        = svcauth_null_release,
@@ -515,6 +517,7 @@ svcauth_unix_release(struct svc_rqst *rqstp)
 
 struct auth_ops svcauth_unix = {
        .name           = "unix",
+       .owner          = THIS_MODULE,
        .flavour        = RPC_AUTH_UNIX,
        .accept         = svcauth_unix_accept,
        .release        = svcauth_unix_release,
index 024e768..a5dc976 100644 (file)
@@ -125,7 +125,7 @@ svc_sock_wspace(struct svc_sock *svsk)
        int wspace;
 
        if (svsk->sk_sock->type == SOCK_STREAM)
-               wspace = tcp_wspace(svsk->sk_sk);
+               wspace = sk_stream_wspace(svsk->sk_sk);
        else
                wspace = sock_wspace(svsk->sk_sk);
 
index abfb211..cf4cf02 100644 (file)
@@ -1086,8 +1086,8 @@ xprt_write_space(struct sock *sk)
 
        /* Wait until we have enough socket memory */
        if (xprt->stream) {
-               /* from net/ipv4/tcp.c:tcp_write_space */
-               if (tcp_wspace(sk) < tcp_min_write_space(sk))
+               /* from net/core/stream.c:sk_stream_write_space */
+               if (sk_stream_wspace(sk) < sk_stream_min_wspace(sk))
                        goto out;
        } else {
                /* from net/core/sock.c:sock_def_write_space */
index d8ee5ed..4776ec1 100644 (file)
@@ -552,7 +552,7 @@ static int wanpipe_sendmsg(struct kiocb *iocb, struct socket *sock,
        if (sk->sk_state != WANSOCK_CONNECTED)
                return -ENOTCONN;       
 
-       if (msg->msg_flags&~MSG_DONTWAIT
+       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)
                return(-EINVAL);
 
        /* it was <=, now one can send
index fcdce75..956c17f 100644 (file)
@@ -128,13 +128,14 @@ static void dbg_kfree(void * v, int line) {
  */
 
 static int wanrouter_device_setup(struct wan_device *wandev,
-                                 wandev_conf_t *u_conf);
+                                 wandev_conf_t __user *u_conf);
 static int wanrouter_device_stat(struct wan_device *wandev,
-                                wandev_stat_t *u_stat);
+                                wandev_stat_t __user *u_stat);
 static int wanrouter_device_shutdown(struct wan_device *wandev);
 static int wanrouter_device_new_if(struct wan_device *wandev,
-                                  wanif_conf_t *u_conf);
-static int wanrouter_device_del_if(struct wan_device *wandev, char *u_name);
+                                  wanif_conf_t __user *u_conf);
+static int wanrouter_device_del_if(struct wan_device *wandev,
+                                  char __user *u_name);
 
 /*
  *     Miscellaneous
@@ -410,6 +411,7 @@ int wanrouter_ioctl(struct inode *inode, struct file *file,
        int err = 0;
        struct proc_dir_entry *dent;
        struct wan_device *wandev;
+       void __user *data = (void __user *)arg;
 
        if (!capable(CAP_NET_ADMIN))
                return -EPERM;
@@ -427,7 +429,7 @@ int wanrouter_ioctl(struct inode *inode, struct file *file,
 
        switch (cmd) {
        case ROUTER_SETUP:
-               err = wanrouter_device_setup(wandev, (void*)arg);
+               err = wanrouter_device_setup(wandev, data);
                break;
 
        case ROUTER_DOWN:
@@ -435,15 +437,15 @@ int wanrouter_ioctl(struct inode *inode, struct file *file,
                break;
 
        case ROUTER_STAT:
-               err = wanrouter_device_stat(wandev, (void*)arg);
+               err = wanrouter_device_stat(wandev, data);
                break;
 
        case ROUTER_IFNEW:
-               err = wanrouter_device_new_if(wandev, (void*)arg);
+               err = wanrouter_device_new_if(wandev, data);
                break;
 
        case ROUTER_IFDEL:
-               err = wanrouter_device_del_if(wandev, (void*)arg);
+               err = wanrouter_device_del_if(wandev, data);
                break;
 
        case ROUTER_IFSTAT:
@@ -472,7 +474,7 @@ int wanrouter_ioctl(struct inode *inode, struct file *file,
  */
 
 static int wanrouter_device_setup(struct wan_device *wandev,
-                                 wandev_conf_t *u_conf)
+                                 wandev_conf_t __user *u_conf)
 {
        void *data = NULL;
        wandev_conf_t *conf;
@@ -583,7 +585,7 @@ static int wanrouter_device_shutdown(struct wan_device *wandev)
  */
 
 static int wanrouter_device_stat(struct wan_device *wandev,
-                                wandev_stat_t *u_stat)
+                                wandev_stat_t __user *u_stat)
 {
        wandev_stat_t stat;
 
@@ -614,7 +616,7 @@ static int wanrouter_device_stat(struct wan_device *wandev,
  */
 
 static int wanrouter_device_new_if(struct wan_device *wandev,
-                                  wanif_conf_t *u_conf)
+                                  wanif_conf_t __user *u_conf)
 {
        wanif_conf_t *cnf;
        struct net_device *dev = NULL;
@@ -740,7 +742,7 @@ out:
  *      o copy configuration data to kernel address space
  */
 
-static int wanrouter_device_del_if(struct wan_device *wandev, char *u_name)
+static int wanrouter_device_del_if(struct wan_device *wandev, char __user *u_name)
 {
        char name[WAN_IFNAME_SZ + 1];
         int err = 0;
index 9863ccd..17d2034 100644 (file)
@@ -922,7 +922,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
        size_t size;
        int qbit = 0, rc = -EINVAL;
 
-       if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_OOB | MSG_EOR))
+       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR|MSG_CMSG_COMPAT))
                goto out;
 
        /* we currently don't support segmented records at the user interface */
@@ -1180,6 +1180,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
        struct x25_opt *x25 = x25_sk(sk);
+       void __user *argp = (void __user *)arg;
        int rc;
 
        switch (cmd) {
@@ -1188,7 +1189,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                                     atomic_read(&sk->sk_wmem_alloc);
                        if (amount < 0)
                                amount = 0;
-                       rc = put_user(amount, (unsigned int *)arg);
+                       rc = put_user(amount, (unsigned int __user *)argp);
                        break;
                }
 
@@ -1201,7 +1202,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                         */
                        if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
                                amount = skb->len;
-                       rc = put_user(amount, (unsigned int *)arg);
+                       rc = put_user(amount, (unsigned int __user *)argp);
                        break;
                }
 
@@ -1209,7 +1210,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        rc = -EINVAL;
                        if (sk)
                                rc = sock_get_timestamp(sk, 
-                                               (struct timeval __user *)arg); 
+                                               (struct timeval __user *)argp); 
                        break;
                case SIOCGIFADDR:
                case SIOCSIFADDR:
@@ -1228,20 +1229,20 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        rc = -EPERM;
                        if (!capable(CAP_NET_ADMIN))
                                break;
-                       rc = x25_route_ioctl(cmd, (void *)arg);
+                       rc = x25_route_ioctl(cmd, argp);
                        break;
                case SIOCX25GSUBSCRIP:
-                       rc = x25_subscr_ioctl(cmd, (void *)arg);
+                       rc = x25_subscr_ioctl(cmd, argp);
                        break;
                case SIOCX25SSUBSCRIP:
                        rc = -EPERM;
                        if (!capable(CAP_NET_ADMIN))
                                break;
-                       rc = x25_subscr_ioctl(cmd, (void *)arg);
+                       rc = x25_subscr_ioctl(cmd, argp);
                        break;
                case SIOCX25GFACILITIES: {
                        struct x25_facilities fac = x25->facilities;
-                       rc = copy_to_user((void *)arg, &fac,
+                       rc = copy_to_user(argp, &fac,
                                          sizeof(fac)) ? -EFAULT : 0;
                        break;
                }
@@ -1249,7 +1250,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                case SIOCX25SFACILITIES: {
                        struct x25_facilities facilities;
                        rc = -EFAULT;
-                       if (copy_from_user(&facilities, (void *)arg,
+                       if (copy_from_user(&facilities, argp,
                                           sizeof(facilities)))
                                break;
                        rc = -EINVAL;
@@ -1277,7 +1278,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
                case SIOCX25GCALLUSERDATA: {
                        struct x25_calluserdata cud = x25->calluserdata;
-                       rc = copy_to_user((void *)arg, &cud,
+                       rc = copy_to_user(argp, &cud,
                                          sizeof(cud)) ? -EFAULT : 0;
                        break;
                }
@@ -1286,7 +1287,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        struct x25_calluserdata calluserdata;
 
                        rc = -EFAULT;
-                       if (copy_from_user(&calluserdata, (void *)arg,
+                       if (copy_from_user(&calluserdata, argp,
                                           sizeof(calluserdata)))
                                break;
                        rc = -EINVAL;
@@ -1300,13 +1301,13 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                case SIOCX25GCAUSEDIAG: {
                        struct x25_causediag causediag;
                        causediag = x25->causediag;
-                       rc = copy_to_user((void *)arg, &causediag,
+                       rc = copy_to_user(argp, &causediag,
                                          sizeof(causediag)) ? -EFAULT : 0;
                        break;
                }
 
                default:
-                       rc = dev_ioctl(cmd, (void __user *)arg);
+                       rc = dev_ioctl(cmd, argp);
                        break;
        }
 
index c5df945..1181466 100644 (file)
@@ -374,7 +374,7 @@ struct x25_neigh *x25_get_neigh(struct net_device *dev)
 /*
  *     Handle the ioctls that control the subscription functions.
  */
-int x25_subscr_ioctl(unsigned int cmd, void *arg)
+int x25_subscr_ioctl(unsigned int cmd, void __user *arg)
 {
        struct x25_subscrip_struct x25_subscr;
        struct x25_neigh *nb;
index 07ae9d9..4697d55 100644 (file)
@@ -174,7 +174,7 @@ struct x25_route *x25_get_route(struct x25_address *addr)
 /*
  *     Handle the ioctls that control the routing functions.
  */
-int x25_route_ioctl(unsigned int cmd, void *arg)
+int x25_route_ioctl(unsigned int cmd, void __user *arg)
 {
        struct x25_route_struct rt;
        struct net_device *dev;
index e725e6b..951e115 100644 (file)
@@ -6,7 +6,7 @@ deps_scripts/basic/docproc := \
   /usr/include/features.h \
   /usr/include/sys/cdefs.h \
   /usr/include/gnu/stubs.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \
   /usr/include/bits/types.h \
   /usr/include/bits/wordsize.h \
   /usr/include/bits/typesizes.h \
@@ -15,7 +15,7 @@ deps_scripts/basic/docproc := \
   /usr/include/wchar.h \
   /usr/include/bits/wchar.h \
   /usr/include/gconv.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \
   /usr/include/bits/stdio_lim.h \
   /usr/include/bits/sys_errlist.h \
   /usr/include/bits/stdio.h \
@@ -40,8 +40,8 @@ deps_scripts/basic/docproc := \
   /usr/include/bits/posix_opt.h \
   /usr/include/bits/confname.h \
   /usr/include/getopt.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/limits.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/syslimits.h \
   /usr/include/limits.h \
   /usr/include/bits/posix1_lim.h \
   /usr/include/bits/local_lim.h \
@@ -54,9 +54,6 @@ deps_scripts/basic/docproc := \
   /usr/include/bits/sigaction.h \
   /usr/include/bits/sigcontext.h \
   /usr/include/asm/sigcontext.h \
-  /usr/include/linux/compiler.h \
-  /usr/include/linux/compiler-gcc3.h \
-  /usr/include/linux/compiler-gcc.h \
   /usr/include/bits/sigstack.h \
   /usr/include/bits/sigthread.h \
   /usr/include/sys/resource.h \
index 1c463aa..cb21b0e 100644 (file)
@@ -12,7 +12,7 @@ deps_scripts/basic/fixdep := \
   /usr/include/gnu/stubs.h \
   /usr/include/bits/types.h \
   /usr/include/bits/wordsize.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \
   /usr/include/bits/typesizes.h \
   /usr/include/time.h \
   /usr/include/endian.h \
@@ -45,12 +45,12 @@ deps_scripts/basic/fixdep := \
   /usr/include/wchar.h \
   /usr/include/bits/wchar.h \
   /usr/include/gconv.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \
   /usr/include/bits/stdio_lim.h \
   /usr/include/bits/sys_errlist.h \
   /usr/include/bits/stdio.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/limits.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/syslimits.h \
   /usr/include/limits.h \
   /usr/include/bits/posix1_lim.h \
   /usr/include/bits/local_lim.h \
index e596a87..f0039a3 100644 (file)
@@ -9,7 +9,7 @@ deps_scripts/basic/split-include := \
   /usr/include/gnu/stubs.h \
   /usr/include/bits/types.h \
   /usr/include/bits/wordsize.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \
   /usr/include/bits/typesizes.h \
   /usr/include/time.h \
   /usr/include/bits/stat.h \
@@ -28,8 +28,6 @@ deps_scripts/basic/split-include := \
   /usr/include/bits/errno.h \
   /usr/include/linux/errno.h \
   /usr/include/asm/errno.h \
-  /usr/include/asm-generic/errno.h \
-  /usr/include/asm-generic/errno-base.h \
   /usr/include/fcntl.h \
   /usr/include/bits/fcntl.h \
   /usr/include/stdio.h \
@@ -38,7 +36,7 @@ deps_scripts/basic/split-include := \
   /usr/include/wchar.h \
   /usr/include/bits/wchar.h \
   /usr/include/gconv.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \
   /usr/include/bits/stdio_lim.h \
   /usr/include/bits/sys_errlist.h \
   /usr/include/bits/stdio.h \
index 51640ad..76cf2bd 100755 (executable)
Binary files a/scripts/basic/docproc and b/scripts/basic/docproc differ
index 800beed..f69d32e 100755 (executable)
Binary files a/scripts/basic/fixdep and b/scripts/basic/fixdep differ
index ecd686e..e8361c8 100755 (executable)
Binary files a/scripts/basic/split-include and b/scripts/basic/split-include differ
index df85c66..073704e 100644 (file)
@@ -23,6 +23,7 @@
 # $1 (first bracket) matches the size of the stack growth
 #
 # use anything else and feel the pain ;)
+my (@stack, $re, $x, $xs);
 {
        my $arch = shift;
        if ($arch eq "") {
 
        $x      = "[0-9a-f]";   # hex character
        $xs     = "[0-9a-f ]";  # hex character or space
-       if ($arch =~ /^arm$/) {
+       if ($arch eq 'arm') {
                #c0008ffc:      e24dd064        sub     sp, sp, #100    ; 0x64
                $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
        } elsif ($arch =~ /^i[3456]86$/) {
                #c0105234:       81 ec ac 05 00 00       sub    $0x5ac,%esp
                $re = qr/^.*[as][du][db]    \$(0x$x{1,8}),\%esp$/o;
-       } elsif ($arch =~ /^ia64$/) {
+       } elsif ($arch eq 'ia64') {
                #e0000000044011fc:       01 0f fc 8c     adds r12=-384,r12
                $re = qr/.*adds.*r12=-(([0-9]{2}|[3-9])[0-9]{2}),r12/o;
-       } elsif ($arch =~ /^mips64$/) {
+       } elsif ($arch eq 'mips64') {
                #8800402c:       67bdfff0        daddiu  sp,sp,-16
                $re = qr/.*daddiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
-       } elsif ($arch =~ /^mips$/) {
+       } elsif ($arch eq 'mips') {
                #88003254:       27bdffe0        addiu   sp,sp,-32
                $re = qr/.*addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
-       } elsif ($arch =~ /^ppc$/) {
+       } elsif ($arch eq 'ppc') {
                #c00029f4:       94 21 ff 30     stwu    r1,-208(r1)
                $re = qr/.*stwu.*r1,-($x{1,8})\(r1\)/o;
-       } elsif ($arch =~ /^ppc64$/) {
+       } elsif ($arch eq 'ppc64') {
                #XXX
                $re = qr/.*stdu.*r1,-($x{1,8})\(r1\)/o;
        } elsif ($arch =~ /^s390x?$/) {
@@ -62,6 +63,7 @@
 }
 
 sub bysize($) {
+       my ($asize, $bsize);
        ($asize = $a) =~ s/.*   +(.*)$/$1/;
        ($bsize = $b) =~ s/.*   +(.*)$/$1/;
        $bsize <=> $asize
@@ -70,8 +72,9 @@ sub bysize($) {
 #
 # main()
 #
-$funcre = qr/^$x* \<(.*)\>:$/;
-while ($line = <STDIN>) {
+my $funcre = qr/^$x* <(.*)>:$/;
+my $func;
+while (my $line = <STDIN>) {
        if ($line =~ m/$funcre/) {
                $func = $1;
        }
@@ -85,7 +88,7 @@ while ($line = <STDIN>) {
                        $size += 0x80000000;
                }
 
-               $line =~ m/^($xs*).*/;
+               next if $line !~ m/^($xs*)/;
                my $addr = $1;
                $addr =~ s/ /0/g;
                $addr = "0x$addr";
@@ -97,12 +100,8 @@ while ($line = <STDIN>) {
                        $padlen -= 8;
                }
                next if ($size < 100);
-               $stack[@stack] = "$intro$size\n";
+               push @stack, "$intro$size\n";
        }
 }
 
-@sortedstack = sort bysize @stack;
-
-foreach $i (@sortedstack) {
-       print("$i");
-}
+print sort bysize @stack;
index 2c06e27..8544ec6 100644 (file)
@@ -9,7 +9,7 @@ deps_scripts/kconfig/conf.o := \
   /usr/include/gnu/stubs.h \
   /usr/include/bits/types.h \
   /usr/include/bits/wordsize.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \
   /usr/include/bits/typesizes.h \
   /usr/include/endian.h \
   /usr/include/bits/endian.h \
@@ -41,11 +41,11 @@ deps_scripts/kconfig/conf.o := \
   /usr/include/wchar.h \
   /usr/include/bits/wchar.h \
   /usr/include/gconv.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \
   /usr/include/bits/stdio_lim.h \
   /usr/include/bits/sys_errlist.h \
   /usr/include/bits/stdio.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdbool.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdbool.h \
   scripts/kconfig/lkc_proto.h \
 
 scripts/kconfig/conf.o: $(deps_scripts/kconfig/conf.o)
index 6f874bf..14dd700 100644 (file)
@@ -18,7 +18,7 @@ deps_scripts/kconfig/mconf.o := \
   /usr/include/bits/sigset.h \
   /usr/include/bits/types.h \
   /usr/include/bits/wordsize.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \
   /usr/include/bits/typesizes.h \
   /usr/include/bits/signum.h \
   /usr/include/time.h \
@@ -26,9 +26,6 @@ deps_scripts/kconfig/mconf.o := \
   /usr/include/bits/sigaction.h \
   /usr/include/bits/sigcontext.h \
   /usr/include/asm/sigcontext.h \
-  /usr/include/linux/compiler.h \
-  /usr/include/linux/compiler-gcc3.h \
-  /usr/include/linux/compiler-gcc.h \
   /usr/include/bits/sigstack.h \
   /usr/include/bits/pthreadtypes.h \
   /usr/include/bits/sched.h \
@@ -45,22 +42,20 @@ deps_scripts/kconfig/mconf.o := \
   /usr/include/bits/errno.h \
   /usr/include/linux/errno.h \
   /usr/include/asm/errno.h \
-  /usr/include/asm-generic/errno.h \
-  /usr/include/asm-generic/errno-base.h \
   /usr/include/fcntl.h \
   /usr/include/bits/fcntl.h \
   /usr/include/sys/types.h \
   /usr/include/sys/select.h \
   /usr/include/bits/select.h \
   /usr/include/sys/sysmacros.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/limits.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/syslimits.h \
   /usr/include/limits.h \
   /usr/include/bits/posix1_lim.h \
   /usr/include/bits/local_lim.h \
   /usr/include/linux/limits.h \
   /usr/include/bits/posix2_lim.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \
   /usr/include/stdlib.h \
   /usr/include/alloca.h \
   /usr/include/string.h \
@@ -83,7 +78,7 @@ deps_scripts/kconfig/mconf.o := \
   /usr/include/bits/stdio_lim.h \
   /usr/include/bits/sys_errlist.h \
   /usr/include/bits/stdio.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdbool.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdbool.h \
   scripts/kconfig/lkc_proto.h \
 
 scripts/kconfig/mconf.o: $(deps_scripts/kconfig/mconf.o)
index 2a3661c..6e60f83 100644 (file)
@@ -8,11 +8,11 @@ deps_scripts/kconfig/zconf.tab.o := \
   /usr/include/gnu/stubs.h \
   /usr/include/bits/types.h \
   /usr/include/bits/wordsize.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \
   /usr/include/bits/typesizes.h \
   /usr/include/endian.h \
   /usr/include/bits/endian.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \
   /usr/include/stdio.h \
   /usr/include/libio.h \
   /usr/include/_G_config.h \
@@ -36,7 +36,7 @@ deps_scripts/kconfig/zconf.tab.o := \
   /usr/include/string.h \
   /usr/include/bits/string.h \
   /usr/include/bits/string2.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdbool.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdbool.h \
   scripts/kconfig/lkc.h \
   scripts/kconfig/expr.h \
   scripts/kconfig/lkc_proto.h \
@@ -45,10 +45,8 @@ deps_scripts/kconfig/zconf.tab.o := \
   /usr/include/bits/errno.h \
   /usr/include/linux/errno.h \
   /usr/include/asm/errno.h \
-  /usr/include/asm-generic/errno.h \
-  /usr/include/asm-generic/errno-base.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \
-  /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/limits.h \
+  /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/syslimits.h \
   /usr/include/limits.h \
   /usr/include/bits/posix1_lim.h \
   /usr/include/bits/local_lim.h \
index 89b852e..d1682f7 100755 (executable)
Binary files a/scripts/kconfig/conf and b/scripts/kconfig/conf differ
index c191a8a..efffb8b 100644 (file)
Binary files a/scripts/kconfig/conf.o and b/scripts/kconfig/conf.o differ
index 0916d8a..66eae45 100755 (executable)
Binary files a/scripts/kconfig/libkconfig.so and b/scripts/kconfig/libkconfig.so differ
index 61fe000..7ccae91 100644 (file)
Binary files a/scripts/kconfig/mconf.o and b/scripts/kconfig/mconf.o differ
index 3d1d070..9691ac2 100644 (file)
Binary files a/scripts/kconfig/zconf.tab.o and b/scripts/kconfig/zconf.tab.o differ
index b4e37dc..5f33311 100644 (file)
@@ -90,6 +90,7 @@ foreach $object (sort(keys(%object))) {
                if (($line =~ /\.init$/ || $line =~ /\.init\./) &&
                    ($from !~ /\.init$/ &&
                     $from !~ /\.init\./ &&
+                    $from !~ /\.eh_frame$/ &&
                     $from !~ /\.stab$/ &&
                     $from !~ /\.rodata$/ &&
                     $from !~ /\.text\.lock$/ &&
index 27fa13b..05d9885 100644 (file)
@@ -688,7 +688,7 @@ static int dummy_shm_shmctl (struct shmid_kernel *shp, int cmd)
        return 0;
 }
 
-static int dummy_shm_shmat (struct shmid_kernel *shp, char *shmaddr,
+static int dummy_shm_shmat (struct shmid_kernel *shp, char __user *shmaddr,
                            int shmflg)
 {
        return 0;
@@ -720,7 +720,7 @@ static int dummy_sem_semop (struct sem_array *sma,
        return 0;
 }
 
-static int dummy_netlink_send (struct sk_buff *skb)
+static int dummy_netlink_send (struct sock *sk, struct sk_buff *skb)
 {
        if (current->euid == 0)
                cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
index 890404e..b038cd0 100644 (file)
@@ -4,7 +4,7 @@
 
 obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/
 
-selinux-y := avc.o hooks.o selinuxfs.o netlink.o
+selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o
 
 selinux-$(CONFIG_SECURITY_NETWORK) += netif.o
 
index 35d779a..b2a1418 100644 (file)
@@ -71,6 +71,9 @@
 #define XATTR_SELINUX_SUFFIX "selinux"
 #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
 
+extern int policydb_loaded_version;
+extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
+
 #ifdef CONFIG_SECURITY_SELINUX_DEVELOP
 int selinux_enforcing = 0;
 
@@ -627,7 +630,7 @@ static inline u16 inode_mode_to_security_class(umode_t mode)
        return SECCLASS_FILE;
 }
 
-static inline u16 socket_type_to_security_class(int family, int type)
+static inline u16 socket_type_to_security_class(int family, int type, int protocol)
 {
        switch (family) {
        case PF_UNIX:
@@ -648,7 +651,28 @@ static inline u16 socket_type_to_security_class(int family, int type)
                        return SECCLASS_RAWIP_SOCKET;
                }
        case PF_NETLINK:
-               return SECCLASS_NETLINK_SOCKET;
+               switch (protocol) {
+               case NETLINK_ROUTE:
+                       return SECCLASS_NETLINK_ROUTE_SOCKET;
+               case NETLINK_FIREWALL:
+                       return SECCLASS_NETLINK_FIREWALL_SOCKET;
+               case NETLINK_TCPDIAG:
+                       return SECCLASS_NETLINK_TCPDIAG_SOCKET;
+               case NETLINK_NFLOG:
+                       return SECCLASS_NETLINK_NFLOG_SOCKET;
+               case NETLINK_XFRM:
+                       return SECCLASS_NETLINK_XFRM_SOCKET;
+               case NETLINK_SELINUX:
+                       return SECCLASS_NETLINK_SELINUX_SOCKET;
+               case NETLINK_AUDIT:
+                       return SECCLASS_NETLINK_AUDIT_SOCKET;
+               case NETLINK_IP6_FW:
+                       return SECCLASS_NETLINK_IP6FW_SOCKET;
+               case NETLINK_DNRTMSG:
+                       return SECCLASS_NETLINK_DNRT_SOCKET;
+               default:
+                       return SECCLASS_NETLINK_SOCKET;
+               }
        case PF_PACKET:
                return SECCLASS_PACKET_SOCKET;
        case PF_KEY:
@@ -853,7 +877,8 @@ out:
                struct socket *sock = SOCKET_I(inode);
                if (sock->sk) {
                        isec->sclass = socket_type_to_security_class(sock->sk->sk_family,
-                                                                    sock->sk->sk_type);
+                                                                    sock->sk->sk_type,
+                                                                    sock->sk->sk_protocol);
                } else {
                        isec->sclass = SECCLASS_SOCKET;
                }
@@ -1380,7 +1405,7 @@ static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effecti
        if (error)
                return;
 
-       return secondary_ops->capset_set(target, effective, inheritable, permitted);
+       secondary_ops->capset_set(target, effective, inheritable, permitted);
 }
 
 static int selinux_capable(struct task_struct *tsk, int cap)
@@ -1567,22 +1592,6 @@ static int selinux_vm_enough_memory(long pages)
        return -ENOMEM;
 }
 
-static int selinux_netlink_send(struct sk_buff *skb)
-{
-       if (capable(CAP_NET_ADMIN))
-               cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
-       else
-               NETLINK_CB(skb).eff_cap = 0;
-       return 0;
-}
-
-static int selinux_netlink_recv(struct sk_buff *skb)
-{
-       if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
-               return -EPERM;
-       return 0;
-}
-
 /* binprm security operations */
 
 static int selinux_bprm_alloc_security(struct linux_binprm *bprm)
@@ -2918,8 +2927,8 @@ static int selinux_socket_create(int family, int type,
 
        tsec = current->security;
        err = avc_has_perm(tsec->sid, tsec->sid,
-                          socket_type_to_security_class(family, type),
-                          SOCKET__CREATE, NULL, NULL);
+                          socket_type_to_security_class(family, type,
+                          protocol), SOCKET__CREATE, NULL, NULL);
 
 out:
        return err;
@@ -2938,7 +2947,7 @@ static void selinux_socket_post_create(struct socket *sock, int family,
        isec = SOCK_INODE(sock)->i_security;
 
        tsec = current->security;
-       isec->sclass = socket_type_to_security_class(family, type);
+       isec->sclass = socket_type_to_security_class(family, type, protocol);
        isec->sid = kern ? SECINITSID_KERNEL : tsec->sid;
 
        return;
@@ -3327,6 +3336,55 @@ static void selinux_sk_free_security(struct sock *sk)
        sk_free_security(sk);
 }
 
+static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
+{
+       int err = 0;
+       u32 perm;
+       struct nlmsghdr *nlh;
+       struct socket *sock = sk->sk_socket;
+       struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
+       
+       if (skb->len < NLMSG_SPACE(0)) {
+               err = -EINVAL;
+               goto out;
+       }
+       nlh = (struct nlmsghdr *)skb->data;
+       
+       err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm);
+       if (err) {
+               /* Ignore */
+               if (err == -ENOENT)
+                       err = 0;
+               goto out;
+       }
+
+       err = socket_has_perm(current, sock, perm);
+out:
+       return err;
+}
+
+static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
+{
+       int err = 0;
+       
+       if (capable(CAP_NET_ADMIN))
+               cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
+       else
+               NETLINK_CB(skb).eff_cap = 0;
+       
+       if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS)
+               err = selinux_nlmsg_perm(sk, skb);
+       
+       return err;
+}
+
+static int selinux_netlink_recv(struct sk_buff *skb)
+{
+       if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
+               return -EPERM;
+       return 0;
+}
+
 #ifdef CONFIG_NETFILTER
 
 static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
@@ -3550,7 +3608,7 @@ static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
 
 static void selinux_msg_msg_free_security(struct msg_msg *msg)
 {
-       return msg_msg_free_security(msg);
+       msg_msg_free_security(msg);
 }
 
 /* message queue security operations */
@@ -3786,7 +3844,7 @@ static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd)
 }
 
 static int selinux_shm_shmat(struct shmid_kernel *shp,
-                            char *shmaddr, int shmflg)
+                            char __user *shmaddr, int shmflg)
 {
        u32 perms;
 
index eb3f4e1..c05e2ee 100644 (file)
@@ -29,6 +29,15 @@ static struct av_inherit av_inherit[] = {
    { SECCLASS_SEM, common_ipc_perm_to_string, 0x00000200UL },
    { SECCLASS_MSGQ, common_ipc_perm_to_string, 0x00000200UL },
    { SECCLASS_SHM, common_ipc_perm_to_string, 0x00000200UL },
+   { SECCLASS_NETLINK_ROUTE_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+   { SECCLASS_NETLINK_FIREWALL_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+   { SECCLASS_NETLINK_TCPDIAG_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+   { SECCLASS_NETLINK_NFLOG_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+   { SECCLASS_NETLINK_XFRM_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+   { SECCLASS_NETLINK_SELINUX_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+   { SECCLASS_NETLINK_AUDIT_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+   { SECCLASS_NETLINK_IP6FW_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+   { SECCLASS_NETLINK_DNRT_SOCKET, common_socket_perm_to_string, 0x00400000UL },
 };
 
 
index 6891745..e8e2a41 100644 (file)
@@ -30,6 +30,9 @@ static struct av_perm_to_string av_perm_to_string[] = {
    { SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto" },
    { SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn" },
    { SECCLASS_TCP_SOCKET, TCP_SOCKET__ACCEPTFROM, "acceptfrom" },
+   { SECCLASS_TCP_SOCKET, TCP_SOCKET__NODE_BIND, "node_bind" },
+   { SECCLASS_UDP_SOCKET, UDP_SOCKET__NODE_BIND, "node_bind" },
+   { SECCLASS_RAWIP_SOCKET, RAWIP_SOCKET__NODE_BIND, "node_bind" },
    { SECCLASS_NODE, NODE__TCP_RECV, "tcp_recv" },
    { SECCLASS_NODE, NODE__TCP_SEND, "tcp_send" },
    { SECCLASS_NODE, NODE__UDP_RECV, "udp_recv" },
@@ -46,9 +49,6 @@ static struct av_perm_to_string av_perm_to_string[] = {
    { SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO, "connectto" },
    { SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn" },
    { SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom" },
-   { SECCLASS_TCP_SOCKET, TCP_SOCKET__NODE_BIND, "node_bind" },
-   { SECCLASS_UDP_SOCKET, UDP_SOCKET__NODE_BIND, "node_bind" },
-   { SECCLASS_RAWIP_SOCKET, RAWIP_SOCKET__NODE_BIND, "node_bind" },
    { SECCLASS_PROCESS, PROCESS__FORK, "fork" },
    { SECCLASS_PROCESS, PROCESS__TRANSITION, "transition" },
    { SECCLASS_PROCESS, PROCESS__SIGCHLD, "sigchld" },
@@ -121,6 +121,104 @@ static struct av_perm_to_string av_perm_to_string[] = {
    { SECCLASS_PASSWD, PASSWD__PASSWD, "passwd" },
    { SECCLASS_PASSWD, PASSWD__CHFN, "chfn" },
    { SECCLASS_PASSWD, PASSWD__CHSH, "chsh" },
+   { SECCLASS_PASSWD, PASSWD__ROOTOK, "rootok" },
+   { SECCLASS_DRAWABLE, DRAWABLE__CREATE, "create" },
+   { SECCLASS_DRAWABLE, DRAWABLE__DESTROY, "destroy" },
+   { SECCLASS_DRAWABLE, DRAWABLE__DRAW, "draw" },
+   { SECCLASS_DRAWABLE, DRAWABLE__COPY, "copy" },
+   { SECCLASS_DRAWABLE, DRAWABLE__GETATTR, "getattr" },
+   { SECCLASS_GC, GC__CREATE, "create" },
+   { SECCLASS_GC, GC__FREE, "free" },
+   { SECCLASS_GC, GC__GETATTR, "getattr" },
+   { SECCLASS_GC, GC__SETATTR, "setattr" },
+   { SECCLASS_WINDOW, WINDOW__ADDCHILD, "addchild" },
+   { SECCLASS_WINDOW, WINDOW__CREATE, "create" },
+   { SECCLASS_WINDOW, WINDOW__DESTROY, "destroy" },
+   { SECCLASS_WINDOW, WINDOW__MAP, "map" },
+   { SECCLASS_WINDOW, WINDOW__UNMAP, "unmap" },
+   { SECCLASS_WINDOW, WINDOW__CHSTACK, "chstack" },
+   { SECCLASS_WINDOW, WINDOW__CHPROPLIST, "chproplist" },
+   { SECCLASS_WINDOW, WINDOW__CHPROP, "chprop" },
+   { SECCLASS_WINDOW, WINDOW__LISTPROP, "listprop" },
+   { SECCLASS_WINDOW, WINDOW__GETATTR, "getattr" },
+   { SECCLASS_WINDOW, WINDOW__SETATTR, "setattr" },
+   { SECCLASS_WINDOW, WINDOW__SETFOCUS, "setfocus" },
+   { SECCLASS_WINDOW, WINDOW__MOVE, "move" },
+   { SECCLASS_WINDOW, WINDOW__CHSELECTION, "chselection" },
+   { SECCLASS_WINDOW, WINDOW__CHPARENT, "chparent" },
+   { SECCLASS_WINDOW, WINDOW__CTRLLIFE, "ctrllife" },
+   { SECCLASS_WINDOW, WINDOW__ENUMERATE, "enumerate" },
+   { SECCLASS_WINDOW, WINDOW__TRANSPARENT, "transparent" },
+   { SECCLASS_WINDOW, WINDOW__MOUSEMOTION, "mousemotion" },
+   { SECCLASS_WINDOW, WINDOW__CLIENTCOMEVENT, "clientcomevent" },
+   { SECCLASS_WINDOW, WINDOW__INPUTEVENT, "inputevent" },
+   { SECCLASS_WINDOW, WINDOW__DRAWEVENT, "drawevent" },
+   { SECCLASS_WINDOW, WINDOW__WINDOWCHANGEEVENT, "windowchangeevent" },
+   { SECCLASS_WINDOW, WINDOW__WINDOWCHANGEREQUEST, "windowchangerequest" },
+   { SECCLASS_WINDOW, WINDOW__SERVERCHANGEEVENT, "serverchangeevent" },
+   { SECCLASS_WINDOW, WINDOW__EXTENSIONEVENT, "extensionevent" },
+   { SECCLASS_FONT, FONT__LOAD, "load" },
+   { SECCLASS_FONT, FONT__FREE, "free" },
+   { SECCLASS_FONT, FONT__GETATTR, "getattr" },
+   { SECCLASS_FONT, FONT__USE, "use" },
+   { SECCLASS_COLORMAP, COLORMAP__CREATE, "create" },
+   { SECCLASS_COLORMAP, COLORMAP__FREE, "free" },
+   { SECCLASS_COLORMAP, COLORMAP__INSTALL, "install" },
+   { SECCLASS_COLORMAP, COLORMAP__UNINSTALL, "uninstall" },
+   { SECCLASS_COLORMAP, COLORMAP__LIST, "list" },
+   { SECCLASS_COLORMAP, COLORMAP__READ, "read" },
+   { SECCLASS_COLORMAP, COLORMAP__STORE, "store" },
+   { SECCLASS_COLORMAP, COLORMAP__GETATTR, "getattr" },
+   { SECCLASS_COLORMAP, COLORMAP__SETATTR, "setattr" },
+   { SECCLASS_PROPERTY, PROPERTY__CREATE, "create" },
+   { SECCLASS_PROPERTY, PROPERTY__FREE, "free" },
+   { SECCLASS_PROPERTY, PROPERTY__READ, "read" },
+   { SECCLASS_PROPERTY, PROPERTY__WRITE, "write" },
+   { SECCLASS_CURSOR, CURSOR__CREATE, "create" },
+   { SECCLASS_CURSOR, CURSOR__CREATEGLYPH, "createglyph" },
+   { SECCLASS_CURSOR, CURSOR__FREE, "free" },
+   { SECCLASS_CURSOR, CURSOR__ASSIGN, "assign" },
+   { SECCLASS_CURSOR, CURSOR__SETATTR, "setattr" },
+   { SECCLASS_XCLIENT, XCLIENT__KILL, "kill" },
+   { SECCLASS_XINPUT, XINPUT__LOOKUP, "lookup" },
+   { SECCLASS_XINPUT, XINPUT__GETATTR, "getattr" },
+   { SECCLASS_XINPUT, XINPUT__SETATTR, "setattr" },
+   { SECCLASS_XINPUT, XINPUT__SETFOCUS, "setfocus" },
+   { SECCLASS_XINPUT, XINPUT__WARPPOINTER, "warppointer" },
+   { SECCLASS_XINPUT, XINPUT__ACTIVEGRAB, "activegrab" },
+   { SECCLASS_XINPUT, XINPUT__PASSIVEGRAB, "passivegrab" },
+   { SECCLASS_XINPUT, XINPUT__UNGRAB, "ungrab" },
+   { SECCLASS_XINPUT, XINPUT__BELL, "bell" },
+   { SECCLASS_XINPUT, XINPUT__MOUSEMOTION, "mousemotion" },
+   { SECCLASS_XINPUT, XINPUT__RELABELINPUT, "relabelinput" },
+   { SECCLASS_XSERVER, XSERVER__SCREENSAVER, "screensaver" },
+   { SECCLASS_XSERVER, XSERVER__GETHOSTLIST, "gethostlist" },
+   { SECCLASS_XSERVER, XSERVER__SETHOSTLIST, "sethostlist" },
+   { SECCLASS_XSERVER, XSERVER__GETFONTPATH, "getfontpath" },
+   { SECCLASS_XSERVER, XSERVER__SETFONTPATH, "setfontpath" },
+   { SECCLASS_XSERVER, XSERVER__GETATTR, "getattr" },
+   { SECCLASS_XSERVER, XSERVER__GRAB, "grab" },
+   { SECCLASS_XSERVER, XSERVER__UNGRAB, "ungrab" },
+   { SECCLASS_XEXTENSION, XEXTENSION__QUERY, "query" },
+   { SECCLASS_XEXTENSION, XEXTENSION__USE, "use" },
+   { SECCLASS_PAX, PAX__PAGEEXEC, "pageexec" },
+   { SECCLASS_PAX, PAX__EMUTRAMP, "emutramp" },
+   { SECCLASS_PAX, PAX__MPROTECT, "mprotect" },
+   { SECCLASS_PAX, PAX__RANDMMAP, "randmmap" },
+   { SECCLASS_PAX, PAX__RANDEXEC, "randexec" },
+   { SECCLASS_PAX, PAX__SEGMEXEC, "segmexec" },
+   { SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_READ, "nlmsg_read" },
+   { SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_WRITE, "nlmsg_write" },
+   { SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_READ, "nlmsg_read" },
+   { SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_WRITE, "nlmsg_write" },
+   { SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_READ, "nlmsg_read" },
+   { SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE, "nlmsg_write" },
+   { SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_READ, "nlmsg_read" },
+   { SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_WRITE, "nlmsg_write" },
+   { SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READ, "nlmsg_read" },
+   { SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE, "nlmsg_write" },
+   { SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_READ, "nlmsg_read" },
+   { SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_WRITE, "nlmsg_write" },
 };
 
 
index 4d77e0c..0a4c6e0 100644 (file)
 #define FILESYSTEM__QUOTAMOD                      0x00000100UL
 #define FILESYSTEM__QUOTAGET                      0x00000200UL
 
-#define DIR__EXECUTE                              0x00002000UL
-#define DIR__UNLINK                               0x00000400UL
+#define DIR__IOCTL                                0x00000001UL
+#define DIR__READ                                 0x00000002UL
+#define DIR__WRITE                                0x00000004UL
+#define DIR__CREATE                               0x00000008UL
+#define DIR__GETATTR                              0x00000010UL
 #define DIR__SETATTR                              0x00000020UL
-#define DIR__QUOTAON                              0x00008000UL
+#define DIR__LOCK                                 0x00000040UL
 #define DIR__RELABELFROM                          0x00000080UL
-#define DIR__LINK                                 0x00000800UL
-#define DIR__WRITE                                0x00000004UL
-#define DIR__IOCTL                                0x00000001UL
 #define DIR__RELABELTO                            0x00000100UL
-#define DIR__READ                                 0x00000002UL
-#define DIR__RENAME                               0x00001000UL
 #define DIR__APPEND                               0x00000200UL
-#define DIR__LOCK                                 0x00000040UL
+#define DIR__UNLINK                               0x00000400UL
+#define DIR__LINK                                 0x00000800UL
+#define DIR__RENAME                               0x00001000UL
+#define DIR__EXECUTE                              0x00002000UL
 #define DIR__SWAPON                               0x00004000UL
-#define DIR__GETATTR                              0x00000010UL
+#define DIR__QUOTAON                              0x00008000UL
 #define DIR__MOUNTON                              0x00010000UL
-#define DIR__CREATE                               0x00000008UL
 
 #define DIR__ADD_NAME                             0x00020000UL
 #define DIR__REMOVE_NAME                          0x00040000UL
 #define DIR__SEARCH                               0x00100000UL
 #define DIR__RMDIR                                0x00200000UL
 
-#define FILE__EXECUTE                             0x00002000UL
-#define FILE__UNLINK                              0x00000400UL
+#define FILE__IOCTL                               0x00000001UL
+#define FILE__READ                                0x00000002UL
+#define FILE__WRITE                               0x00000004UL
+#define FILE__CREATE                              0x00000008UL
+#define FILE__GETATTR                             0x00000010UL
 #define FILE__SETATTR                             0x00000020UL
-#define FILE__QUOTAON                             0x00008000UL
+#define FILE__LOCK                                0x00000040UL
 #define FILE__RELABELFROM                         0x00000080UL
-#define FILE__LINK                                0x00000800UL
-#define FILE__WRITE                               0x00000004UL
-#define FILE__IOCTL                               0x00000001UL
 #define FILE__RELABELTO                           0x00000100UL
-#define FILE__READ                                0x00000002UL
-#define FILE__RENAME                              0x00001000UL
 #define FILE__APPEND                              0x00000200UL
-#define FILE__LOCK                                0x00000040UL
+#define FILE__UNLINK                              0x00000400UL
+#define FILE__LINK                                0x00000800UL
+#define FILE__RENAME                              0x00001000UL
+#define FILE__EXECUTE                             0x00002000UL
 #define FILE__SWAPON                              0x00004000UL
-#define FILE__GETATTR                             0x00000010UL
+#define FILE__QUOTAON                             0x00008000UL
 #define FILE__MOUNTON                             0x00010000UL
-#define FILE__CREATE                              0x00000008UL
 
 #define FILE__EXECUTE_NO_TRANS                    0x00020000UL
 #define FILE__ENTRYPOINT                          0x00040000UL
 
-#define LNK_FILE__EXECUTE                         0x00002000UL
-#define LNK_FILE__UNLINK                          0x00000400UL
+#define LNK_FILE__IOCTL                           0x00000001UL
+#define LNK_FILE__READ                            0x00000002UL
+#define LNK_FILE__WRITE                           0x00000004UL
+#define LNK_FILE__CREATE                          0x00000008UL
+#define LNK_FILE__GETATTR                         0x00000010UL
 #define LNK_FILE__SETATTR                         0x00000020UL
-#define LNK_FILE__QUOTAON                         0x00008000UL
+#define LNK_FILE__LOCK                            0x00000040UL
 #define LNK_FILE__RELABELFROM                     0x00000080UL
-#define LNK_FILE__LINK                            0x00000800UL
-#define LNK_FILE__WRITE                           0x00000004UL
-#define LNK_FILE__IOCTL                           0x00000001UL
 #define LNK_FILE__RELABELTO                       0x00000100UL
-#define LNK_FILE__READ                            0x00000002UL
-#define LNK_FILE__RENAME                          0x00001000UL
 #define LNK_FILE__APPEND                          0x00000200UL
-#define LNK_FILE__LOCK                            0x00000040UL
+#define LNK_FILE__UNLINK                          0x00000400UL
+#define LNK_FILE__LINK                            0x00000800UL
+#define LNK_FILE__RENAME                          0x00001000UL
+#define LNK_FILE__EXECUTE                         0x00002000UL
 #define LNK_FILE__SWAPON                          0x00004000UL
-#define LNK_FILE__GETATTR                         0x00000010UL
+#define LNK_FILE__QUOTAON                         0x00008000UL
 #define LNK_FILE__MOUNTON                         0x00010000UL
-#define LNK_FILE__CREATE                          0x00000008UL
 
-#define CHR_FILE__EXECUTE                         0x00002000UL
-#define CHR_FILE__UNLINK                          0x00000400UL
+#define CHR_FILE__IOCTL                           0x00000001UL
+#define CHR_FILE__READ                            0x00000002UL
+#define CHR_FILE__WRITE                           0x00000004UL
+#define CHR_FILE__CREATE                          0x00000008UL
+#define CHR_FILE__GETATTR                         0x00000010UL
 #define CHR_FILE__SETATTR                         0x00000020UL
-#define CHR_FILE__QUOTAON                         0x00008000UL
+#define CHR_FILE__LOCK                            0x00000040UL
 #define CHR_FILE__RELABELFROM                     0x00000080UL
-#define CHR_FILE__LINK                            0x00000800UL
-#define CHR_FILE__WRITE                           0x00000004UL
-#define CHR_FILE__IOCTL                           0x00000001UL
 #define CHR_FILE__RELABELTO                       0x00000100UL
-#define CHR_FILE__READ                            0x00000002UL
-#define CHR_FILE__RENAME                          0x00001000UL
 #define CHR_FILE__APPEND                          0x00000200UL
-#define CHR_FILE__LOCK                            0x00000040UL
+#define CHR_FILE__UNLINK                          0x00000400UL
+#define CHR_FILE__LINK                            0x00000800UL
+#define CHR_FILE__RENAME                          0x00001000UL
+#define CHR_FILE__EXECUTE                         0x00002000UL
 #define CHR_FILE__SWAPON                          0x00004000UL
-#define CHR_FILE__GETATTR                         0x00000010UL
+#define CHR_FILE__QUOTAON                         0x00008000UL
 #define CHR_FILE__MOUNTON                         0x00010000UL
-#define CHR_FILE__CREATE                          0x00000008UL
 
-#define BLK_FILE__EXECUTE                         0x00002000UL
-#define BLK_FILE__UNLINK                          0x00000400UL
+#define BLK_FILE__IOCTL                           0x00000001UL
+#define BLK_FILE__READ                            0x00000002UL
+#define BLK_FILE__WRITE                           0x00000004UL
+#define BLK_FILE__CREATE                          0x00000008UL
+#define BLK_FILE__GETATTR                         0x00000010UL
 #define BLK_FILE__SETATTR                         0x00000020UL
-#define BLK_FILE__QUOTAON                         0x00008000UL
+#define BLK_FILE__LOCK                            0x00000040UL
 #define BLK_FILE__RELABELFROM                     0x00000080UL
-#define BLK_FILE__LINK                            0x00000800UL
-#define BLK_FILE__WRITE                           0x00000004UL
-#define BLK_FILE__IOCTL                           0x00000001UL
 #define BLK_FILE__RELABELTO                       0x00000100UL
-#define BLK_FILE__READ                            0x00000002UL
-#define BLK_FILE__RENAME                          0x00001000UL
 #define BLK_FILE__APPEND                          0x00000200UL
-#define BLK_FILE__LOCK                            0x00000040UL
+#define BLK_FILE__UNLINK                          0x00000400UL
+#define BLK_FILE__LINK                            0x00000800UL
+#define BLK_FILE__RENAME                          0x00001000UL
+#define BLK_FILE__EXECUTE                         0x00002000UL
 #define BLK_FILE__SWAPON                          0x00004000UL
-#define BLK_FILE__GETATTR                         0x00000010UL
+#define BLK_FILE__QUOTAON                         0x00008000UL
 #define BLK_FILE__MOUNTON                         0x00010000UL
-#define BLK_FILE__CREATE                          0x00000008UL
 
-#define SOCK_FILE__EXECUTE                        0x00002000UL
-#define SOCK_FILE__UNLINK                         0x00000400UL
+#define SOCK_FILE__IOCTL                          0x00000001UL
+#define SOCK_FILE__READ                           0x00000002UL
+#define SOCK_FILE__WRITE                          0x00000004UL
+#define SOCK_FILE__CREATE                         0x00000008UL
+#define SOCK_FILE__GETATTR                        0x00000010UL
 #define SOCK_FILE__SETATTR                        0x00000020UL
-#define SOCK_FILE__QUOTAON                        0x00008000UL
+#define SOCK_FILE__LOCK                           0x00000040UL
 #define SOCK_FILE__RELABELFROM                    0x00000080UL
-#define SOCK_FILE__LINK                           0x00000800UL
-#define SOCK_FILE__WRITE                          0x00000004UL
-#define SOCK_FILE__IOCTL                          0x00000001UL
 #define SOCK_FILE__RELABELTO                      0x00000100UL
-#define SOCK_FILE__READ                           0x00000002UL
-#define SOCK_FILE__RENAME                         0x00001000UL
 #define SOCK_FILE__APPEND                         0x00000200UL
-#define SOCK_FILE__LOCK                           0x00000040UL
+#define SOCK_FILE__UNLINK                         0x00000400UL
+#define SOCK_FILE__LINK                           0x00000800UL
+#define SOCK_FILE__RENAME                         0x00001000UL
+#define SOCK_FILE__EXECUTE                        0x00002000UL
 #define SOCK_FILE__SWAPON                         0x00004000UL
-#define SOCK_FILE__GETATTR                        0x00000010UL
+#define SOCK_FILE__QUOTAON                        0x00008000UL
 #define SOCK_FILE__MOUNTON                        0x00010000UL
-#define SOCK_FILE__CREATE                         0x00000008UL
 
-#define FIFO_FILE__EXECUTE                        0x00002000UL
-#define FIFO_FILE__UNLINK                         0x00000400UL
+#define FIFO_FILE__IOCTL                          0x00000001UL
+#define FIFO_FILE__READ                           0x00000002UL
+#define FIFO_FILE__WRITE                          0x00000004UL
+#define FIFO_FILE__CREATE                         0x00000008UL
+#define FIFO_FILE__GETATTR                        0x00000010UL
 #define FIFO_FILE__SETATTR                        0x00000020UL
-#define FIFO_FILE__QUOTAON                        0x00008000UL
+#define FIFO_FILE__LOCK                           0x00000040UL
 #define FIFO_FILE__RELABELFROM                    0x00000080UL
-#define FIFO_FILE__LINK                           0x00000800UL
-#define FIFO_FILE__WRITE                          0x00000004UL
-#define FIFO_FILE__IOCTL                          0x00000001UL
 #define FIFO_FILE__RELABELTO                      0x00000100UL
-#define FIFO_FILE__READ                           0x00000002UL
-#define FIFO_FILE__RENAME                         0x00001000UL
 #define FIFO_FILE__APPEND                         0x00000200UL
-#define FIFO_FILE__LOCK                           0x00000040UL
+#define FIFO_FILE__UNLINK                         0x00000400UL
+#define FIFO_FILE__LINK                           0x00000800UL
+#define FIFO_FILE__RENAME                         0x00001000UL
+#define FIFO_FILE__EXECUTE                        0x00002000UL
 #define FIFO_FILE__SWAPON                         0x00004000UL
-#define FIFO_FILE__GETATTR                        0x00000010UL
+#define FIFO_FILE__QUOTAON                        0x00008000UL
 #define FIFO_FILE__MOUNTON                        0x00010000UL
-#define FIFO_FILE__CREATE                         0x00000008UL
 
 #define FD__USE                                   0x00000001UL
 
-#define SOCKET__RELABELTO                         0x00000100UL
-#define SOCKET__RECV_MSG                          0x00080000UL
+#define SOCKET__IOCTL                             0x00000001UL
+#define SOCKET__READ                              0x00000002UL
+#define SOCKET__WRITE                             0x00000004UL
+#define SOCKET__CREATE                            0x00000008UL
+#define SOCKET__GETATTR                           0x00000010UL
+#define SOCKET__SETATTR                           0x00000020UL
+#define SOCKET__LOCK                              0x00000040UL
 #define SOCKET__RELABELFROM                       0x00000080UL
-#define SOCKET__SETOPT                            0x00008000UL
+#define SOCKET__RELABELTO                         0x00000100UL
 #define SOCKET__APPEND                            0x00000200UL
-#define SOCKET__SETATTR                           0x00000020UL
-#define SOCKET__SENDTO                            0x00040000UL
-#define SOCKET__GETOPT                            0x00004000UL
-#define SOCKET__READ                              0x00000002UL
-#define SOCKET__SHUTDOWN                          0x00010000UL
-#define SOCKET__LISTEN                            0x00001000UL
 #define SOCKET__BIND                              0x00000400UL
-#define SOCKET__WRITE                             0x00000004UL
-#define SOCKET__ACCEPT                            0x00002000UL
 #define SOCKET__CONNECT                           0x00000800UL
-#define SOCKET__LOCK                              0x00000040UL
-#define SOCKET__IOCTL                             0x00000001UL
-#define SOCKET__CREATE                            0x00000008UL
-#define SOCKET__NAME_BIND                         0x00200000UL
-#define SOCKET__SEND_MSG                          0x00100000UL
+#define SOCKET__LISTEN                            0x00001000UL
+#define SOCKET__ACCEPT                            0x00002000UL
+#define SOCKET__GETOPT                            0x00004000UL
+#define SOCKET__SETOPT                            0x00008000UL
+#define SOCKET__SHUTDOWN                          0x00010000UL
 #define SOCKET__RECVFROM                          0x00020000UL
-#define SOCKET__GETATTR                           0x00000010UL
+#define SOCKET__SENDTO                            0x00040000UL
+#define SOCKET__RECV_MSG                          0x00080000UL
+#define SOCKET__SEND_MSG                          0x00100000UL
+#define SOCKET__NAME_BIND                         0x00200000UL
 
-#define TCP_SOCKET__RELABELTO                     0x00000100UL
-#define TCP_SOCKET__RECV_MSG                      0x00080000UL
+#define TCP_SOCKET__IOCTL                         0x00000001UL
+#define TCP_SOCKET__READ                          0x00000002UL
+#define TCP_SOCKET__WRITE                         0x00000004UL
+#define TCP_SOCKET__CREATE                        0x00000008UL
+#define TCP_SOCKET__GETATTR                       0x00000010UL
+#define TCP_SOCKET__SETATTR                       0x00000020UL
+#define TCP_SOCKET__LOCK                          0x00000040UL
 #define TCP_SOCKET__RELABELFROM                   0x00000080UL
-#define TCP_SOCKET__SETOPT                        0x00008000UL
+#define TCP_SOCKET__RELABELTO                     0x00000100UL
 #define TCP_SOCKET__APPEND                        0x00000200UL
-#define TCP_SOCKET__SETATTR                       0x00000020UL
-#define TCP_SOCKET__SENDTO                        0x00040000UL
-#define TCP_SOCKET__GETOPT                        0x00004000UL
-#define TCP_SOCKET__READ                          0x00000002UL
-#define TCP_SOCKET__SHUTDOWN                      0x00010000UL
-#define TCP_SOCKET__LISTEN                        0x00001000UL
 #define TCP_SOCKET__BIND                          0x00000400UL
-#define TCP_SOCKET__WRITE                         0x00000004UL
-#define TCP_SOCKET__ACCEPT                        0x00002000UL
 #define TCP_SOCKET__CONNECT                       0x00000800UL
-#define TCP_SOCKET__LOCK                          0x00000040UL
-#define TCP_SOCKET__IOCTL                         0x00000001UL
-#define TCP_SOCKET__CREATE                        0x00000008UL
-#define TCP_SOCKET__NAME_BIND                     0x00200000UL
-#define TCP_SOCKET__SEND_MSG                      0x00100000UL
+#define TCP_SOCKET__LISTEN                        0x00001000UL
+#define TCP_SOCKET__ACCEPT                        0x00002000UL
+#define TCP_SOCKET__GETOPT                        0x00004000UL
+#define TCP_SOCKET__SETOPT                        0x00008000UL
+#define TCP_SOCKET__SHUTDOWN                      0x00010000UL
 #define TCP_SOCKET__RECVFROM                      0x00020000UL
-#define TCP_SOCKET__GETATTR                       0x00000010UL
+#define TCP_SOCKET__SENDTO                        0x00040000UL
+#define TCP_SOCKET__RECV_MSG                      0x00080000UL
+#define TCP_SOCKET__SEND_MSG                      0x00100000UL
+#define TCP_SOCKET__NAME_BIND                     0x00200000UL
 
 #define TCP_SOCKET__CONNECTTO                     0x00400000UL
 #define TCP_SOCKET__NEWCONN                       0x00800000UL
 #define TCP_SOCKET__ACCEPTFROM                    0x01000000UL
 #define TCP_SOCKET__NODE_BIND                     0x02000000UL
 
-#define UDP_SOCKET__RELABELTO                     0x00000100UL
-#define UDP_SOCKET__RECV_MSG                      0x00080000UL
+#define UDP_SOCKET__IOCTL                         0x00000001UL
+#define UDP_SOCKET__READ                          0x00000002UL
+#define UDP_SOCKET__WRITE                         0x00000004UL
+#define UDP_SOCKET__CREATE                        0x00000008UL
+#define UDP_SOCKET__GETATTR                       0x00000010UL
+#define UDP_SOCKET__SETATTR                       0x00000020UL
+#define UDP_SOCKET__LOCK                          0x00000040UL
 #define UDP_SOCKET__RELABELFROM                   0x00000080UL
-#define UDP_SOCKET__SETOPT                        0x00008000UL
+#define UDP_SOCKET__RELABELTO                     0x00000100UL
 #define UDP_SOCKET__APPEND                        0x00000200UL
-#define UDP_SOCKET__SETATTR                       0x00000020UL
-#define UDP_SOCKET__SENDTO                        0x00040000UL
-#define UDP_SOCKET__GETOPT                        0x00004000UL
-#define UDP_SOCKET__READ                          0x00000002UL
-#define UDP_SOCKET__SHUTDOWN                      0x00010000UL
-#define UDP_SOCKET__LISTEN                        0x00001000UL
 #define UDP_SOCKET__BIND                          0x00000400UL
-#define UDP_SOCKET__WRITE                         0x00000004UL
-#define UDP_SOCKET__ACCEPT                        0x00002000UL
 #define UDP_SOCKET__CONNECT                       0x00000800UL
-#define UDP_SOCKET__LOCK                          0x00000040UL
-#define UDP_SOCKET__IOCTL                         0x00000001UL
-#define UDP_SOCKET__CREATE                        0x00000008UL
-#define UDP_SOCKET__NAME_BIND                     0x00200000UL
-#define UDP_SOCKET__SEND_MSG                      0x00100000UL
+#define UDP_SOCKET__LISTEN                        0x00001000UL
+#define UDP_SOCKET__ACCEPT                        0x00002000UL
+#define UDP_SOCKET__GETOPT                        0x00004000UL
+#define UDP_SOCKET__SETOPT                        0x00008000UL
+#define UDP_SOCKET__SHUTDOWN                      0x00010000UL
 #define UDP_SOCKET__RECVFROM                      0x00020000UL
-#define UDP_SOCKET__GETATTR                       0x00000010UL
+#define UDP_SOCKET__SENDTO                        0x00040000UL
+#define UDP_SOCKET__RECV_MSG                      0x00080000UL
+#define UDP_SOCKET__SEND_MSG                      0x00100000UL
+#define UDP_SOCKET__NAME_BIND                     0x00200000UL
+
 #define UDP_SOCKET__NODE_BIND                     0x00400000UL
 
-#define RAWIP_SOCKET__RELABELTO                   0x00000100UL
-#define RAWIP_SOCKET__RECV_MSG                    0x00080000UL
+#define RAWIP_SOCKET__IOCTL                       0x00000001UL
+#define RAWIP_SOCKET__READ                        0x00000002UL
+#define RAWIP_SOCKET__WRITE                       0x00000004UL
+#define RAWIP_SOCKET__CREATE                      0x00000008UL
+#define RAWIP_SOCKET__GETATTR                     0x00000010UL
+#define RAWIP_SOCKET__SETATTR                     0x00000020UL
+#define RAWIP_SOCKET__LOCK                        0x00000040UL
 #define RAWIP_SOCKET__RELABELFROM                 0x00000080UL
-#define RAWIP_SOCKET__SETOPT                      0x00008000UL
+#define RAWIP_SOCKET__RELABELTO                   0x00000100UL
 #define RAWIP_SOCKET__APPEND                      0x00000200UL
-#define RAWIP_SOCKET__SETATTR                     0x00000020UL
-#define RAWIP_SOCKET__SENDTO                      0x00040000UL
-#define RAWIP_SOCKET__GETOPT                      0x00004000UL
-#define RAWIP_SOCKET__READ                        0x00000002UL
-#define RAWIP_SOCKET__SHUTDOWN                    0x00010000UL
-#define RAWIP_SOCKET__LISTEN                      0x00001000UL
 #define RAWIP_SOCKET__BIND                        0x00000400UL
-#define RAWIP_SOCKET__WRITE                       0x00000004UL
-#define RAWIP_SOCKET__ACCEPT                      0x00002000UL
 #define RAWIP_SOCKET__CONNECT                     0x00000800UL
-#define RAWIP_SOCKET__LOCK                        0x00000040UL
-#define RAWIP_SOCKET__IOCTL                       0x00000001UL
-#define RAWIP_SOCKET__CREATE                      0x00000008UL
-#define RAWIP_SOCKET__NAME_BIND                   0x00200000UL
-#define RAWIP_SOCKET__SEND_MSG                    0x00100000UL
+#define RAWIP_SOCKET__LISTEN                      0x00001000UL
+#define RAWIP_SOCKET__ACCEPT                      0x00002000UL
+#define RAWIP_SOCKET__GETOPT                      0x00004000UL
+#define RAWIP_SOCKET__SETOPT                      0x00008000UL
+#define RAWIP_SOCKET__SHUTDOWN                    0x00010000UL
 #define RAWIP_SOCKET__RECVFROM                    0x00020000UL
-#define RAWIP_SOCKET__GETATTR                     0x00000010UL
+#define RAWIP_SOCKET__SENDTO                      0x00040000UL
+#define RAWIP_SOCKET__RECV_MSG                    0x00080000UL
+#define RAWIP_SOCKET__SEND_MSG                    0x00100000UL
+#define RAWIP_SOCKET__NAME_BIND                   0x00200000UL
+
 #define RAWIP_SOCKET__NODE_BIND                   0x00400000UL
 
 #define NODE__TCP_RECV                            0x00000001UL
 #define NETIF__RAWIP_RECV                         0x00000010UL
 #define NETIF__RAWIP_SEND                         0x00000020UL
 
-#define NETLINK_SOCKET__RELABELTO                 0x00000100UL
-#define NETLINK_SOCKET__RECV_MSG                  0x00080000UL
+#define NETLINK_SOCKET__IOCTL                     0x00000001UL
+#define NETLINK_SOCKET__READ                      0x00000002UL
+#define NETLINK_SOCKET__WRITE                     0x00000004UL
+#define NETLINK_SOCKET__CREATE                    0x00000008UL
+#define NETLINK_SOCKET__GETATTR                   0x00000010UL
+#define NETLINK_SOCKET__SETATTR                   0x00000020UL
+#define NETLINK_SOCKET__LOCK                      0x00000040UL
 #define NETLINK_SOCKET__RELABELFROM               0x00000080UL
-#define NETLINK_SOCKET__SETOPT                    0x00008000UL
+#define NETLINK_SOCKET__RELABELTO                 0x00000100UL
 #define NETLINK_SOCKET__APPEND                    0x00000200UL
-#define NETLINK_SOCKET__SETATTR                   0x00000020UL
-#define NETLINK_SOCKET__SENDTO                    0x00040000UL
-#define NETLINK_SOCKET__GETOPT                    0x00004000UL
-#define NETLINK_SOCKET__READ                      0x00000002UL
-#define NETLINK_SOCKET__SHUTDOWN                  0x00010000UL
-#define NETLINK_SOCKET__LISTEN                    0x00001000UL
 #define NETLINK_SOCKET__BIND                      0x00000400UL
-#define NETLINK_SOCKET__WRITE                     0x00000004UL
-#define NETLINK_SOCKET__ACCEPT                    0x00002000UL
 #define NETLINK_SOCKET__CONNECT                   0x00000800UL
-#define NETLINK_SOCKET__LOCK                      0x00000040UL
-#define NETLINK_SOCKET__IOCTL                     0x00000001UL
-#define NETLINK_SOCKET__CREATE                    0x00000008UL
-#define NETLINK_SOCKET__NAME_BIND                 0x00200000UL
-#define NETLINK_SOCKET__SEND_MSG                  0x00100000UL
+#define NETLINK_SOCKET__LISTEN                    0x00001000UL
+#define NETLINK_SOCKET__ACCEPT                    0x00002000UL
+#define NETLINK_SOCKET__GETOPT                    0x00004000UL
+#define NETLINK_SOCKET__SETOPT                    0x00008000UL
+#define NETLINK_SOCKET__SHUTDOWN                  0x00010000UL
 #define NETLINK_SOCKET__RECVFROM                  0x00020000UL
-#define NETLINK_SOCKET__GETATTR                   0x00000010UL
+#define NETLINK_SOCKET__SENDTO                    0x00040000UL
+#define NETLINK_SOCKET__RECV_MSG                  0x00080000UL
+#define NETLINK_SOCKET__SEND_MSG                  0x00100000UL
+#define NETLINK_SOCKET__NAME_BIND                 0x00200000UL
 
-#define PACKET_SOCKET__RELABELTO                  0x00000100UL
-#define PACKET_SOCKET__RECV_MSG                   0x00080000UL
+#define PACKET_SOCKET__IOCTL                      0x00000001UL
+#define PACKET_SOCKET__READ                       0x00000002UL
+#define PACKET_SOCKET__WRITE                      0x00000004UL
+#define PACKET_SOCKET__CREATE                     0x00000008UL
+#define PACKET_SOCKET__GETATTR                    0x00000010UL
+#define PACKET_SOCKET__SETATTR                    0x00000020UL
+#define PACKET_SOCKET__LOCK                       0x00000040UL
 #define PACKET_SOCKET__RELABELFROM                0x00000080UL
-#define PACKET_SOCKET__SETOPT                     0x00008000UL
+#define PACKET_SOCKET__RELABELTO                  0x00000100UL
 #define PACKET_SOCKET__APPEND                     0x00000200UL
-#define PACKET_SOCKET__SETATTR                    0x00000020UL
-#define PACKET_SOCKET__SENDTO                     0x00040000UL
-#define PACKET_SOCKET__GETOPT                     0x00004000UL
-#define PACKET_SOCKET__READ                       0x00000002UL
-#define PACKET_SOCKET__SHUTDOWN                   0x00010000UL
-#define PACKET_SOCKET__LISTEN                     0x00001000UL
 #define PACKET_SOCKET__BIND                       0x00000400UL
-#define PACKET_SOCKET__WRITE                      0x00000004UL
-#define PACKET_SOCKET__ACCEPT                     0x00002000UL
 #define PACKET_SOCKET__CONNECT                    0x00000800UL
-#define PACKET_SOCKET__LOCK                       0x00000040UL
-#define PACKET_SOCKET__IOCTL                      0x00000001UL
-#define PACKET_SOCKET__CREATE                     0x00000008UL
-#define PACKET_SOCKET__NAME_BIND                  0x00200000UL
-#define PACKET_SOCKET__SEND_MSG                   0x00100000UL
+#define PACKET_SOCKET__LISTEN                     0x00001000UL
+#define PACKET_SOCKET__ACCEPT                     0x00002000UL
+#define PACKET_SOCKET__GETOPT                     0x00004000UL
+#define PACKET_SOCKET__SETOPT                     0x00008000UL
+#define PACKET_SOCKET__SHUTDOWN                   0x00010000UL
 #define PACKET_SOCKET__RECVFROM                   0x00020000UL
-#define PACKET_SOCKET__GETATTR                    0x00000010UL
+#define PACKET_SOCKET__SENDTO                     0x00040000UL
+#define PACKET_SOCKET__RECV_MSG                   0x00080000UL
+#define PACKET_SOCKET__SEND_MSG                   0x00100000UL
+#define PACKET_SOCKET__NAME_BIND                  0x00200000UL
 
-#define KEY_SOCKET__RELABELTO                     0x00000100UL
-#define KEY_SOCKET__RECV_MSG                      0x00080000UL
+#define KEY_SOCKET__IOCTL                         0x00000001UL
+#define KEY_SOCKET__READ                          0x00000002UL
+#define KEY_SOCKET__WRITE                         0x00000004UL
+#define KEY_SOCKET__CREATE                        0x00000008UL
+#define KEY_SOCKET__GETATTR                       0x00000010UL
+#define KEY_SOCKET__SETATTR                       0x00000020UL
+#define KEY_SOCKET__LOCK                          0x00000040UL
 #define KEY_SOCKET__RELABELFROM                   0x00000080UL
-#define KEY_SOCKET__SETOPT                        0x00008000UL
+#define KEY_SOCKET__RELABELTO                     0x00000100UL
 #define KEY_SOCKET__APPEND                        0x00000200UL
-#define KEY_SOCKET__SETATTR                       0x00000020UL
-#define KEY_SOCKET__SENDTO                        0x00040000UL
-#define KEY_SOCKET__GETOPT                        0x00004000UL
-#define KEY_SOCKET__READ                          0x00000002UL
-#define KEY_SOCKET__SHUTDOWN                      0x00010000UL
-#define KEY_SOCKET__LISTEN                        0x00001000UL
 #define KEY_SOCKET__BIND                          0x00000400UL
-#define KEY_SOCKET__WRITE                         0x00000004UL
-#define KEY_SOCKET__ACCEPT                        0x00002000UL
 #define KEY_SOCKET__CONNECT                       0x00000800UL
-#define KEY_SOCKET__LOCK                          0x00000040UL
-#define KEY_SOCKET__IOCTL                         0x00000001UL
-#define KEY_SOCKET__CREATE                        0x00000008UL
-#define KEY_SOCKET__NAME_BIND                     0x00200000UL
-#define KEY_SOCKET__SEND_MSG                      0x00100000UL
+#define KEY_SOCKET__LISTEN                        0x00001000UL
+#define KEY_SOCKET__ACCEPT                        0x00002000UL
+#define KEY_SOCKET__GETOPT                        0x00004000UL
+#define KEY_SOCKET__SETOPT                        0x00008000UL
+#define KEY_SOCKET__SHUTDOWN                      0x00010000UL
 #define KEY_SOCKET__RECVFROM                      0x00020000UL
-#define KEY_SOCKET__GETATTR                       0x00000010UL
+#define KEY_SOCKET__SENDTO                        0x00040000UL
+#define KEY_SOCKET__RECV_MSG                      0x00080000UL
+#define KEY_SOCKET__SEND_MSG                      0x00100000UL
+#define KEY_SOCKET__NAME_BIND                     0x00200000UL
 
-#define UNIX_STREAM_SOCKET__RELABELTO             0x00000100UL
-#define UNIX_STREAM_SOCKET__RECV_MSG              0x00080000UL
+#define UNIX_STREAM_SOCKET__IOCTL                 0x00000001UL
+#define UNIX_STREAM_SOCKET__READ                  0x00000002UL
+#define UNIX_STREAM_SOCKET__WRITE                 0x00000004UL
+#define UNIX_STREAM_SOCKET__CREATE                0x00000008UL
+#define UNIX_STREAM_SOCKET__GETATTR               0x00000010UL
+#define UNIX_STREAM_SOCKET__SETATTR               0x00000020UL
+#define UNIX_STREAM_SOCKET__LOCK                  0x00000040UL
 #define UNIX_STREAM_SOCKET__RELABELFROM           0x00000080UL
-#define UNIX_STREAM_SOCKET__SETOPT                0x00008000UL
+#define UNIX_STREAM_SOCKET__RELABELTO             0x00000100UL
 #define UNIX_STREAM_SOCKET__APPEND                0x00000200UL
-#define UNIX_STREAM_SOCKET__SETATTR               0x00000020UL
-#define UNIX_STREAM_SOCKET__SENDTO                0x00040000UL
-#define UNIX_STREAM_SOCKET__GETOPT                0x00004000UL
-#define UNIX_STREAM_SOCKET__READ                  0x00000002UL
-#define UNIX_STREAM_SOCKET__SHUTDOWN              0x00010000UL
-#define UNIX_STREAM_SOCKET__LISTEN                0x00001000UL
 #define UNIX_STREAM_SOCKET__BIND                  0x00000400UL
-#define UNIX_STREAM_SOCKET__WRITE                 0x00000004UL
-#define UNIX_STREAM_SOCKET__ACCEPT                0x00002000UL
 #define UNIX_STREAM_SOCKET__CONNECT               0x00000800UL
-#define UNIX_STREAM_SOCKET__LOCK                  0x00000040UL
-#define UNIX_STREAM_SOCKET__IOCTL                 0x00000001UL
-#define UNIX_STREAM_SOCKET__CREATE                0x00000008UL
-#define UNIX_STREAM_SOCKET__NAME_BIND             0x00200000UL
-#define UNIX_STREAM_SOCKET__SEND_MSG              0x00100000UL
+#define UNIX_STREAM_SOCKET__LISTEN                0x00001000UL
+#define UNIX_STREAM_SOCKET__ACCEPT                0x00002000UL
+#define UNIX_STREAM_SOCKET__GETOPT                0x00004000UL
+#define UNIX_STREAM_SOCKET__SETOPT                0x00008000UL
+#define UNIX_STREAM_SOCKET__SHUTDOWN              0x00010000UL
 #define UNIX_STREAM_SOCKET__RECVFROM              0x00020000UL
-#define UNIX_STREAM_SOCKET__GETATTR               0x00000010UL
+#define UNIX_STREAM_SOCKET__SENDTO                0x00040000UL
+#define UNIX_STREAM_SOCKET__RECV_MSG              0x00080000UL
+#define UNIX_STREAM_SOCKET__SEND_MSG              0x00100000UL
+#define UNIX_STREAM_SOCKET__NAME_BIND             0x00200000UL
 
 #define UNIX_STREAM_SOCKET__CONNECTTO             0x00400000UL
 #define UNIX_STREAM_SOCKET__NEWCONN               0x00800000UL
 #define UNIX_STREAM_SOCKET__ACCEPTFROM            0x01000000UL
 
-#define UNIX_DGRAM_SOCKET__RELABELTO              0x00000100UL
-#define UNIX_DGRAM_SOCKET__RECV_MSG               0x00080000UL
+#define UNIX_DGRAM_SOCKET__IOCTL                  0x00000001UL
+#define UNIX_DGRAM_SOCKET__READ                   0x00000002UL
+#define UNIX_DGRAM_SOCKET__WRITE                  0x00000004UL
+#define UNIX_DGRAM_SOCKET__CREATE                 0x00000008UL
+#define UNIX_DGRAM_SOCKET__GETATTR                0x00000010UL
+#define UNIX_DGRAM_SOCKET__SETATTR                0x00000020UL
+#define UNIX_DGRAM_SOCKET__LOCK                   0x00000040UL
 #define UNIX_DGRAM_SOCKET__RELABELFROM            0x00000080UL
-#define UNIX_DGRAM_SOCKET__SETOPT                 0x00008000UL
+#define UNIX_DGRAM_SOCKET__RELABELTO              0x00000100UL
 #define UNIX_DGRAM_SOCKET__APPEND                 0x00000200UL
-#define UNIX_DGRAM_SOCKET__SETATTR                0x00000020UL
-#define UNIX_DGRAM_SOCKET__SENDTO                 0x00040000UL
-#define UNIX_DGRAM_SOCKET__GETOPT                 0x00004000UL
-#define UNIX_DGRAM_SOCKET__READ                   0x00000002UL
-#define UNIX_DGRAM_SOCKET__SHUTDOWN               0x00010000UL
-#define UNIX_DGRAM_SOCKET__LISTEN                 0x00001000UL
 #define UNIX_DGRAM_SOCKET__BIND                   0x00000400UL
-#define UNIX_DGRAM_SOCKET__WRITE                  0x00000004UL
-#define UNIX_DGRAM_SOCKET__ACCEPT                 0x00002000UL
 #define UNIX_DGRAM_SOCKET__CONNECT                0x00000800UL
-#define UNIX_DGRAM_SOCKET__LOCK                   0x00000040UL
-#define UNIX_DGRAM_SOCKET__IOCTL                  0x00000001UL
-#define UNIX_DGRAM_SOCKET__CREATE                 0x00000008UL
-#define UNIX_DGRAM_SOCKET__NAME_BIND              0x00200000UL
-#define UNIX_DGRAM_SOCKET__SEND_MSG               0x00100000UL
+#define UNIX_DGRAM_SOCKET__LISTEN                 0x00001000UL
+#define UNIX_DGRAM_SOCKET__ACCEPT                 0x00002000UL
+#define UNIX_DGRAM_SOCKET__GETOPT                 0x00004000UL
+#define UNIX_DGRAM_SOCKET__SETOPT                 0x00008000UL
+#define UNIX_DGRAM_SOCKET__SHUTDOWN               0x00010000UL
 #define UNIX_DGRAM_SOCKET__RECVFROM               0x00020000UL
-#define UNIX_DGRAM_SOCKET__GETATTR                0x00000010UL
+#define UNIX_DGRAM_SOCKET__SENDTO                 0x00040000UL
+#define UNIX_DGRAM_SOCKET__RECV_MSG               0x00080000UL
+#define UNIX_DGRAM_SOCKET__SEND_MSG               0x00100000UL
+#define UNIX_DGRAM_SOCKET__NAME_BIND              0x00200000UL
 
 #define PROCESS__FORK                             0x00000001UL
 #define PROCESS__TRANSITION                       0x00000002UL
 #define PROCESS__SETRLIMIT                        0x00200000UL
 #define PROCESS__RLIMITINH                        0x00400000UL
 
+#define IPC__CREATE                               0x00000001UL
+#define IPC__DESTROY                              0x00000002UL
+#define IPC__GETATTR                              0x00000004UL
 #define IPC__SETATTR                              0x00000008UL
 #define IPC__READ                                 0x00000010UL
+#define IPC__WRITE                                0x00000020UL
 #define IPC__ASSOCIATE                            0x00000040UL
-#define IPC__DESTROY                              0x00000002UL
-#define IPC__UNIX_WRITE                           0x00000100UL
-#define IPC__CREATE                               0x00000001UL
 #define IPC__UNIX_READ                            0x00000080UL
-#define IPC__GETATTR                              0x00000004UL
-#define IPC__WRITE                                0x00000020UL
+#define IPC__UNIX_WRITE                           0x00000100UL
 
+#define SEM__CREATE                               0x00000001UL
+#define SEM__DESTROY                              0x00000002UL
+#define SEM__GETATTR                              0x00000004UL
 #define SEM__SETATTR                              0x00000008UL
 #define SEM__READ                                 0x00000010UL
+#define SEM__WRITE                                0x00000020UL
 #define SEM__ASSOCIATE                            0x00000040UL
-#define SEM__DESTROY                              0x00000002UL
-#define SEM__UNIX_WRITE                           0x00000100UL
-#define SEM__CREATE                               0x00000001UL
 #define SEM__UNIX_READ                            0x00000080UL
-#define SEM__GETATTR                              0x00000004UL
-#define SEM__WRITE                                0x00000020UL
+#define SEM__UNIX_WRITE                           0x00000100UL
 
+#define MSGQ__CREATE                              0x00000001UL
+#define MSGQ__DESTROY                             0x00000002UL
+#define MSGQ__GETATTR                             0x00000004UL
 #define MSGQ__SETATTR                             0x00000008UL
 #define MSGQ__READ                                0x00000010UL
+#define MSGQ__WRITE                               0x00000020UL
 #define MSGQ__ASSOCIATE                           0x00000040UL
-#define MSGQ__DESTROY                             0x00000002UL
-#define MSGQ__UNIX_WRITE                          0x00000100UL
-#define MSGQ__CREATE                              0x00000001UL
 #define MSGQ__UNIX_READ                           0x00000080UL
-#define MSGQ__GETATTR                             0x00000004UL
-#define MSGQ__WRITE                               0x00000020UL
+#define MSGQ__UNIX_WRITE                          0x00000100UL
 
 #define MSGQ__ENQUEUE                             0x00000200UL
 
 #define MSG__SEND                                 0x00000001UL
 #define MSG__RECEIVE                              0x00000002UL
 
+#define SHM__CREATE                               0x00000001UL
+#define SHM__DESTROY                              0x00000002UL
+#define SHM__GETATTR                              0x00000004UL
 #define SHM__SETATTR                              0x00000008UL
 #define SHM__READ                                 0x00000010UL
+#define SHM__WRITE                                0x00000020UL
 #define SHM__ASSOCIATE                            0x00000040UL
-#define SHM__DESTROY                              0x00000002UL
-#define SHM__UNIX_WRITE                           0x00000100UL
-#define SHM__CREATE                               0x00000001UL
 #define SHM__UNIX_READ                            0x00000080UL
-#define SHM__GETATTR                              0x00000004UL
-#define SHM__WRITE                                0x00000020UL
+#define SHM__UNIX_WRITE                           0x00000100UL
 
 #define SHM__LOCK                                 0x00000200UL
 
 #define PASSWD__PASSWD                            0x00000001UL
 #define PASSWD__CHFN                              0x00000002UL
 #define PASSWD__CHSH                              0x00000004UL
-
+#define PASSWD__ROOTOK                            0x00000008UL
+
+#define DRAWABLE__CREATE                          0x00000001UL
+#define DRAWABLE__DESTROY                         0x00000002UL
+#define DRAWABLE__DRAW                            0x00000004UL
+#define DRAWABLE__COPY                            0x00000008UL
+#define DRAWABLE__GETATTR                         0x00000010UL
+
+#define GC__CREATE                                0x00000001UL
+#define GC__FREE                                  0x00000002UL
+#define GC__GETATTR                               0x00000004UL
+#define GC__SETATTR                               0x00000008UL
+
+#define WINDOW__ADDCHILD                          0x00000001UL
+#define WINDOW__CREATE                            0x00000002UL
+#define WINDOW__DESTROY                           0x00000004UL
+#define WINDOW__MAP                               0x00000008UL
+#define WINDOW__UNMAP                             0x00000010UL
+#define WINDOW__CHSTACK                           0x00000020UL
+#define WINDOW__CHPROPLIST                        0x00000040UL
+#define WINDOW__CHPROP                            0x00000080UL
+#define WINDOW__LISTPROP                          0x00000100UL
+#define WINDOW__GETATTR                           0x00000200UL
+#define WINDOW__SETATTR                           0x00000400UL
+#define WINDOW__SETFOCUS                          0x00000800UL
+#define WINDOW__MOVE                              0x00001000UL
+#define WINDOW__CHSELECTION                       0x00002000UL
+#define WINDOW__CHPARENT                          0x00004000UL
+#define WINDOW__CTRLLIFE                          0x00008000UL
+#define WINDOW__ENUMERATE                         0x00010000UL
+#define WINDOW__TRANSPARENT                       0x00020000UL
+#define WINDOW__MOUSEMOTION                       0x00040000UL
+#define WINDOW__CLIENTCOMEVENT                    0x00080000UL
+#define WINDOW__INPUTEVENT                        0x00100000UL
+#define WINDOW__DRAWEVENT                         0x00200000UL
+#define WINDOW__WINDOWCHANGEEVENT                 0x00400000UL
+#define WINDOW__WINDOWCHANGEREQUEST               0x00800000UL
+#define WINDOW__SERVERCHANGEEVENT                 0x01000000UL
+#define WINDOW__EXTENSIONEVENT                    0x02000000UL
+
+#define FONT__LOAD                                0x00000001UL
+#define FONT__FREE                                0x00000002UL
+#define FONT__GETATTR                             0x00000004UL
+#define FONT__USE                                 0x00000008UL
+
+#define COLORMAP__CREATE                          0x00000001UL
+#define COLORMAP__FREE                            0x00000002UL
+#define COLORMAP__INSTALL                         0x00000004UL
+#define COLORMAP__UNINSTALL                       0x00000008UL
+#define COLORMAP__LIST                            0x00000010UL
+#define COLORMAP__READ                            0x00000020UL
+#define COLORMAP__STORE                           0x00000040UL
+#define COLORMAP__GETATTR                         0x00000080UL
+#define COLORMAP__SETATTR                         0x00000100UL
+
+#define PROPERTY__CREATE                          0x00000001UL
+#define PROPERTY__FREE                            0x00000002UL
+#define PROPERTY__READ                            0x00000004UL
+#define PROPERTY__WRITE                           0x00000008UL
+
+#define CURSOR__CREATE                            0x00000001UL
+#define CURSOR__CREATEGLYPH                       0x00000002UL
+#define CURSOR__FREE                              0x00000004UL
+#define CURSOR__ASSIGN                            0x00000008UL
+#define CURSOR__SETATTR                           0x00000010UL
+
+#define XCLIENT__KILL                             0x00000001UL
+
+#define XINPUT__LOOKUP                            0x00000001UL
+#define XINPUT__GETATTR                           0x00000002UL
+#define XINPUT__SETATTR                           0x00000004UL
+#define XINPUT__SETFOCUS                          0x00000008UL
+#define XINPUT__WARPPOINTER                       0x00000010UL
+#define XINPUT__ACTIVEGRAB                        0x00000020UL
+#define XINPUT__PASSIVEGRAB                       0x00000040UL
+#define XINPUT__UNGRAB                            0x00000080UL
+#define XINPUT__BELL                              0x00000100UL
+#define XINPUT__MOUSEMOTION                       0x00000200UL
+#define XINPUT__RELABELINPUT                      0x00000400UL
+
+#define XSERVER__SCREENSAVER                      0x00000001UL
+#define XSERVER__GETHOSTLIST                      0x00000002UL
+#define XSERVER__SETHOSTLIST                      0x00000004UL
+#define XSERVER__GETFONTPATH                      0x00000008UL
+#define XSERVER__SETFONTPATH                      0x00000010UL
+#define XSERVER__GETATTR                          0x00000020UL
+#define XSERVER__GRAB                             0x00000040UL
+#define XSERVER__UNGRAB                           0x00000080UL
+
+#define XEXTENSION__QUERY                         0x00000001UL
+#define XEXTENSION__USE                           0x00000002UL
+
+#define PAX__PAGEEXEC                             0x00000001UL
+#define PAX__EMUTRAMP                             0x00000002UL
+#define PAX__MPROTECT                             0x00000004UL
+#define PAX__RANDMMAP                             0x00000008UL
+#define PAX__RANDEXEC                             0x00000010UL
+#define PAX__SEGMEXEC                             0x00000020UL
+
+#define NETLINK_ROUTE_SOCKET__IOCTL               0x00000001UL
+#define NETLINK_ROUTE_SOCKET__READ                0x00000002UL
+#define NETLINK_ROUTE_SOCKET__WRITE               0x00000004UL
+#define NETLINK_ROUTE_SOCKET__CREATE              0x00000008UL
+#define NETLINK_ROUTE_SOCKET__GETATTR             0x00000010UL
+#define NETLINK_ROUTE_SOCKET__SETATTR             0x00000020UL
+#define NETLINK_ROUTE_SOCKET__LOCK                0x00000040UL
+#define NETLINK_ROUTE_SOCKET__RELABELFROM         0x00000080UL
+#define NETLINK_ROUTE_SOCKET__RELABELTO           0x00000100UL
+#define NETLINK_ROUTE_SOCKET__APPEND              0x00000200UL
+#define NETLINK_ROUTE_SOCKET__BIND                0x00000400UL
+#define NETLINK_ROUTE_SOCKET__CONNECT             0x00000800UL
+#define NETLINK_ROUTE_SOCKET__LISTEN              0x00001000UL
+#define NETLINK_ROUTE_SOCKET__ACCEPT              0x00002000UL
+#define NETLINK_ROUTE_SOCKET__GETOPT              0x00004000UL
+#define NETLINK_ROUTE_SOCKET__SETOPT              0x00008000UL
+#define NETLINK_ROUTE_SOCKET__SHUTDOWN            0x00010000UL
+#define NETLINK_ROUTE_SOCKET__RECVFROM            0x00020000UL
+#define NETLINK_ROUTE_SOCKET__SENDTO              0x00040000UL
+#define NETLINK_ROUTE_SOCKET__RECV_MSG            0x00080000UL
+#define NETLINK_ROUTE_SOCKET__SEND_MSG            0x00100000UL
+#define NETLINK_ROUTE_SOCKET__NAME_BIND           0x00200000UL
+
+#define NETLINK_ROUTE_SOCKET__NLMSG_READ          0x00400000UL
+#define NETLINK_ROUTE_SOCKET__NLMSG_WRITE         0x00800000UL
+
+#define NETLINK_FIREWALL_SOCKET__IOCTL            0x00000001UL
+#define NETLINK_FIREWALL_SOCKET__READ             0x00000002UL
+#define NETLINK_FIREWALL_SOCKET__WRITE            0x00000004UL
+#define NETLINK_FIREWALL_SOCKET__CREATE           0x00000008UL
+#define NETLINK_FIREWALL_SOCKET__GETATTR          0x00000010UL
+#define NETLINK_FIREWALL_SOCKET__SETATTR          0x00000020UL
+#define NETLINK_FIREWALL_SOCKET__LOCK             0x00000040UL
+#define NETLINK_FIREWALL_SOCKET__RELABELFROM      0x00000080UL
+#define NETLINK_FIREWALL_SOCKET__RELABELTO        0x00000100UL
+#define NETLINK_FIREWALL_SOCKET__APPEND           0x00000200UL
+#define NETLINK_FIREWALL_SOCKET__BIND             0x00000400UL
+#define NETLINK_FIREWALL_SOCKET__CONNECT          0x00000800UL
+#define NETLINK_FIREWALL_SOCKET__LISTEN           0x00001000UL
+#define NETLINK_FIREWALL_SOCKET__ACCEPT           0x00002000UL
+#define NETLINK_FIREWALL_SOCKET__GETOPT           0x00004000UL
+#define NETLINK_FIREWALL_SOCKET__SETOPT           0x00008000UL
+#define NETLINK_FIREWALL_SOCKET__SHUTDOWN         0x00010000UL
+#define NETLINK_FIREWALL_SOCKET__RECVFROM         0x00020000UL
+#define NETLINK_FIREWALL_SOCKET__SENDTO           0x00040000UL
+#define NETLINK_FIREWALL_SOCKET__RECV_MSG         0x00080000UL
+#define NETLINK_FIREWALL_SOCKET__SEND_MSG         0x00100000UL
+#define NETLINK_FIREWALL_SOCKET__NAME_BIND        0x00200000UL
+
+#define NETLINK_FIREWALL_SOCKET__NLMSG_READ       0x00400000UL
+#define NETLINK_FIREWALL_SOCKET__NLMSG_WRITE      0x00800000UL
+
+#define NETLINK_TCPDIAG_SOCKET__IOCTL             0x00000001UL
+#define NETLINK_TCPDIAG_SOCKET__READ              0x00000002UL
+#define NETLINK_TCPDIAG_SOCKET__WRITE             0x00000004UL
+#define NETLINK_TCPDIAG_SOCKET__CREATE            0x00000008UL
+#define NETLINK_TCPDIAG_SOCKET__GETATTR           0x00000010UL
+#define NETLINK_TCPDIAG_SOCKET__SETATTR           0x00000020UL
+#define NETLINK_TCPDIAG_SOCKET__LOCK              0x00000040UL
+#define NETLINK_TCPDIAG_SOCKET__RELABELFROM       0x00000080UL
+#define NETLINK_TCPDIAG_SOCKET__RELABELTO         0x00000100UL
+#define NETLINK_TCPDIAG_SOCKET__APPEND            0x00000200UL
+#define NETLINK_TCPDIAG_SOCKET__BIND              0x00000400UL
+#define NETLINK_TCPDIAG_SOCKET__CONNECT           0x00000800UL
+#define NETLINK_TCPDIAG_SOCKET__LISTEN            0x00001000UL
+#define NETLINK_TCPDIAG_SOCKET__ACCEPT            0x00002000UL
+#define NETLINK_TCPDIAG_SOCKET__GETOPT            0x00004000UL
+#define NETLINK_TCPDIAG_SOCKET__SETOPT            0x00008000UL
+#define NETLINK_TCPDIAG_SOCKET__SHUTDOWN          0x00010000UL
+#define NETLINK_TCPDIAG_SOCKET__RECVFROM          0x00020000UL
+#define NETLINK_TCPDIAG_SOCKET__SENDTO            0x00040000UL
+#define NETLINK_TCPDIAG_SOCKET__RECV_MSG          0x00080000UL
+#define NETLINK_TCPDIAG_SOCKET__SEND_MSG          0x00100000UL
+#define NETLINK_TCPDIAG_SOCKET__NAME_BIND         0x00200000UL
+
+#define NETLINK_TCPDIAG_SOCKET__NLMSG_READ        0x00400000UL
+#define NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE       0x00800000UL
+
+#define NETLINK_NFLOG_SOCKET__IOCTL               0x00000001UL
+#define NETLINK_NFLOG_SOCKET__READ                0x00000002UL
+#define NETLINK_NFLOG_SOCKET__WRITE               0x00000004UL
+#define NETLINK_NFLOG_SOCKET__CREATE              0x00000008UL
+#define NETLINK_NFLOG_SOCKET__GETATTR             0x00000010UL
+#define NETLINK_NFLOG_SOCKET__SETATTR             0x00000020UL
+#define NETLINK_NFLOG_SOCKET__LOCK                0x00000040UL
+#define NETLINK_NFLOG_SOCKET__RELABELFROM         0x00000080UL
+#define NETLINK_NFLOG_SOCKET__RELABELTO           0x00000100UL
+#define NETLINK_NFLOG_SOCKET__APPEND              0x00000200UL
+#define NETLINK_NFLOG_SOCKET__BIND                0x00000400UL
+#define NETLINK_NFLOG_SOCKET__CONNECT             0x00000800UL
+#define NETLINK_NFLOG_SOCKET__LISTEN              0x00001000UL
+#define NETLINK_NFLOG_SOCKET__ACCEPT              0x00002000UL
+#define NETLINK_NFLOG_SOCKET__GETOPT              0x00004000UL
+#define NETLINK_NFLOG_SOCKET__SETOPT              0x00008000UL
+#define NETLINK_NFLOG_SOCKET__SHUTDOWN            0x00010000UL
+#define NETLINK_NFLOG_SOCKET__RECVFROM            0x00020000UL
+#define NETLINK_NFLOG_SOCKET__SENDTO              0x00040000UL
+#define NETLINK_NFLOG_SOCKET__RECV_MSG            0x00080000UL
+#define NETLINK_NFLOG_SOCKET__SEND_MSG            0x00100000UL
+#define NETLINK_NFLOG_SOCKET__NAME_BIND           0x00200000UL
+
+#define NETLINK_XFRM_SOCKET__IOCTL                0x00000001UL
+#define NETLINK_XFRM_SOCKET__READ                 0x00000002UL
+#define NETLINK_XFRM_SOCKET__WRITE                0x00000004UL
+#define NETLINK_XFRM_SOCKET__CREATE               0x00000008UL
+#define NETLINK_XFRM_SOCKET__GETATTR              0x00000010UL
+#define NETLINK_XFRM_SOCKET__SETATTR              0x00000020UL
+#define NETLINK_XFRM_SOCKET__LOCK                 0x00000040UL
+#define NETLINK_XFRM_SOCKET__RELABELFROM          0x00000080UL
+#define NETLINK_XFRM_SOCKET__RELABELTO            0x00000100UL
+#define NETLINK_XFRM_SOCKET__APPEND               0x00000200UL
+#define NETLINK_XFRM_SOCKET__BIND                 0x00000400UL
+#define NETLINK_XFRM_SOCKET__CONNECT              0x00000800UL
+#define NETLINK_XFRM_SOCKET__LISTEN               0x00001000UL
+#define NETLINK_XFRM_SOCKET__ACCEPT               0x00002000UL
+#define NETLINK_XFRM_SOCKET__GETOPT               0x00004000UL
+#define NETLINK_XFRM_SOCKET__SETOPT               0x00008000UL
+#define NETLINK_XFRM_SOCKET__SHUTDOWN             0x00010000UL
+#define NETLINK_XFRM_SOCKET__RECVFROM             0x00020000UL
+#define NETLINK_XFRM_SOCKET__SENDTO               0x00040000UL
+#define NETLINK_XFRM_SOCKET__RECV_MSG             0x00080000UL
+#define NETLINK_XFRM_SOCKET__SEND_MSG             0x00100000UL
+#define NETLINK_XFRM_SOCKET__NAME_BIND            0x00200000UL
+
+#define NETLINK_XFRM_SOCKET__NLMSG_READ           0x00400000UL
+#define NETLINK_XFRM_SOCKET__NLMSG_WRITE          0x00800000UL
+
+#define NETLINK_SELINUX_SOCKET__IOCTL             0x00000001UL
+#define NETLINK_SELINUX_SOCKET__READ              0x00000002UL
+#define NETLINK_SELINUX_SOCKET__WRITE             0x00000004UL
+#define NETLINK_SELINUX_SOCKET__CREATE            0x00000008UL
+#define NETLINK_SELINUX_SOCKET__GETATTR           0x00000010UL
+#define NETLINK_SELINUX_SOCKET__SETATTR           0x00000020UL
+#define NETLINK_SELINUX_SOCKET__LOCK              0x00000040UL
+#define NETLINK_SELINUX_SOCKET__RELABELFROM       0x00000080UL
+#define NETLINK_SELINUX_SOCKET__RELABELTO         0x00000100UL
+#define NETLINK_SELINUX_SOCKET__APPEND            0x00000200UL
+#define NETLINK_SELINUX_SOCKET__BIND              0x00000400UL
+#define NETLINK_SELINUX_SOCKET__CONNECT           0x00000800UL
+#define NETLINK_SELINUX_SOCKET__LISTEN            0x00001000UL
+#define NETLINK_SELINUX_SOCKET__ACCEPT            0x00002000UL
+#define NETLINK_SELINUX_SOCKET__GETOPT            0x00004000UL
+#define NETLINK_SELINUX_SOCKET__SETOPT            0x00008000UL
+#define NETLINK_SELINUX_SOCKET__SHUTDOWN          0x00010000UL
+#define NETLINK_SELINUX_SOCKET__RECVFROM          0x00020000UL
+#define NETLINK_SELINUX_SOCKET__SENDTO            0x00040000UL
+#define NETLINK_SELINUX_SOCKET__RECV_MSG          0x00080000UL
+#define NETLINK_SELINUX_SOCKET__SEND_MSG          0x00100000UL
+#define NETLINK_SELINUX_SOCKET__NAME_BIND         0x00200000UL
+
+#define NETLINK_AUDIT_SOCKET__IOCTL               0x00000001UL
+#define NETLINK_AUDIT_SOCKET__READ                0x00000002UL
+#define NETLINK_AUDIT_SOCKET__WRITE               0x00000004UL
+#define NETLINK_AUDIT_SOCKET__CREATE              0x00000008UL
+#define NETLINK_AUDIT_SOCKET__GETATTR             0x00000010UL
+#define NETLINK_AUDIT_SOCKET__SETATTR             0x00000020UL
+#define NETLINK_AUDIT_SOCKET__LOCK                0x00000040UL
+#define NETLINK_AUDIT_SOCKET__RELABELFROM         0x00000080UL
+#define NETLINK_AUDIT_SOCKET__RELABELTO           0x00000100UL
+#define NETLINK_AUDIT_SOCKET__APPEND              0x00000200UL
+#define NETLINK_AUDIT_SOCKET__BIND                0x00000400UL
+#define NETLINK_AUDIT_SOCKET__CONNECT             0x00000800UL
+#define NETLINK_AUDIT_SOCKET__LISTEN              0x00001000UL
+#define NETLINK_AUDIT_SOCKET__ACCEPT              0x00002000UL
+#define NETLINK_AUDIT_SOCKET__GETOPT              0x00004000UL
+#define NETLINK_AUDIT_SOCKET__SETOPT              0x00008000UL
+#define NETLINK_AUDIT_SOCKET__SHUTDOWN            0x00010000UL
+#define NETLINK_AUDIT_SOCKET__RECVFROM            0x00020000UL
+#define NETLINK_AUDIT_SOCKET__SENDTO              0x00040000UL
+#define NETLINK_AUDIT_SOCKET__RECV_MSG            0x00080000UL
+#define NETLINK_AUDIT_SOCKET__SEND_MSG            0x00100000UL
+#define NETLINK_AUDIT_SOCKET__NAME_BIND           0x00200000UL
+
+#define NETLINK_AUDIT_SOCKET__NLMSG_READ          0x00400000UL
+#define NETLINK_AUDIT_SOCKET__NLMSG_WRITE         0x00800000UL
+
+#define NETLINK_IP6FW_SOCKET__IOCTL               0x00000001UL
+#define NETLINK_IP6FW_SOCKET__READ                0x00000002UL
+#define NETLINK_IP6FW_SOCKET__WRITE               0x00000004UL
+#define NETLINK_IP6FW_SOCKET__CREATE              0x00000008UL
+#define NETLINK_IP6FW_SOCKET__GETATTR             0x00000010UL
+#define NETLINK_IP6FW_SOCKET__SETATTR             0x00000020UL
+#define NETLINK_IP6FW_SOCKET__LOCK                0x00000040UL
+#define NETLINK_IP6FW_SOCKET__RELABELFROM         0x00000080UL
+#define NETLINK_IP6FW_SOCKET__RELABELTO           0x00000100UL
+#define NETLINK_IP6FW_SOCKET__APPEND              0x00000200UL
+#define NETLINK_IP6FW_SOCKET__BIND                0x00000400UL
+#define NETLINK_IP6FW_SOCKET__CONNECT             0x00000800UL
+#define NETLINK_IP6FW_SOCKET__LISTEN              0x00001000UL
+#define NETLINK_IP6FW_SOCKET__ACCEPT              0x00002000UL
+#define NETLINK_IP6FW_SOCKET__GETOPT              0x00004000UL
+#define NETLINK_IP6FW_SOCKET__SETOPT              0x00008000UL
+#define NETLINK_IP6FW_SOCKET__SHUTDOWN            0x00010000UL
+#define NETLINK_IP6FW_SOCKET__RECVFROM            0x00020000UL
+#define NETLINK_IP6FW_SOCKET__SENDTO              0x00040000UL
+#define NETLINK_IP6FW_SOCKET__RECV_MSG            0x00080000UL
+#define NETLINK_IP6FW_SOCKET__SEND_MSG            0x00100000UL
+#define NETLINK_IP6FW_SOCKET__NAME_BIND           0x00200000UL
+
+#define NETLINK_IP6FW_SOCKET__NLMSG_READ          0x00400000UL
+#define NETLINK_IP6FW_SOCKET__NLMSG_WRITE         0x00800000UL
+
+#define NETLINK_DNRT_SOCKET__IOCTL                0x00000001UL
+#define NETLINK_DNRT_SOCKET__READ                 0x00000002UL
+#define NETLINK_DNRT_SOCKET__WRITE                0x00000004UL
+#define NETLINK_DNRT_SOCKET__CREATE               0x00000008UL
+#define NETLINK_DNRT_SOCKET__GETATTR              0x00000010UL
+#define NETLINK_DNRT_SOCKET__SETATTR              0x00000020UL
+#define NETLINK_DNRT_SOCKET__LOCK                 0x00000040UL
+#define NETLINK_DNRT_SOCKET__RELABELFROM          0x00000080UL
+#define NETLINK_DNRT_SOCKET__RELABELTO            0x00000100UL
+#define NETLINK_DNRT_SOCKET__APPEND               0x00000200UL
+#define NETLINK_DNRT_SOCKET__BIND                 0x00000400UL
+#define NETLINK_DNRT_SOCKET__CONNECT              0x00000800UL
+#define NETLINK_DNRT_SOCKET__LISTEN               0x00001000UL
+#define NETLINK_DNRT_SOCKET__ACCEPT               0x00002000UL
+#define NETLINK_DNRT_SOCKET__GETOPT               0x00004000UL
+#define NETLINK_DNRT_SOCKET__SETOPT               0x00008000UL
+#define NETLINK_DNRT_SOCKET__SHUTDOWN             0x00010000UL
+#define NETLINK_DNRT_SOCKET__RECVFROM             0x00020000UL
+#define NETLINK_DNRT_SOCKET__SENDTO               0x00040000UL
+#define NETLINK_DNRT_SOCKET__RECV_MSG             0x00080000UL
+#define NETLINK_DNRT_SOCKET__SEND_MSG             0x00100000UL
 
 /* FLASK */
index ce33ff3..a65e25e 100644 (file)
@@ -35,5 +35,26 @@ static char *class_to_string[] =
     "shm",
     "ipc",
     "passwd",
+    "drawable",
+    "window",
+    "gc",
+    "font",
+    "colormap",
+    "property",
+    "cursor",
+    "xclient",
+    "xinput",
+    "xserver",
+    "xextension",
+    "pax",
+    "netlink_route_socket",
+    "netlink_firewall_socket",
+    "netlink_tcpdiag_socket",
+    "netlink_nflog_socket",
+    "netlink_xfrm_socket",
+    "netlink_selinux_socket",
+    "netlink_audit_socket",
+    "netlink_ip6fw_socket",
+    "netlink_dnrt_socket",
 };
 
index 6425c78..a392a3d 100644 (file)
 #define SECCLASS_SHM                                     28
 #define SECCLASS_IPC                                     29
 #define SECCLASS_PASSWD                                  30
+#define SECCLASS_DRAWABLE                                31
+#define SECCLASS_WINDOW                                  32
+#define SECCLASS_GC                                      33
+#define SECCLASS_FONT                                    34
+#define SECCLASS_COLORMAP                                35
+#define SECCLASS_PROPERTY                                36
+#define SECCLASS_CURSOR                                  37
+#define SECCLASS_XCLIENT                                 38
+#define SECCLASS_XINPUT                                  39
+#define SECCLASS_XSERVER                                 40
+#define SECCLASS_XEXTENSION                              41
+#define SECCLASS_PAX                                     42
+#define SECCLASS_NETLINK_ROUTE_SOCKET                    43
+#define SECCLASS_NETLINK_FIREWALL_SOCKET                 44
+#define SECCLASS_NETLINK_TCPDIAG_SOCKET                  45
+#define SECCLASS_NETLINK_NFLOG_SOCKET                    46
+#define SECCLASS_NETLINK_XFRM_SOCKET                     47
+#define SECCLASS_NETLINK_SELINUX_SOCKET                  48
+#define SECCLASS_NETLINK_AUDIT_SOCKET                    49
+#define SECCLASS_NETLINK_IP6FW_SOCKET                    50
+#define SECCLASS_NETLINK_DNRT_SOCKET                     51
 
 /*
  * Security identifier indices for initial entities
index 0413683..5931e46 100644 (file)
 #define SELINUX_MAGIC 0xf97cff8c
 
 /* Identify specific policy version changes */
-#define POLICYDB_VERSION_BASE  15
-#define POLICYDB_VERSION_BOOL  16
-#define POLICYDB_VERSION_IPV6  17
+#define POLICYDB_VERSION_BASE          15
+#define POLICYDB_VERSION_BOOL          16
+#define POLICYDB_VERSION_IPV6          17
+#define POLICYDB_VERSION_NLCLASS       18
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_IPV6
+#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_NLCLASS
 
 #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
 extern int selinux_enabled;
index 274275a..975a177 100644 (file)
@@ -68,7 +68,7 @@ enum sel_inos {
        SEL_DISABLE     /* disable SELinux until next reboot */
 };
 
-static ssize_t sel_read_enforce(struct file *filp, char *buf,
+static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
                                size_t count, loff_t *ppos)
 {
        char *page;
@@ -105,7 +105,7 @@ out:
 }
 
 #ifdef CONFIG_SECURITY_SELINUX_DEVELOP
-static ssize_t sel_write_enforce(struct file * file, const char * buf,
+static ssize_t sel_write_enforce(struct file * file, const char __user * buf,
                                 size_t count, loff_t *ppos)
 
 {
@@ -155,7 +155,7 @@ static struct file_operations sel_enforce_ops = {
 };
 
 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
-static ssize_t sel_write_disable(struct file * file, const char * buf,
+static ssize_t sel_write_disable(struct file * file, const char __user * buf,
                                 size_t count, loff_t *ppos)
 
 {
@@ -201,7 +201,7 @@ static struct file_operations sel_disable_ops = {
        .write          = sel_write_disable,
 };
 
-static ssize_t sel_read_policyvers(struct file *filp, char *buf,
+static ssize_t sel_read_policyvers(struct file *filp, char __user *buf,
                                    size_t count, loff_t *ppos)
 {
        char *page;
@@ -244,7 +244,7 @@ static struct file_operations sel_policyvers_ops = {
 /* declaration for sel_write_load */
 static int sel_make_bools(void);
 
-static ssize_t sel_read_mls(struct file *filp, char *buf,
+static ssize_t sel_read_mls(struct file *filp, char __user *buf,
                                size_t count, loff_t *ppos)
 {
        char *page;
@@ -284,7 +284,7 @@ static struct file_operations sel_mls_ops = {
        .read           = sel_read_mls,
 };
 
-static ssize_t sel_write_load(struct file * file, const char * buf,
+static ssize_t sel_write_load(struct file * file, const char __user * buf,
                              size_t count, loff_t *ppos)
 
 {
@@ -334,7 +334,7 @@ static struct file_operations sel_load_ops = {
 };
 
 
-static ssize_t sel_write_context(struct file * file, const char * buf,
+static ssize_t sel_write_context(struct file * file, const char __user * buf,
                                 size_t count, loff_t *ppos)
 
 {
@@ -406,7 +406,7 @@ struct argresp {
  * possibly a read which collects the result - which is stored in a
  * file-local buffer.
  */
-static ssize_t TA_write(struct file *file, const char *buf, size_t size, loff_t *pos)
+static ssize_t TA_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
 {
        ino_t ino =  file->f_dentry->d_inode->i_ino;
        struct argresp *ar;
@@ -445,7 +445,7 @@ static ssize_t TA_write(struct file *file, const char *buf, size_t size, loff_t
        return rv;
 }
 
-static ssize_t TA_read(struct file *file, char *buf, size_t size, loff_t *pos)
+static ssize_t TA_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
 {
        struct argresp *ar;
        ssize_t rv = 0;
@@ -744,7 +744,7 @@ static struct inode *sel_make_inode(struct super_block *sb, int mode)
 
 #define BOOL_INO_OFFSET 30
 
-static ssize_t sel_read_bool(struct file *filep, char *buf,
+static ssize_t sel_read_bool(struct file *filep, char __user *buf,
                             size_t count, loff_t *ppos)
 {
        char *page = NULL;
@@ -806,7 +806,7 @@ out:
        return ret;
 }
 
-static ssize_t sel_write_bool(struct file *filep, const char *buf,
+static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
                              size_t count, loff_t *ppos)
 {
        char *page = NULL;
@@ -865,7 +865,8 @@ static struct file_operations sel_bool_ops = {
        .write          = sel_write_bool,
 };
 
-static ssize_t sel_commit_bools_write(struct file *filep, const char *buf,
+static ssize_t sel_commit_bools_write(struct file *filep,
+                                     const char __user *buf,
                                      size_t count, loff_t *ppos)
 {
        char *page = NULL;
index aa1b54c..f54ad88 100644 (file)
@@ -290,7 +290,7 @@ int mls_context_to_sid(char oldc,
                if (rc)
                        goto out;
        }
-       *scontext = p;
+       *scontext = ++p;
        rc = 0;
 out:
        return rc;
index d98bb8d..ec14093 100644 (file)
@@ -38,6 +38,8 @@ static char *symtab_name[SYM_NUM] = {
 };
 #endif
 
+int policydb_loaded_version;
+
 static unsigned int symtab_sizes[SYM_NUM] = {
        2,
        32,
@@ -71,6 +73,11 @@ static struct policydb_compat_info policydb_compat[] = {
                .sym_num        = SYM_NUM,
                .ocon_num       = OCON_NUM,
        },
+       {
+               .version        = POLICYDB_VERSION_NLCLASS,
+               .sym_num        = SYM_NUM,
+               .ocon_num       = OCON_NUM,
+       },
 };
 
 static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -1125,7 +1132,7 @@ int policydb_read(struct policydb *p, void *fp)
        struct role_trans *tr, *ltr;
        struct ocontext *l, *c, *newc;
        struct genfs *genfs_p, *genfs, *newgenfs;
-       int i, j, rc, r_policyvers;
+       int i, j, rc, r_policyvers = 0;
        u32 *buf, len, len2, config, nprim, nel, nel2;
        char *policydb_str;
        struct policydb_compat_info *info;
@@ -1546,6 +1553,7 @@ int policydb_read(struct policydb *p, void *fp)
        if (rc)
                goto bad;
 out:
+       policydb_loaded_version = r_policyvers;
        return rc;
 bad_newc:
        ocontext_destroy(newc,OCON_FSUSE);
index 7d0fedf..2e857b7 100644 (file)
@@ -40,6 +40,7 @@
 #include "mls.h"
 
 extern void selnl_notify_policyload(u32 seqno);
+extern int policydb_loaded_version;
 
 static rwlock_t policy_rwlock = RW_LOCK_UNLOCKED;
 #define POLICY_RDLOCK read_lock(&policy_rwlock)
@@ -203,6 +204,17 @@ static int context_struct_compute_av(struct context *scontext,
        struct avtab_datum *avdatum;
        struct class_datum *tclass_datum;
 
+       /*
+        * Remap extended Netlink classes for old policy versions.
+        * Do this here rather than socket_type_to_security_class()
+        * in case a newer policy version is loaded, allowing sockets
+        * to remain in the correct class.
+        */
+       if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
+               if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
+                   tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
+                       tclass = SECCLASS_NETLINK_SOCKET;
+
        if (!tclass || tclass > policydb.p_classes.nprim) {
                printk(KERN_ERR "security_compute_av:  unrecognized class %d\n",
                       tclass);
@@ -532,6 +544,11 @@ int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
        if (rc)
                goto out_unlock;
 
+       if ((p - scontext2) < scontext_len) {
+               rc = -EINVAL;
+               goto out_unlock;
+       }
+
        /* Check the validity of the new context. */
        if (!policydb_context_isvalid(&policydb, &context)) {
                rc = -EINVAL;
index 95e84df..7cc1939 100644 (file)
@@ -512,7 +512,7 @@ snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
 }
 
 static int snd_ctl_card_info(snd_card_t * card, snd_ctl_file_t * ctl,
-                            unsigned int cmd, unsigned long arg)
+                            unsigned int cmd, void __user *arg)
 {
        snd_ctl_card_info_t info;
 
@@ -526,12 +526,12 @@ static int snd_ctl_card_info(snd_card_t * card, snd_ctl_file_t * ctl,
        strlcpy(info.mixername, card->mixername, sizeof(info.mixername));
        strlcpy(info.components, card->components, sizeof(info.components));
        up_read(&snd_ioctl_rwsem);
-       if (copy_to_user((void *) arg, &info, sizeof(snd_ctl_card_info_t)))
+       if (copy_to_user(arg, &info, sizeof(snd_ctl_card_info_t)))
                return -EFAULT;
        return 0;
 }
 
-static int snd_ctl_elem_list(snd_card_t *card, snd_ctl_elem_list_t *_list)
+static int snd_ctl_elem_list(snd_card_t *card, snd_ctl_elem_list_t __user *_list)
 {
        struct list_head *plist;
        snd_ctl_elem_list_t list;
@@ -593,7 +593,7 @@ static int snd_ctl_elem_list(snd_card_t *card, snd_ctl_elem_list_t *_list)
        return 0;
 }
 
-static int snd_ctl_elem_info(snd_ctl_file_t *ctl, snd_ctl_elem_info_t *_info)
+static int snd_ctl_elem_info(snd_ctl_file_t *ctl, snd_ctl_elem_info_t __user *_info)
 {
        snd_card_t *card = ctl->card;
        snd_ctl_elem_info_t info;
@@ -636,7 +636,7 @@ static int snd_ctl_elem_info(snd_ctl_file_t *ctl, snd_ctl_elem_info_t *_info)
        return result;
 }
 
-static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *_control)
+static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t __user *_control)
 {
        snd_ctl_elem_value_t *control;
        snd_kcontrol_t *kctl;
@@ -676,7 +676,7 @@ static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *_control)
        return result;
 }
 
-static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *_control)
+static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t __user *_control)
 {
        snd_card_t *card = file->card;
        snd_ctl_elem_value_t *control;
@@ -726,7 +726,7 @@ static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *_contr
        return result;
 }
 
-static int snd_ctl_elem_lock(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id)
+static int snd_ctl_elem_lock(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id)
 {
        snd_card_t *card = file->card;
        snd_ctl_elem_id_t id;
@@ -754,7 +754,7 @@ static int snd_ctl_elem_lock(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id)
        return result;
 }
 
-static int snd_ctl_elem_unlock(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id)
+static int snd_ctl_elem_unlock(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id)
 {
        snd_card_t *card = file->card;
        snd_ctl_elem_id_t id;
@@ -840,7 +840,7 @@ static void snd_ctl_elem_user_free(snd_kcontrol_t * kcontrol)
        kfree(kcontrol->private_data);
 }
 
-static int snd_ctl_elem_add(snd_ctl_file_t *file, snd_ctl_elem_info_t *_info, int replace)
+static int snd_ctl_elem_add(snd_ctl_file_t *file, snd_ctl_elem_info_t __user *_info, int replace)
 {
        snd_card_t *card = file->card;
        snd_ctl_elem_info_t info;
@@ -965,7 +965,7 @@ static int snd_ctl_elem_add(snd_ctl_file_t *file, snd_ctl_elem_info_t *_info, in
        return 0;
 }
 
-static int snd_ctl_elem_remove(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id)
+static int snd_ctl_elem_remove(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id)
 {
        snd_ctl_elem_id_t id;
 
@@ -974,7 +974,7 @@ static int snd_ctl_elem_remove(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id)
        return snd_ctl_remove_unlocked_id(file, &id);
 }
 
-static int snd_ctl_subscribe_events(snd_ctl_file_t *file, int *ptr)
+static int snd_ctl_subscribe_events(snd_ctl_file_t *file, int __user *ptr)
 {
        int subscribe;
        if (get_user(subscribe, ptr))
@@ -1029,6 +1029,8 @@ static int snd_ctl_ioctl(struct inode *inode, struct file *file,
        snd_card_t *card;
        struct list_head *list;
        snd_kctl_ioctl_t *p;
+       void __user *argp = (void __user *)arg;
+       int __user *ip = argp;
        int err;
 
        ctl = snd_magic_cast(snd_ctl_file_t, file->private_data, return -ENXIO);
@@ -1036,31 +1038,31 @@ static int snd_ctl_ioctl(struct inode *inode, struct file *file,
        snd_assert(card != NULL, return -ENXIO);
        switch (cmd) {
        case SNDRV_CTL_IOCTL_PVERSION:
-               return put_user(SNDRV_CTL_VERSION, (int *)arg) ? -EFAULT : 0;
+               return put_user(SNDRV_CTL_VERSION, ip) ? -EFAULT : 0;
        case SNDRV_CTL_IOCTL_CARD_INFO:
-               return snd_ctl_card_info(card, ctl, cmd, arg);
+               return snd_ctl_card_info(card, ctl, cmd, argp);
        case SNDRV_CTL_IOCTL_ELEM_LIST:
-               return snd_ctl_elem_list(ctl->card, (snd_ctl_elem_list_t *) arg);
+               return snd_ctl_elem_list(ctl->card, argp);
        case SNDRV_CTL_IOCTL_ELEM_INFO:
-               return snd_ctl_elem_info(ctl, (snd_ctl_elem_info_t *) arg);
+               return snd_ctl_elem_info(ctl, argp);
        case SNDRV_CTL_IOCTL_ELEM_READ:
-               return snd_ctl_elem_read(ctl->card, (snd_ctl_elem_value_t *) arg);
+               return snd_ctl_elem_read(ctl->card, argp);
        case SNDRV_CTL_IOCTL_ELEM_WRITE:
-               return snd_ctl_elem_write(ctl, (snd_ctl_elem_value_t *) arg);
+               return snd_ctl_elem_write(ctl, argp);
        case SNDRV_CTL_IOCTL_ELEM_LOCK:
-               return snd_ctl_elem_lock(ctl, (snd_ctl_elem_id_t *) arg);
+               return snd_ctl_elem_lock(ctl, argp);
        case SNDRV_CTL_IOCTL_ELEM_UNLOCK:
-               return snd_ctl_elem_unlock(ctl, (snd_ctl_elem_id_t *) arg);
+               return snd_ctl_elem_unlock(ctl, argp);
        case SNDRV_CTL_IOCTL_ELEM_ADD:
-               return snd_ctl_elem_add(ctl, (snd_ctl_elem_info_t *) arg, 0);
+               return snd_ctl_elem_add(ctl, argp, 0);
        case SNDRV_CTL_IOCTL_ELEM_REPLACE:
-               return snd_ctl_elem_add(ctl, (snd_ctl_elem_info_t *) arg, 1);
+               return snd_ctl_elem_add(ctl, argp, 1);
        case SNDRV_CTL_IOCTL_ELEM_REMOVE:
-               return snd_ctl_elem_remove(ctl, (snd_ctl_elem_id_t *) arg);
+               return snd_ctl_elem_remove(ctl, argp);
        case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
-               return snd_ctl_subscribe_events(ctl, (int *) arg);
+               return snd_ctl_subscribe_events(ctl, ip);
        case SNDRV_CTL_IOCTL_POWER:
-               if (get_user(err, (int *)arg))
+               if (get_user(err, ip))
                        return -EFAULT;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
@@ -1075,9 +1077,9 @@ static int snd_ctl_ioctl(struct inode *inode, struct file *file,
                return err;
        case SNDRV_CTL_IOCTL_POWER_STATE:
 #ifdef CONFIG_PM
-               return put_user(card->power_state, (int *)arg) ? -EFAULT : 0;
+               return put_user(card->power_state, ip) ? -EFAULT : 0;
 #else
-               return put_user(SNDRV_CTL_POWER_D0, (int *)arg) ? -EFAULT : 0;
+               return put_user(SNDRV_CTL_POWER_D0, ip) ? -EFAULT : 0;
 #endif
        }
        down_read(&snd_ioctl_rwsem);
@@ -1094,7 +1096,7 @@ static int snd_ctl_ioctl(struct inode *inode, struct file *file,
        return -ENOTTY;
 }
 
-static ssize_t snd_ctl_read(struct file *file, char *buffer, size_t count, loff_t * offset)
+static ssize_t snd_ctl_read(struct file *file, char __user *buffer, size_t count, loff_t * offset)
 {
        snd_ctl_file_t *ctl;
        int err = 0;
index 33d7603..d18e476 100644 (file)
@@ -55,7 +55,7 @@ static loff_t snd_hwdep_llseek(struct file * file, loff_t offset, int orig)
        return -ENXIO;
 }
 
-static ssize_t snd_hwdep_read(struct file * file, char *buf, size_t count, loff_t *offset)
+static ssize_t snd_hwdep_read(struct file * file, char __user *buf, size_t count, loff_t *offset)
 {
        snd_hwdep_t *hw = snd_magic_cast(snd_hwdep_t, file->private_data, return -ENXIO);
        if (hw->ops.read)
@@ -63,7 +63,7 @@ static ssize_t snd_hwdep_read(struct file * file, char *buf, size_t count, loff_
        return -ENXIO;  
 }
 
-static ssize_t snd_hwdep_write(struct file * file, const char *buf, size_t count, loff_t *offset)
+static ssize_t snd_hwdep_write(struct file * file, const char __user *buf, size_t count, loff_t *offset)
 {
        snd_hwdep_t *hw = snd_magic_cast(snd_hwdep_t, file->private_data, return -ENXIO);
        if (hw->ops.write)
@@ -179,7 +179,7 @@ static unsigned int snd_hwdep_poll(struct file * file, poll_table * wait)
        return 0;
 }
 
-static int snd_hwdep_info(snd_hwdep_t *hw, snd_hwdep_info_t *_info)
+static int snd_hwdep_info(snd_hwdep_t *hw, snd_hwdep_info_t __user *_info)
 {
        snd_hwdep_info_t info;
        
@@ -193,7 +193,7 @@ static int snd_hwdep_info(snd_hwdep_t *hw, snd_hwdep_info_t *_info)
        return 0;
 }
 
-static int snd_hwdep_dsp_status(snd_hwdep_t *hw, snd_hwdep_dsp_status_t *_info)
+static int snd_hwdep_dsp_status(snd_hwdep_t *hw, snd_hwdep_dsp_status_t __user *_info)
 {
        snd_hwdep_dsp_status_t info;
        int err;
@@ -209,7 +209,7 @@ static int snd_hwdep_dsp_status(snd_hwdep_t *hw, snd_hwdep_dsp_status_t *_info)
        return 0;
 }
 
-static int snd_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *_info)
+static int snd_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t __user *_info)
 {
        snd_hwdep_dsp_image_t info;
        int err;
@@ -235,15 +235,16 @@ static int snd_hwdep_ioctl(struct inode *inode, struct file * file,
                           unsigned int cmd, unsigned long arg)
 {
        snd_hwdep_t *hw = snd_magic_cast(snd_hwdep_t, file->private_data, return -ENXIO);
+       void __user *argp = (void __user *)arg;
        switch (cmd) {
        case SNDRV_HWDEP_IOCTL_PVERSION:
-               return put_user(SNDRV_HWDEP_VERSION, (int *)arg);
+               return put_user(SNDRV_HWDEP_VERSION, (int __user *)argp);
        case SNDRV_HWDEP_IOCTL_INFO:
-               return snd_hwdep_info(hw, (snd_hwdep_info_t *)arg);
+               return snd_hwdep_info(hw, argp);
        case SNDRV_HWDEP_IOCTL_DSP_STATUS:
-               return snd_hwdep_dsp_status(hw, (snd_hwdep_dsp_status_t *)arg);
+               return snd_hwdep_dsp_status(hw, argp);
        case SNDRV_HWDEP_IOCTL_DSP_LOAD:
-               return snd_hwdep_dsp_load(hw, (snd_hwdep_dsp_image_t *)arg);
+               return snd_hwdep_dsp_load(hw, argp);
        }
        if (hw->ops.ioctl)
                return hw->ops.ioctl(hw, file, cmd, arg);
@@ -269,7 +270,7 @@ static int snd_hwdep_control_ioctl(snd_card_t * card, snd_ctl_file_t * control,
                {
                        int device;
 
-                       if (get_user(device, (int *)arg))
+                       if (get_user(device, (int __user *)arg))
                                return -EFAULT;
                        device = device < 0 ? 0 : device + 1;
                        while (device < SNDRV_MINOR_HWDEPS) {
@@ -279,13 +280,13 @@ static int snd_hwdep_control_ioctl(snd_card_t * card, snd_ctl_file_t * control,
                        }
                        if (device >= SNDRV_MINOR_HWDEPS)
                                device = -1;
-                       if (put_user(device, (int *)arg))
+                       if (put_user(device, (int __user *)arg))
                                return -EFAULT;
                        return 0;
                }
        case SNDRV_CTL_IOCTL_HWDEP_INFO:
                {
-                       snd_hwdep_info_t *info = (snd_hwdep_info_t *)arg;
+                       snd_hwdep_info_t __user *info = (snd_hwdep_info_t __user *)arg;
                        int device;
                        snd_hwdep_t *hwdep;
 
index fadd471..0b08203 100644 (file)
@@ -174,7 +174,7 @@ out:
        return ret;
 }
 
-static ssize_t snd_info_entry_read(struct file *file, char *buffer,
+static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
                                   size_t count, loff_t * offset)
 {
        snd_info_private_data_t *data;
@@ -208,7 +208,7 @@ static ssize_t snd_info_entry_read(struct file *file, char *buffer,
        return size;
 }
 
-static ssize_t snd_info_entry_write(struct file *file, const char *buffer,
+static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer,
                                    size_t count, loff_t * offset)
 {
        snd_info_private_data_t *data;
index 1f8c8d9..cf4f75c 100644 (file)
@@ -307,7 +307,7 @@ char *snd_kmalloc_strdup(const char *string, int flags)
  *
  * Returns zero if successful, or non-zero on failure.
  */
-int copy_to_user_fromio(void *dst, unsigned long src, size_t count)
+int copy_to_user_fromio(void __user *dst, unsigned long src, size_t count)
 {
 #if defined(__i386__) || defined(CONFIG_SPARC32)
        return copy_to_user(dst, (const void*)src, count) ? -EFAULT : 0;
@@ -338,7 +338,7 @@ int copy_to_user_fromio(void *dst, unsigned long src, size_t count)
  *
  * Returns zero if successful, or non-zero on failure.
  */
-int copy_from_user_toio(unsigned long dst, const void *src, size_t count)
+int copy_from_user_toio(unsigned long dst, const void __user *src, size_t count)
 {
 #if defined(__i386__) || defined(CONFIG_SPARC32)
        return copy_from_user((void*)dst, src, count) ? -EFAULT : 0;
index 8e7efaf..d8359d3 100644 (file)
@@ -81,7 +81,7 @@ static int snd_mixer_oss_release(struct inode *inode, struct file *file)
 }
 
 static int snd_mixer_oss_info(snd_mixer_oss_file_t *fmixer,
-                             mixer_info *_info)
+                             mixer_info __user *_info)
 {
        snd_card_t *card = fmixer->card;
        snd_mixer_oss_t *mixer = fmixer->mixer;
@@ -97,7 +97,7 @@ static int snd_mixer_oss_info(snd_mixer_oss_file_t *fmixer,
 }
 
 static int snd_mixer_oss_info_obsolete(snd_mixer_oss_file_t *fmixer,
-                                      _old_mixer_info *_info)
+                                      _old_mixer_info __user *_info)
 {
        snd_card_t *card = fmixer->card;
        snd_mixer_oss_t *mixer = fmixer->mixer;
@@ -293,65 +293,67 @@ static int snd_mixer_oss_set_volume(snd_mixer_oss_file_t *fmixer,
 
 static int snd_mixer_oss_ioctl1(snd_mixer_oss_file_t *fmixer, unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        int tmp;
 
        snd_assert(fmixer != NULL, return -ENXIO);
        if (((cmd >> 8) & 0xff) == 'M') {
                switch (cmd) {
                case SOUND_MIXER_INFO:
-                       return snd_mixer_oss_info(fmixer, (mixer_info *)arg);
+                       return snd_mixer_oss_info(fmixer, argp);
                case SOUND_OLD_MIXER_INFO:
-                       return snd_mixer_oss_info_obsolete(fmixer, (_old_mixer_info *)arg);
+                       return snd_mixer_oss_info_obsolete(fmixer, argp);
                case SOUND_MIXER_WRITE_RECSRC:
-                       if (get_user(tmp, (int *)arg))
+                       if (get_user(tmp, p))
                                return -EFAULT;
                        tmp = snd_mixer_oss_set_recsrc(fmixer, tmp);
                        if (tmp < 0)
                                return tmp;
-                       return put_user(tmp, (int *)arg);
+                       return put_user(tmp, p);
                case OSS_GETVERSION:
-                       return put_user(SNDRV_OSS_VERSION, (int *) arg);
+                       return put_user(SNDRV_OSS_VERSION, p);
                case OSS_ALSAEMULVER:
-                       return put_user(1, (int *) arg);
+                       return put_user(1, p);
                case SOUND_MIXER_READ_DEVMASK:
                        tmp = snd_mixer_oss_devmask(fmixer);
                        if (tmp < 0)
                                return tmp;
-                       return put_user(tmp, (int *)arg);
+                       return put_user(tmp, p);
                case SOUND_MIXER_READ_STEREODEVS:
                        tmp = snd_mixer_oss_stereodevs(fmixer);
                        if (tmp < 0)
                                return tmp;
-                       return put_user(tmp, (int *)arg);
+                       return put_user(tmp, p);
                case SOUND_MIXER_READ_RECMASK:
                        tmp = snd_mixer_oss_recmask(fmixer);
                        if (tmp < 0)
                                return tmp;
-                       return put_user(tmp, (int *)arg);
+                       return put_user(tmp, p);
                case SOUND_MIXER_READ_CAPS:
                        tmp = snd_mixer_oss_caps(fmixer);
                        if (tmp < 0)
                                return tmp;
-                       return put_user(tmp, (int *)arg);
+                       return put_user(tmp, p);
                case SOUND_MIXER_READ_RECSRC:
                        tmp = snd_mixer_oss_get_recsrc(fmixer);
                        if (tmp < 0)
                                return tmp;
-                       return put_user(tmp, (int *)arg);
+                       return put_user(tmp, p);
                }
        }
        if (cmd & SIOC_IN) {
-               if (get_user(tmp, (int *)arg))
+               if (get_user(tmp, p))
                        return -EFAULT;
                tmp = snd_mixer_oss_set_volume(fmixer, cmd & 0xff, tmp);
                if (tmp < 0)
                        return tmp;
-               return put_user(tmp, (int *)arg);
+               return put_user(tmp, p);
        } else if (cmd & SIOC_OUT) {
                tmp = snd_mixer_oss_get_volume(fmixer, cmd & 0xff);
                if (tmp < 0)
                        return tmp;
-               return put_user(tmp, (int *)arg);
+               return put_user(tmp, p);
        }
        return -ENXIO;
 }
index 75cea7e..65b5017 100644 (file)
@@ -806,7 +806,7 @@ static ssize_t snd_pcm_oss_write2(snd_pcm_substream_t *substream, const char *bu
        return bytes;
 }
 
-static ssize_t snd_pcm_oss_write1(snd_pcm_substream_t *substream, const char *buf, size_t bytes)
+static ssize_t snd_pcm_oss_write1(snd_pcm_substream_t *substream, const char __user *buf, size_t bytes)
 {
        size_t xfer = 0;
        ssize_t tmp;
@@ -883,7 +883,7 @@ static ssize_t snd_pcm_oss_read2(snd_pcm_substream_t *substream, char *buf, size
        return bytes;
 }
 
-static ssize_t snd_pcm_oss_read1(snd_pcm_substream_t *substream, char *buf, size_t bytes)
+static ssize_t snd_pcm_oss_read1(snd_pcm_substream_t *substream, char __user *buf, size_t bytes)
 {
        size_t xfer = 0;
        ssize_t tmp;
@@ -1067,9 +1067,9 @@ static int snd_pcm_oss_sync(snd_pcm_oss_file_t *pcm_oss_file)
                                        snd_pcm_lib_write(substream, runtime->oss.buffer, size1);
                                }
                        } else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
-                               void *buffers[runtime->channels];
+                               void __user *buffers[runtime->channels];
                                memset(buffers, 0, runtime->channels * sizeof(void *));
-                               snd_pcm_lib_writev(substream, (void **)buffers, size);
+                               snd_pcm_lib_writev(substream, buffers, size);
                        }
                }
                /*
@@ -1468,7 +1468,7 @@ static int snd_pcm_oss_get_odelay(snd_pcm_oss_file_t *pcm_oss_file)
        return snd_pcm_oss_bytes(substream, delay);
 }
 
-static int snd_pcm_oss_get_ptr(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct count_info * _info)
+static int snd_pcm_oss_get_ptr(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct count_info __user * _info)
 {      
        snd_pcm_substream_t *substream;
        snd_pcm_runtime_t *runtime;
@@ -1530,7 +1530,7 @@ static int snd_pcm_oss_get_ptr(snd_pcm_oss_file_t *pcm_oss_file, int stream, str
        return 0;
 }
 
-static int snd_pcm_oss_get_space(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct audio_buf_info *_info)
+static int snd_pcm_oss_get_space(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct audio_buf_info __user *_info)
 {
        snd_pcm_substream_t *substream;
        snd_pcm_runtime_t *runtime;
@@ -1589,7 +1589,7 @@ static int snd_pcm_oss_get_space(snd_pcm_oss_file_t *pcm_oss_file, int stream, s
        return 0;
 }
 
-static int snd_pcm_oss_get_mapbuf(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct buffmem_desc * _info)
+static int snd_pcm_oss_get_mapbuf(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct buffmem_desc __user * _info)
 {
        // it won't be probably implemented
        // snd_printd("TODO: snd_pcm_oss_get_mapbuf\n");
@@ -1912,13 +1912,14 @@ static int snd_pcm_oss_ioctl(struct inode *inode, struct file *file,
                              unsigned int cmd, unsigned long arg)
 {
        snd_pcm_oss_file_t *pcm_oss_file;
+       int __user *p = (int __user *)arg;
        int res;
 
        pcm_oss_file = snd_magic_cast(snd_pcm_oss_file_t, file->private_data, return -ENXIO);
        if (cmd == OSS_GETVERSION)
-               return put_user(SNDRV_OSS_VERSION, (int *)arg);
+               return put_user(SNDRV_OSS_VERSION, p);
        if (cmd == OSS_ALSAEMULVER)
-               return put_user(1, (int *)arg);
+               return put_user(1, p);
 #if defined(CONFIG_SND_MIXER_OSS) || (defined(MODULE) && defined(CONFIG_SND_MIXER_OSS_MODULE))
        if (((cmd >> 8) & 0xff) == 'M') {       /* mixer ioctl - for OSS compatibility */
                snd_pcm_substream_t *substream;
@@ -1943,93 +1944,93 @@ static int snd_pcm_oss_ioctl(struct inode *inode, struct file *file,
        case SNDCTL_DSP_SYNC:
                return snd_pcm_oss_sync(pcm_oss_file);
        case SNDCTL_DSP_SPEED:
-               if (get_user(res, (int *)arg))
+               if (get_user(res, p))
                        return -EFAULT;
                if ((res = snd_pcm_oss_set_rate(pcm_oss_file, res))<0)
                        return res;
-               return put_user(res, (int *)arg);
+               return put_user(res, p);
        case SOUND_PCM_READ_RATE:
                res = snd_pcm_oss_get_rate(pcm_oss_file);
                if (res < 0)
                        return res;
-               return put_user(res, (int *)arg);
+               return put_user(res, p);
        case SNDCTL_DSP_STEREO:
-               if (get_user(res, (int *)arg))
+               if (get_user(res, p))
                        return -EFAULT;
                res = res > 0 ? 2 : 1;
                if ((res = snd_pcm_oss_set_channels(pcm_oss_file, res)) < 0)
                        return res;
-               return put_user(--res, (int *)arg);
+               return put_user(--res, p);
        case SNDCTL_DSP_GETBLKSIZE:
                res = snd_pcm_oss_get_block_size(pcm_oss_file);
                if (res < 0)
                        return res;
-               return put_user(res, (int *)arg);
+               return put_user(res, p);
        case SNDCTL_DSP_SETFMT:
-               if (get_user(res, (int *)arg))
+               if (get_user(res, p))
                        return -EFAULT;
                res = snd_pcm_oss_set_format(pcm_oss_file, res);
                if (res < 0)
                        return res;
-               return put_user(res, (int *)arg);
+               return put_user(res, p);
        case SOUND_PCM_READ_BITS:
                res = snd_pcm_oss_get_format(pcm_oss_file);
                if (res < 0)
                        return res;
-               return put_user(res, (int *)arg);
+               return put_user(res, p);
        case SNDCTL_DSP_CHANNELS:
-               if (get_user(res, (int *)arg))
+               if (get_user(res, p))
                        return -EFAULT;
                res = snd_pcm_oss_set_channels(pcm_oss_file, res);
                if (res < 0)
                        return res;
-               return put_user(res, (int *)arg);
+               return put_user(res, p);
        case SOUND_PCM_READ_CHANNELS:
                res = snd_pcm_oss_get_channels(pcm_oss_file);
                if (res < 0)
                        return res;
-               return put_user(res, (int *)arg);
+               return put_user(res, p);
        case SOUND_PCM_WRITE_FILTER:
        case SOUND_PCM_READ_FILTER:
                return -EIO;
        case SNDCTL_DSP_POST:
                return snd_pcm_oss_post(pcm_oss_file);
        case SNDCTL_DSP_SUBDIVIDE:
-               if (get_user(res, (int *)arg))
+               if (get_user(res, p))
                        return -EFAULT;
                res = snd_pcm_oss_set_subdivide(pcm_oss_file, res);
                if (res < 0)
                        return res;
-               return put_user(res, (int *)arg);
+               return put_user(res, p);
        case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(res, (int *)arg))
+               if (get_user(res, p))
                        return -EFAULT;
                return snd_pcm_oss_set_fragment(pcm_oss_file, res);
        case SNDCTL_DSP_GETFMTS:
                res = snd_pcm_oss_get_formats(pcm_oss_file);
                if (res < 0)
                        return res;
-               return put_user(res, (int *)arg);
+               return put_user(res, p);
        case SNDCTL_DSP_GETOSPACE:
        case SNDCTL_DSP_GETISPACE:
                return snd_pcm_oss_get_space(pcm_oss_file,
                        cmd == SNDCTL_DSP_GETISPACE ?
                                SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
-                       (struct audio_buf_info *) arg);
+                       (struct audio_buf_info __user *) arg);
        case SNDCTL_DSP_NONBLOCK:
                return snd_pcm_oss_nonblock(file);
        case SNDCTL_DSP_GETCAPS:
                res = snd_pcm_oss_get_caps(pcm_oss_file);
                if (res < 0)
                        return res;
-               return put_user(res, (int *)arg);
+               return put_user(res, p);
        case SNDCTL_DSP_GETTRIGGER:
                res = snd_pcm_oss_get_trigger(pcm_oss_file);
                if (res < 0)
                        return res;
-               return put_user(res, (int *)arg);
+               return put_user(res, p);
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(res, (int *)arg))
+               if (get_user(res, p))
                        return -EFAULT;
                return snd_pcm_oss_set_trigger(pcm_oss_file, res);
        case SNDCTL_DSP_GETIPTR:
@@ -2037,13 +2038,13 @@ static int snd_pcm_oss_ioctl(struct inode *inode, struct file *file,
                return snd_pcm_oss_get_ptr(pcm_oss_file,
                        cmd == SNDCTL_DSP_GETIPTR ?
                                SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
-                       (struct count_info *) arg);
+                       (struct count_info __user *) arg);
        case SNDCTL_DSP_MAPINBUF:
        case SNDCTL_DSP_MAPOUTBUF:
                return snd_pcm_oss_get_mapbuf(pcm_oss_file,
                        cmd == SNDCTL_DSP_MAPINBUF ?
                                SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
-                       (struct buffmem_desc *) arg);
+                       (struct buffmem_desc __user *) arg);
        case SNDCTL_DSP_SETSYNCRO:
                /* stop DMA now.. */
                return 0;
@@ -2055,10 +2056,10 @@ static int snd_pcm_oss_ioctl(struct inode *inode, struct file *file,
                res = snd_pcm_oss_get_odelay(pcm_oss_file);
                if (res < 0) {
                        /* it's for sure, some broken apps don't check for error codes */
-                       put_user(0, (int *)arg);
+                       put_user(0, p);
                        return res;
                }
-               return put_user(res, (int *)arg);
+               return put_user(res, p);
        case SNDCTL_DSP_PROFILE:
                return 0;       /* silently ignore */
        default:
@@ -2067,7 +2068,7 @@ static int snd_pcm_oss_ioctl(struct inode *inode, struct file *file,
        return -EINVAL;
 }
 
-static ssize_t snd_pcm_oss_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
        snd_pcm_oss_file_t *pcm_oss_file;
        snd_pcm_substream_t *substream;
@@ -2087,7 +2088,7 @@ static ssize_t snd_pcm_oss_read(struct file *file, char *buf, size_t count, loff
 #endif
 }
 
-static ssize_t snd_pcm_oss_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
 {
        snd_pcm_oss_file_t *pcm_oss_file;
        snd_pcm_substream_t *substream;
index 4f87974..7f1bf94 100644 (file)
@@ -55,7 +55,7 @@ static int snd_pcm_control_ioctl(snd_card_t * card,
                {
                        int device;
 
-                       if (get_user(device, (int *)arg))
+                       if (get_user(device, (int __user *)arg))
                                return -EFAULT;
                        device = device < 0 ? 0 : device + 1;
                        while (device < SNDRV_PCM_DEVICES) {
@@ -65,18 +65,19 @@ static int snd_pcm_control_ioctl(snd_card_t * card,
                        }
                        if (device == SNDRV_PCM_DEVICES)
                                device = -1;
-                       if (put_user(device, (int *)arg))
+                       if (put_user(device, (int __user *)arg))
                                return -EFAULT;
                        return 0;
                }
        case SNDRV_CTL_IOCTL_PCM_INFO:
                {
-                       snd_pcm_info_t *info = (snd_pcm_info_t *)arg;
+                       snd_pcm_info_t __user *info;
                        unsigned int device, subdevice;
                        snd_pcm_stream_t stream;
                        snd_pcm_t *pcm;
                        snd_pcm_str_t *pstr;
                        snd_pcm_substream_t *substream;
+                       info = (snd_pcm_info_t __user *)arg;
                        if (get_user(device, &info->device))
                                return -EFAULT;
                        if (device >= SNDRV_PCM_DEVICES)
@@ -106,7 +107,7 @@ static int snd_pcm_control_ioctl(snd_card_t * card,
                {
                        int val;
                        
-                       if (get_user(val, (int *)arg))
+                       if (get_user(val, (int __user *)arg))
                                return -EFAULT;
                        control->prefer_pcm_subdevice = val;
                        return 0;
index 49ab384..61d1c38 100644 (file)
@@ -2049,12 +2049,12 @@ void snd_pcm_period_elapsed(snd_pcm_substream_t *substream)
 
 static int snd_pcm_lib_write_transfer(snd_pcm_substream_t *substream,
                                      unsigned int hwoff,
-                                     void *data, unsigned int off,
+                                     unsigned long data, unsigned int off,
                                      snd_pcm_uframes_t frames)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
        int err;
-       char *buf = (char *) data + frames_to_bytes(runtime, off);
+       char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
        if (substream->ops->copy) {
                if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
                        return err;
@@ -2068,10 +2068,12 @@ static int snd_pcm_lib_write_transfer(snd_pcm_substream_t *substream,
 }
  
 typedef int (*transfer_f)(snd_pcm_substream_t *substream, unsigned int hwoff,
-                         void *data, unsigned int off, snd_pcm_uframes_t size);
+                         unsigned long data, unsigned int off,
+                         snd_pcm_uframes_t size);
 
 static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream, 
-                                           const void *data, snd_pcm_uframes_t size,
+                                           unsigned long data,
+                                           snd_pcm_uframes_t size,
                                            int nonblock,
                                            transfer_f transfer)
 {
@@ -2186,7 +2188,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream,
                appl_ptr = runtime->control->appl_ptr;
                appl_ofs = appl_ptr % runtime->buffer_size;
                snd_pcm_stream_unlock_irq(substream);
-               if ((err = transfer(substream, appl_ofs, (void *)data, offset, frames)) < 0)
+               if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0)
                        goto _end;
                snd_pcm_stream_lock_irq(substream);
                switch (runtime->status->state) {
@@ -2227,7 +2229,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream,
        return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
 }
 
-snd_pcm_sframes_t snd_pcm_lib_write(snd_pcm_substream_t *substream, const void *buf, snd_pcm_uframes_t size)
+snd_pcm_sframes_t snd_pcm_lib_write(snd_pcm_substream_t *substream, const void __user *buf, snd_pcm_uframes_t size)
 {
        snd_pcm_runtime_t *runtime;
        int nonblock;
@@ -2256,18 +2258,18 @@ snd_pcm_sframes_t snd_pcm_lib_write(snd_pcm_substream_t *substream, const void *
        if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
            runtime->channels > 1)
                return -EINVAL;
-       return snd_pcm_lib_write1(substream, buf, size, nonblock,
+       return snd_pcm_lib_write1(substream, (unsigned long)buf, size, nonblock,
                                  snd_pcm_lib_write_transfer);
 }
 
 static int snd_pcm_lib_writev_transfer(snd_pcm_substream_t *substream,
                                       unsigned int hwoff,
-                                      void *data, unsigned int off,
+                                      unsigned long data, unsigned int off,
                                       snd_pcm_uframes_t frames)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
        int err;
-       void **bufs = data;
+       void __user **bufs = (void __user **)data;
        int channels = runtime->channels;
        int c;
        if (substream->ops->copy) {
@@ -2277,7 +2279,7 @@ static int snd_pcm_lib_writev_transfer(snd_pcm_substream_t *substream,
                                if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0)
                                        return err;
                        } else {
-                               char *buf = *bufs + samples_to_bytes(runtime, off);
+                               char __user *buf = *bufs + samples_to_bytes(runtime, off);
                                if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0)
                                        return err;
                        }
@@ -2291,7 +2293,7 @@ static int snd_pcm_lib_writev_transfer(snd_pcm_substream_t *substream,
                        if (*bufs == NULL) {
                                snd_pcm_format_set_silence(runtime->format, hwbuf, frames);
                        } else {
-                               char *buf = *bufs + samples_to_bytes(runtime, off);
+                               char __user *buf = *bufs + samples_to_bytes(runtime, off);
                                if (copy_from_user(hwbuf, buf, samples_to_bytes(runtime, frames)))
                                        return -EFAULT;
                        }
@@ -2300,7 +2302,8 @@ static int snd_pcm_lib_writev_transfer(snd_pcm_substream_t *substream,
        return 0;
 }
  
-snd_pcm_sframes_t snd_pcm_lib_writev(snd_pcm_substream_t *substream, void **bufs,
+snd_pcm_sframes_t snd_pcm_lib_writev(snd_pcm_substream_t *substream,
+                                    void __user **bufs,
                                     snd_pcm_uframes_t frames)
 {
        snd_pcm_runtime_t *runtime;
@@ -2329,18 +2332,18 @@ snd_pcm_sframes_t snd_pcm_lib_writev(snd_pcm_substream_t *substream, void **bufs
 
        if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
                return -EINVAL;
-       return snd_pcm_lib_write1(substream, bufs, frames, nonblock,
-                                 snd_pcm_lib_writev_transfer);
+       return snd_pcm_lib_write1(substream, (unsigned long)bufs, frames,
+                                 nonblock, snd_pcm_lib_writev_transfer);
 }
 
 static int snd_pcm_lib_read_transfer(snd_pcm_substream_t *substream, 
                                     unsigned int hwoff,
-                                    void *data, unsigned int off,
+                                    unsigned long data, unsigned int off,
                                     snd_pcm_uframes_t frames)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
        int err;
-       char *buf = (char *) data + frames_to_bytes(runtime, off);
+       char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
        if (substream->ops->copy) {
                if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
                        return err;
@@ -2353,7 +2356,10 @@ static int snd_pcm_lib_read_transfer(snd_pcm_substream_t *substream,
        return 0;
 }
 
-static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, void *data, snd_pcm_uframes_t size, int nonblock,
+static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream,
+                                          unsigned long data,
+                                          snd_pcm_uframes_t size,
+                                          int nonblock,
                                           transfer_f transfer)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
@@ -2481,7 +2487,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, void
                appl_ptr = runtime->control->appl_ptr;
                appl_ofs = appl_ptr % runtime->buffer_size;
                snd_pcm_stream_unlock_irq(substream);
-               if ((err = transfer(substream, appl_ofs, (void *)data, offset, frames)) < 0)
+               if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0)
                        goto _end;
                snd_pcm_stream_lock_irq(substream);
                switch (runtime->status->state) {
@@ -2516,7 +2522,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, void
        return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
 }
 
-snd_pcm_sframes_t snd_pcm_lib_read(snd_pcm_substream_t *substream, void *buf, snd_pcm_uframes_t size)
+snd_pcm_sframes_t snd_pcm_lib_read(snd_pcm_substream_t *substream, void __user *buf, snd_pcm_uframes_t size)
 {
        snd_pcm_runtime_t *runtime;
        int nonblock;
@@ -2543,22 +2549,22 @@ snd_pcm_sframes_t snd_pcm_lib_read(snd_pcm_substream_t *substream, void *buf, sn
 #endif
        if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED)
                return -EINVAL;
-       return snd_pcm_lib_read1(substream, buf, size, nonblock, snd_pcm_lib_read_transfer);
+       return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer);
 }
 
 static int snd_pcm_lib_readv_transfer(snd_pcm_substream_t *substream,
                                      unsigned int hwoff,
-                                     void *data, unsigned int off,
+                                     unsigned long data, unsigned int off,
                                      snd_pcm_uframes_t frames)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
        int err;
-       void **bufs = data;
+       void __user **bufs = (void __user **)data;
        int channels = runtime->channels;
        int c;
        if (substream->ops->copy) {
                for (c = 0; c < channels; ++c, ++bufs) {
-                       char *buf;
+                       char __user *buf;
                        if (*bufs == NULL)
                                continue;
                        buf = *bufs + samples_to_bytes(runtime, off);
@@ -2569,7 +2575,8 @@ static int snd_pcm_lib_readv_transfer(snd_pcm_substream_t *substream,
                snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels;
                snd_assert(runtime->dma_area, return -EFAULT);
                for (c = 0; c < channels; ++c, ++bufs) {
-                       char *hwbuf, *buf;
+                       char *hwbuf;
+                       char __user *buf;
                        if (*bufs == NULL)
                                continue;
 
@@ -2582,7 +2589,8 @@ static int snd_pcm_lib_readv_transfer(snd_pcm_substream_t *substream,
        return 0;
 }
  
-snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream, void **bufs,
+snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream,
+                                   void __user **bufs,
                                    snd_pcm_uframes_t frames)
 {
        snd_pcm_runtime_t *runtime;
@@ -2611,7 +2619,7 @@ snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream, void **bufs,
 
        if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
                return -EINVAL;
-       return snd_pcm_lib_read1(substream, bufs, frames, nonblock, snd_pcm_lib_readv_transfer);
+       return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer);
 }
 
 /*
index 38d5641..15ed2b9 100644 (file)
@@ -56,8 +56,8 @@ struct sndrv_pcm_hw_params_old {
 #define SNDRV_PCM_IOCTL_HW_REFINE_OLD _IOWR('A', 0x10, struct sndrv_pcm_hw_params_old)
 #define SNDRV_PCM_IOCTL_HW_PARAMS_OLD _IOWR('A', 0x11, struct sndrv_pcm_hw_params_old)
 
-static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old * _oparams);
-static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old * _oparams);
+static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams);
+static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams);
 
 /*
  *
@@ -108,7 +108,7 @@ int snd_pcm_info(snd_pcm_substream_t * substream, snd_pcm_info_t *info)
        return 0;
 }
 
-int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t * _info)
+int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t __user * _info)
 {
        snd_pcm_info_t info;
        int err = snd_pcm_info(substream, &info);
@@ -302,7 +302,7 @@ int snd_pcm_hw_refine(snd_pcm_substream_t *substream,
        return 0;
 }
 
-static int snd_pcm_hw_refine_user(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * _params)
+static int snd_pcm_hw_refine_user(snd_pcm_substream_t * substream, snd_pcm_hw_params_t __user * _params)
 {
        snd_pcm_hw_params_t params;
        int err;
@@ -406,7 +406,7 @@ static int snd_pcm_hw_params(snd_pcm_substream_t *substream,
        return err;
 }
 
-static int snd_pcm_hw_params_user(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * _params)
+static int snd_pcm_hw_params_user(snd_pcm_substream_t * substream, snd_pcm_hw_params_t __user * _params)
 {
        snd_pcm_hw_params_t params;
        int err;
@@ -494,7 +494,7 @@ static int snd_pcm_sw_params(snd_pcm_substream_t * substream, snd_pcm_sw_params_
        return 0;
 }
 
-static int snd_pcm_sw_params_user(snd_pcm_substream_t * substream, snd_pcm_sw_params_t * _params)
+static int snd_pcm_sw_params_user(snd_pcm_substream_t * substream, snd_pcm_sw_params_t __user * _params)
 {
        snd_pcm_sw_params_t params;
        int err;
@@ -550,7 +550,7 @@ int snd_pcm_status(snd_pcm_substream_t *substream,
        return 0;
 }
 
-static int snd_pcm_status_user(snd_pcm_substream_t * substream, snd_pcm_status_t * _status)
+static int snd_pcm_status_user(snd_pcm_substream_t * substream, snd_pcm_status_t __user * _status)
 {
        snd_pcm_status_t status;
        snd_pcm_runtime_t *runtime;
@@ -567,7 +567,7 @@ static int snd_pcm_status_user(snd_pcm_substream_t * substream, snd_pcm_status_t
        return 0;
 }
 
-static int snd_pcm_channel_info(snd_pcm_substream_t * substream, snd_pcm_channel_info_t * _info)
+static int snd_pcm_channel_info(snd_pcm_substream_t * substream, snd_pcm_channel_info_t __user * _info)
 {
        snd_pcm_channel_info_t info;
        snd_pcm_runtime_t *runtime;
@@ -2297,7 +2297,7 @@ static int snd_pcm_hwsync(snd_pcm_substream_t *substream)
        return err;
 }
                
-static int snd_pcm_delay(snd_pcm_substream_t *substream, snd_pcm_sframes_t *res)
+static int snd_pcm_delay(snd_pcm_substream_t *substream, snd_pcm_sframes_t __user *res)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
        int err;
@@ -2335,7 +2335,7 @@ static int snd_pcm_delay(snd_pcm_substream_t *substream, snd_pcm_sframes_t *res)
        return err;
 }
                
-static int snd_pcm_sync_ptr(snd_pcm_substream_t *substream, struct sndrv_pcm_sync_ptr *_sync_ptr)
+static int snd_pcm_sync_ptr(snd_pcm_substream_t *substream, struct sndrv_pcm_sync_ptr __user *_sync_ptr)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
        struct sndrv_pcm_sync_ptr sync_ptr;
@@ -2344,7 +2344,7 @@ static int snd_pcm_sync_ptr(snd_pcm_substream_t *substream, struct sndrv_pcm_syn
        int err;
 
        memset(&sync_ptr, 0, sizeof(sync_ptr));
-       if (get_user(sync_ptr.flags, (unsigned int *) &(_sync_ptr->flags)))
+       if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
                return -EFAULT;
        if (copy_from_user(&sync_ptr.c.control, &(_sync_ptr->c.control), sizeof(struct sndrv_pcm_mmap_control)))
                return -EFAULT; 
@@ -2375,40 +2375,40 @@ static int snd_pcm_sync_ptr(snd_pcm_substream_t *substream, struct sndrv_pcm_syn
 }
                
 static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
-                                  unsigned int cmd, void *arg);
+                                  unsigned int cmd, void __user *arg);
 static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
-                                 unsigned int cmd, void *arg);
+                                 unsigned int cmd, void __user *arg);
 
 static int snd_pcm_common_ioctl1(snd_pcm_substream_t *substream,
-                                unsigned int cmd, void *arg)
+                                unsigned int cmd, void __user *arg)
 {
        snd_assert(substream != NULL, return -ENXIO);
 
        switch (cmd) {
        case SNDRV_PCM_IOCTL_PVERSION:
-               return put_user(SNDRV_PCM_VERSION, (int *)arg) ? -EFAULT : 0;
+               return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
        case SNDRV_PCM_IOCTL_INFO:
-               return snd_pcm_info_user(substream, (snd_pcm_info_t *) arg);
+               return snd_pcm_info_user(substream, arg);
        case SNDRV_PCM_IOCTL_TSTAMP:
        {
                int xarg;
-               if (get_user(xarg, (int *) arg))
+               if (get_user(xarg, (int __user *)arg))
                        return -EFAULT;
                substream->runtime->tstamp_timespec = xarg ? 1 : 0;
                return 0;
        }
        case SNDRV_PCM_IOCTL_HW_REFINE:
-               return snd_pcm_hw_refine_user(substream, (snd_pcm_hw_params_t *) arg);
+               return snd_pcm_hw_refine_user(substream, arg);
        case SNDRV_PCM_IOCTL_HW_PARAMS:
-               return snd_pcm_hw_params_user(substream, (snd_pcm_hw_params_t *) arg);
+               return snd_pcm_hw_params_user(substream, arg);
        case SNDRV_PCM_IOCTL_HW_FREE:
                return snd_pcm_hw_free(substream);
        case SNDRV_PCM_IOCTL_SW_PARAMS:
-               return snd_pcm_sw_params_user(substream, (snd_pcm_sw_params_t *) arg);
+               return snd_pcm_sw_params_user(substream, arg);
        case SNDRV_PCM_IOCTL_STATUS:
-               return snd_pcm_status_user(substream, (snd_pcm_status_t *) arg);
+               return snd_pcm_status_user(substream, arg);
        case SNDRV_PCM_IOCTL_CHANNEL_INFO:
-               return snd_pcm_channel_info(substream, (snd_pcm_channel_info_t *) arg);
+               return snd_pcm_channel_info(substream, arg);
        case SNDRV_PCM_IOCTL_PREPARE:
                return snd_pcm_prepare(substream);
        case SNDRV_PCM_IOCTL_RESET:
@@ -2416,7 +2416,7 @@ static int snd_pcm_common_ioctl1(snd_pcm_substream_t *substream,
        case SNDRV_PCM_IOCTL_START:
                return snd_pcm_action_lock_irq(&snd_pcm_action_start, substream, 0, 0);
        case SNDRV_PCM_IOCTL_LINK:
-               return snd_pcm_link(substream, (long) arg);
+               return snd_pcm_link(substream, (int)(unsigned long) arg);
        case SNDRV_PCM_IOCTL_UNLINK:
                return snd_pcm_unlink(substream);
        case SNDRV_PCM_IOCTL_RESUME:
@@ -2426,27 +2426,28 @@ static int snd_pcm_common_ioctl1(snd_pcm_substream_t *substream,
        case SNDRV_PCM_IOCTL_HWSYNC:
                return snd_pcm_hwsync(substream);
        case SNDRV_PCM_IOCTL_DELAY:
-               return snd_pcm_delay(substream, (snd_pcm_sframes_t *) arg);
+               return snd_pcm_delay(substream, arg);
        case SNDRV_PCM_IOCTL_SYNC_PTR:
-               return snd_pcm_sync_ptr(substream, (struct sndrv_pcm_sync_ptr *) arg);
+               return snd_pcm_sync_ptr(substream, arg);
        case SNDRV_PCM_IOCTL_HW_REFINE_OLD:
-               return snd_pcm_hw_refine_old_user(substream, (struct sndrv_pcm_hw_params_old *) arg);
+               return snd_pcm_hw_refine_old_user(substream, arg);
        case SNDRV_PCM_IOCTL_HW_PARAMS_OLD:
-               return snd_pcm_hw_params_old_user(substream, (struct sndrv_pcm_hw_params_old *) arg);
+               return snd_pcm_hw_params_old_user(substream, arg);
        }
        snd_printd("unknown ioctl = 0x%x\n", cmd);
        return -ENOTTY;
 }
 
 static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
-                                  unsigned int cmd, void *arg)
+                                  unsigned int cmd, void __user *arg)
 {
        snd_assert(substream != NULL, return -ENXIO);
        snd_assert(substream->stream == SNDRV_PCM_STREAM_PLAYBACK, return -EINVAL);
        switch (cmd) {
        case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
        {
-               snd_xferi_t xferi, *_xferi = arg;
+               snd_xferi_t xferi;
+               snd_xferi_t __user *_xferi = arg;
                snd_pcm_runtime_t *runtime = substream->runtime;
                snd_pcm_sframes_t result;
                if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
@@ -2461,9 +2462,10 @@ static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
        }
        case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
        {
-               snd_xfern_t xfern, *_xfern = arg;
+               snd_xfern_t xfern;
+               snd_xfern_t __user *_xfern = arg;
                snd_pcm_runtime_t *runtime = substream->runtime;
-               void *bufs;
+               void __user **bufs;
                snd_pcm_sframes_t result;
                if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
                        return -EBADFD;
@@ -2487,7 +2489,8 @@ static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
        }
        case SNDRV_PCM_IOCTL_REWIND:
        {
-               snd_pcm_uframes_t frames, *_frames = arg;
+               snd_pcm_uframes_t frames;
+               snd_pcm_uframes_t __user *_frames = arg;
                snd_pcm_sframes_t result;
                if (get_user(frames, _frames))
                        return -EFAULT;
@@ -2499,7 +2502,8 @@ static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
        }
        case SNDRV_PCM_IOCTL_FORWARD:
        {
-               snd_pcm_uframes_t frames, *_frames = arg;
+               snd_pcm_uframes_t frames;
+               snd_pcm_uframes_t __user *_frames = arg;
                snd_pcm_sframes_t result;
                if (get_user(frames, _frames))
                        return -EFAULT;
@@ -2513,7 +2517,7 @@ static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
        {
                int res;
                snd_pcm_stream_lock_irq(substream);
-               res = snd_pcm_pause(substream, (long) arg);
+               res = snd_pcm_pause(substream, (int)(unsigned long)arg);
                snd_pcm_stream_unlock_irq(substream);
                return res;
        }
@@ -2526,14 +2530,15 @@ static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
 }
 
 static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
-                                 unsigned int cmd, void *arg)
+                                 unsigned int cmd, void __user *arg)
 {
        snd_assert(substream != NULL, return -ENXIO);
        snd_assert(substream->stream == SNDRV_PCM_STREAM_CAPTURE, return -EINVAL);
        switch (cmd) {
        case SNDRV_PCM_IOCTL_READI_FRAMES:
        {
-               snd_xferi_t xferi, *_xferi = arg;
+               snd_xferi_t xferi;
+               snd_xferi_t __user *_xferi = arg;
                snd_pcm_runtime_t *runtime = substream->runtime;
                snd_pcm_sframes_t result;
                if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
@@ -2548,7 +2553,8 @@ static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
        }
        case SNDRV_PCM_IOCTL_READN_FRAMES:
        {
-               snd_xfern_t xfern, *_xfern = arg;
+               snd_xfern_t xfern;
+               snd_xfern_t __user *_xfern = arg;
                snd_pcm_runtime_t *runtime = substream->runtime;
                void *bufs;
                snd_pcm_sframes_t result;
@@ -2574,7 +2580,8 @@ static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
        }
        case SNDRV_PCM_IOCTL_REWIND:
        {
-               snd_pcm_uframes_t frames, *_frames = arg;
+               snd_pcm_uframes_t frames;
+               snd_pcm_uframes_t __user *_frames = arg;
                snd_pcm_sframes_t result;
                if (get_user(frames, _frames))
                        return -EFAULT;
@@ -2586,7 +2593,8 @@ static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
        }
        case SNDRV_PCM_IOCTL_FORWARD:
        {
-               snd_pcm_uframes_t frames, *_frames = arg;
+               snd_pcm_uframes_t frames;
+               snd_pcm_uframes_t __user *_frames = arg;
                snd_pcm_sframes_t result;
                if (get_user(frames, _frames))
                        return -EFAULT;
@@ -2614,7 +2622,7 @@ static int snd_pcm_playback_ioctl(struct inode *inode, struct file *file,
        if (((cmd >> 8) & 0xff) != 'A')
                return -ENOTTY;
 
-       return snd_pcm_playback_ioctl1(pcm_file->substream, cmd, (void *) arg);
+       return snd_pcm_playback_ioctl1(pcm_file->substream, cmd, (void __user *)arg);
 }
 
 static int snd_pcm_capture_ioctl(struct inode *inode, struct file *file,
@@ -2627,7 +2635,7 @@ static int snd_pcm_capture_ioctl(struct inode *inode, struct file *file,
        if (((cmd >> 8) & 0xff) != 'A')
                return -ENOTTY;
 
-       return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void *) arg);
+       return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg);
 }
 
 int snd_pcm_kernel_playback_ioctl(snd_pcm_substream_t *substream,
@@ -2667,7 +2675,7 @@ int snd_pcm_kernel_ioctl(snd_pcm_substream_t *substream,
        }
 }
 
-static ssize_t snd_pcm_read(struct file *file, char *buf, size_t count, loff_t * offset)
+static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, loff_t * offset)
 {
        snd_pcm_file_t *pcm_file;
        snd_pcm_substream_t *substream;
@@ -2689,7 +2697,7 @@ static ssize_t snd_pcm_read(struct file *file, char *buf, size_t count, loff_t *
        return result;
 }
 
-static ssize_t snd_pcm_write(struct file *file, const char *buf, size_t count, loff_t * offset)
+static ssize_t snd_pcm_write(struct file *file, const char __user *buf, size_t count, loff_t * offset)
 {
        snd_pcm_file_t *pcm_file;
        snd_pcm_substream_t *substream;
@@ -2725,7 +2733,7 @@ static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
        snd_pcm_runtime_t *runtime;
        snd_pcm_sframes_t result;
        unsigned long i;
-       void **bufs;
+       void __user **bufs;
        snd_pcm_uframes_t frames;
 
        pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, return -ENXIO);
@@ -2759,7 +2767,7 @@ static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
        snd_pcm_runtime_t *runtime;
        snd_pcm_sframes_t result;
        unsigned long i;
-       void **bufs;
+       void __user **bufs;
        snd_pcm_uframes_t frames;
 
        pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, result = -ENXIO; goto end);
@@ -3123,7 +3131,7 @@ static void snd_pcm_hw_convert_to_old_params(struct sndrv_pcm_hw_params_old *opa
        oparams->fifo_size = params->fifo_size;
 }
 
-static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old * _oparams)
+static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams)
 {
        snd_pcm_hw_params_t params;
        struct sndrv_pcm_hw_params_old oparams;
@@ -3138,7 +3146,7 @@ static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sn
        return err;
 }
 
-static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old * _oparams)
+static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams)
 {
        snd_pcm_hw_params_t params;
        struct sndrv_pcm_hw_params_old oparams;
index abc2221..df904d1 100644 (file)
@@ -543,7 +543,7 @@ int snd_rawmidi_info(snd_rawmidi_substream_t *substream, snd_rawmidi_info_t *inf
        return 0;
 }
 
-static int snd_rawmidi_info_user(snd_rawmidi_substream_t *substream, snd_rawmidi_info_t * _info)
+static int snd_rawmidi_info_user(snd_rawmidi_substream_t *substream, snd_rawmidi_info_t __user * _info)
 {
        snd_rawmidi_info_t info;
        int err;
@@ -579,7 +579,7 @@ int snd_rawmidi_info_select(snd_card_t *card, snd_rawmidi_info_t *info)
 }
 
 static int snd_rawmidi_info_select_user(snd_card_t *card,
-                                       snd_rawmidi_info_t *_info)
+                                       snd_rawmidi_info_t __user *_info)
 {
        int err;
        snd_rawmidi_info_t info;
@@ -679,17 +679,18 @@ static int snd_rawmidi_ioctl(struct inode *inode, struct file *file,
                             unsigned int cmd, unsigned long arg)
 {
        snd_rawmidi_file_t *rfile;
+       void __user *argp = (void __user *)arg;
 
        rfile = snd_magic_cast(snd_rawmidi_file_t, file->private_data, return -ENXIO);
        if (((cmd >> 8) & 0xff) != 'W')
                return -ENOTTY;
        switch (cmd) {
        case SNDRV_RAWMIDI_IOCTL_PVERSION:
-               return put_user(SNDRV_RAWMIDI_VERSION, (int *)arg) ? -EFAULT : 0;
+               return put_user(SNDRV_RAWMIDI_VERSION, (int __user *)argp) ? -EFAULT : 0;
        case SNDRV_RAWMIDI_IOCTL_INFO:
        {
                snd_rawmidi_stream_t stream;
-               snd_rawmidi_info_t *info = (snd_rawmidi_info_t *) arg;
+               snd_rawmidi_info_t __user *info = argp;
                if (get_user(stream, &info->stream))
                        return -EFAULT;
                switch (stream) {
@@ -704,7 +705,7 @@ static int snd_rawmidi_ioctl(struct inode *inode, struct file *file,
        case SNDRV_RAWMIDI_IOCTL_PARAMS:
        {
                snd_rawmidi_params_t params;
-               if (copy_from_user(&params, (snd_rawmidi_params_t *) arg, sizeof(snd_rawmidi_params_t)))
+               if (copy_from_user(&params, argp, sizeof(snd_rawmidi_params_t)))
                        return -EFAULT;
                switch (params.stream) {
                case SNDRV_RAWMIDI_STREAM_OUTPUT:
@@ -723,7 +724,7 @@ static int snd_rawmidi_ioctl(struct inode *inode, struct file *file,
        {
                int err = 0;
                snd_rawmidi_status_t status;
-               if (copy_from_user(&status, (snd_rawmidi_status_t *) arg, sizeof(snd_rawmidi_status_t)))
+               if (copy_from_user(&status, argp, sizeof(snd_rawmidi_status_t)))
                        return -EFAULT;
                switch (status.stream) {
                case SNDRV_RAWMIDI_STREAM_OUTPUT:
@@ -741,14 +742,14 @@ static int snd_rawmidi_ioctl(struct inode *inode, struct file *file,
                }
                if (err < 0)
                        return err;
-               if (copy_to_user((snd_rawmidi_status_t *) arg, &status, sizeof(snd_rawmidi_status_t)))
+               if (copy_to_user(argp, &status, sizeof(snd_rawmidi_status_t)))
                        return -EFAULT;
                return 0;
        }
        case SNDRV_RAWMIDI_IOCTL_DROP:
        {
                int val;
-               if (get_user(val, (long *) arg))
+               if (get_user(val, (long __user *) argp))
                        return -EFAULT;
                switch (val) {
                case SNDRV_RAWMIDI_STREAM_OUTPUT:
@@ -762,7 +763,7 @@ static int snd_rawmidi_ioctl(struct inode *inode, struct file *file,
        case SNDRV_RAWMIDI_IOCTL_DRAIN:
        {
                int val;
-               if (get_user(val, (long *) arg))
+               if (get_user(val, (long __user *) argp))
                        return -EFAULT;
                switch (val) {
                case SNDRV_RAWMIDI_STREAM_OUTPUT:
@@ -788,6 +789,7 @@ static int snd_rawmidi_ioctl(struct inode *inode, struct file *file,
 int snd_rawmidi_control_ioctl(snd_card_t * card, snd_ctl_file_t * control,
                              unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
        unsigned int tmp;
 
        tmp = card->number * SNDRV_RAWMIDI_DEVICES;
@@ -796,7 +798,7 @@ int snd_rawmidi_control_ioctl(snd_card_t * card, snd_ctl_file_t * control,
        {
                int device;
                
-               if (get_user(device, (int *)arg))
+               if (get_user(device, (int __user *)argp))
                        return -EFAULT;
                device = device < 0 ? 0 : device + 1;
                while (device < SNDRV_RAWMIDI_DEVICES) {
@@ -806,7 +808,7 @@ int snd_rawmidi_control_ioctl(snd_card_t * card, snd_ctl_file_t * control,
                }
                if (device == SNDRV_RAWMIDI_DEVICES)
                        device = -1;
-               if (put_user(device, (int *)arg))
+               if (put_user(device, (int __user *)argp))
                        return -EFAULT;
                return 0;
        }
@@ -814,13 +816,13 @@ int snd_rawmidi_control_ioctl(snd_card_t * card, snd_ctl_file_t * control,
        {
                int val;
                
-               if (get_user(val, (int *)arg))
+               if (get_user(val, (int __user *)argp))
                        return -EFAULT;
                control->prefer_rawmidi_subdevice = val;
                return 0;
        }
        case SNDRV_CTL_IOCTL_RAWMIDI_INFO:
-               return snd_rawmidi_info_select_user(card, (snd_rawmidi_info_t *)arg);
+               return snd_rawmidi_info_select_user(card, argp);
        }
        return -ENOIOCTLCMD;
 }
@@ -934,7 +936,7 @@ long snd_rawmidi_kernel_read(snd_rawmidi_substream_t *substream, unsigned char *
        return snd_rawmidi_kernel_read1(substream, buf, count, 1);
 }
 
-static ssize_t snd_rawmidi_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
        long result;
        int count1;
@@ -1166,7 +1168,7 @@ long snd_rawmidi_kernel_write(snd_rawmidi_substream_t * substream, const unsigne
        return snd_rawmidi_kernel_write1(substream, buf, count, 1);
 }
 
-static ssize_t snd_rawmidi_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
 {
        long result, timeout;
        int count1;
index 1c4d10d..e731cdc 100644 (file)
@@ -51,7 +51,6 @@ obj-$(call sequencer,$(CONFIG_SND_AD1816A)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
 obj-$(call sequencer,$(CONFIG_SND_CS4231)) += $(RAWMIDI_OBJS)
 obj-$(call sequencer,$(CONFIG_SND_CS4232)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
 obj-$(call sequencer,$(CONFIG_SND_CS4236)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(call sequencer,$(CONFIG_SND_PC98_CS4232)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
 obj-$(call sequencer,$(CONFIG_SND_ES1688)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
 obj-$(call sequencer,$(CONFIG_SND_GUSCLASSIC)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
 obj-$(call sequencer,$(CONFIG_SND_GUSMAX)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
index 8db86fe..5ae3552 100644 (file)
@@ -26,7 +26,6 @@ obj-$(call sequencer,$(CONFIG_SND_OPL3SA2)) += snd-ainstr-fm.o
 obj-$(call sequencer,$(CONFIG_SND_AD1816A)) += snd-ainstr-fm.o
 obj-$(call sequencer,$(CONFIG_SND_CS4232)) += snd-ainstr-fm.o
 obj-$(call sequencer,$(CONFIG_SND_CS4236)) += snd-ainstr-fm.o
-obj-$(call sequencer,$(CONFIG_SND_PC98_CS4232)) += snd-ainstr-fm.o
 obj-$(call sequencer,$(CONFIG_SND_ES1688)) += snd-ainstr-fm.o
 obj-$(call sequencer,$(CONFIG_SND_GUSCLASSIC)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
 obj-$(call sequencer,$(CONFIG_SND_GUSMAX)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
index aabb0c2..648a7b8 100644 (file)
@@ -35,7 +35,7 @@ MODULE_SUPPORTED_DEVICE("sound");
 char *snd_seq_fm_id = SNDRV_SEQ_INSTR_ID_OPL2_3;
 
 static int snd_seq_fm_put(void *private_data, snd_seq_kinstr_t *instr,
-                         char *instr_data, long len, int atomic, int cmd)
+                         char __user *instr_data, long len, int atomic, int cmd)
 {
        fm_instrument_t *ip;
        fm_xinstrument_t ix;
@@ -77,7 +77,8 @@ static int snd_seq_fm_put(void *private_data, snd_seq_kinstr_t *instr,
 }
 
 static int snd_seq_fm_get(void *private_data, snd_seq_kinstr_t *instr,
-                         char *instr_data, long len, int atomic, int cmd)
+                         char __user *instr_data, long len, int atomic,
+                         int cmd)
 {
        fm_instrument_t *ip;
        fm_xinstrument_t ix;
index d1029df..13b46be 100644 (file)
@@ -48,7 +48,7 @@ static unsigned int snd_seq_gf1_size(unsigned int size, unsigned int format)
 
 static int snd_seq_gf1_copy_wave_from_stream(snd_gf1_ops_t *ops,
                                             gf1_instrument_t *ip,
-                                            char **data,
+                                            char __user **data,
                                             long *len,
                                             int atomic)
 {
@@ -141,7 +141,8 @@ static void snd_seq_gf1_instr_free(snd_gf1_ops_t *ops,
 }
 
 static int snd_seq_gf1_put(void *private_data, snd_seq_kinstr_t *instr,
-                          char *instr_data, long len, int atomic, int cmd)
+                          char __user *instr_data, long len, int atomic,
+                          int cmd)
 {
        snd_gf1_ops_t *ops = (snd_gf1_ops_t *)private_data;
        gf1_instrument_t *ip;
@@ -192,7 +193,7 @@ static int snd_seq_gf1_put(void *private_data, snd_seq_kinstr_t *instr,
 
 static int snd_seq_gf1_copy_wave_to_stream(snd_gf1_ops_t *ops,
                                           gf1_instrument_t *ip,
-                                          char **data,
+                                          char __user **data,
                                           long *len,
                                           int atomic)
 {
@@ -253,7 +254,8 @@ static int snd_seq_gf1_copy_wave_to_stream(snd_gf1_ops_t *ops,
 }
 
 static int snd_seq_gf1_get(void *private_data, snd_seq_kinstr_t *instr,
-                          char *instr_data, long len, int atomic, int cmd)
+                          char __user *instr_data, long len, int atomic,
+                          int cmd)
 {
        snd_gf1_ops_t *ops = (snd_gf1_ops_t *)private_data;
        gf1_instrument_t *ip;
index 121e09c..cd9ea55 100644 (file)
@@ -60,7 +60,7 @@ static int snd_seq_iwffff_copy_env_from_stream(__u32 req_stype,
                                               iwffff_layer_t *lp,
                                               iwffff_env_t *ep,
                                               iwffff_xenv_t *ex,
-                                              char **data,
+                                              char __user **data,
                                               long *len,
                                               int gfp_mask)
 {
@@ -126,7 +126,7 @@ static int snd_seq_iwffff_copy_env_from_stream(__u32 req_stype,
 
 static int snd_seq_iwffff_copy_wave_from_stream(snd_iwffff_ops_t *ops,
                                                iwffff_layer_t *lp,
-                                               char **data,
+                                               char __user **data,
                                                long *len,
                                                int atomic)
 {
@@ -230,7 +230,8 @@ static void snd_seq_iwffff_instr_free(snd_iwffff_ops_t *ops,
 }
 
 static int snd_seq_iwffff_put(void *private_data, snd_seq_kinstr_t *instr,
-                             char *instr_data, long len, int atomic, int cmd)
+                             char __user *instr_data, long len, int atomic,
+                             int cmd)
 {
        snd_iwffff_ops_t *ops = (snd_iwffff_ops_t *)private_data;
        iwffff_instrument_t *ip;
@@ -350,7 +351,7 @@ static int snd_seq_iwffff_copy_env_to_stream(__u32 req_stype,
                                             iwffff_layer_t *lp,
                                             iwffff_xenv_t *ex,
                                             iwffff_env_t *ep,
-                                            char **data,
+                                            char __user **data,
                                             long *len)
 {
        iwffff_env_record_t *rp;
@@ -395,7 +396,7 @@ static int snd_seq_iwffff_copy_env_to_stream(__u32 req_stype,
 
 static int snd_seq_iwffff_copy_wave_to_stream(snd_iwffff_ops_t *ops,
                                              iwffff_layer_t *lp,
-                                             char **data,
+                                             char __user **data,
                                              long *len,
                                              int atomic)
 {
@@ -449,14 +450,14 @@ static int snd_seq_iwffff_copy_wave_to_stream(snd_iwffff_ops_t *ops,
 }
 
 static int snd_seq_iwffff_get(void *private_data, snd_seq_kinstr_t *instr,
-                             char *instr_data, long len, int atomic, int cmd)
+                             char __user *instr_data, long len, int atomic, int cmd)
 {
        snd_iwffff_ops_t *ops = (snd_iwffff_ops_t *)private_data;
        iwffff_instrument_t *ip;
        iwffff_xinstrument_t ix;
        iwffff_layer_t *lp;
        iwffff_xlayer_t lx;
-       char *layer_instr_data;
+       char __user *layer_instr_data;
        int err;
        
        if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
index 575b1e8..0f81178 100644 (file)
@@ -55,7 +55,8 @@ static void snd_seq_simple_instr_free(snd_simple_ops_t *ops,
 }
 
 static int snd_seq_simple_put(void *private_data, snd_seq_kinstr_t *instr,
-                             char *instr_data, long len, int atomic, int cmd)
+                             char __user *instr_data, long len,
+                             int atomic, int cmd)
 {
        snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
        simple_instrument_t *ip;
@@ -103,7 +104,8 @@ static int snd_seq_simple_put(void *private_data, snd_seq_kinstr_t *instr,
 }
 
 static int snd_seq_simple_get(void *private_data, snd_seq_kinstr_t *instr,
-                             char *instr_data, long len, int atomic, int cmd)
+                             char __user *instr_data, long len,
+                             int atomic, int cmd)
 {
        snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
        simple_instrument_t *ip;
index 50a3740..5681563 100644 (file)
@@ -57,8 +57,8 @@ static void unregister_proc(void);
 
 static int odev_open(struct inode *inode, struct file *file);
 static int odev_release(struct inode *inode, struct file *file);
-static ssize_t odev_read(struct file *file, char *buf, size_t count, loff_t *offset);
-static ssize_t odev_write(struct file *file, const char *buf, size_t count, loff_t *offset);
+static ssize_t odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset);
+static ssize_t odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset);
 static int odev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
 static unsigned int odev_poll(struct file *file, poll_table * wait);
 #ifdef CONFIG_PROC_FS
@@ -155,7 +155,7 @@ odev_release(struct inode *inode, struct file *file)
 }
 
 static ssize_t
-odev_read(struct file *file, char *buf, size_t count, loff_t *offset)
+odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
        seq_oss_devinfo_t *dp;
        dp = file->private_data;
@@ -165,7 +165,7 @@ odev_read(struct file *file, char *buf, size_t count, loff_t *offset)
 
 
 static ssize_t
-odev_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
 {
        seq_oss_devinfo_t *dp;
        dp = file->private_data;
index d5973a8..6d783cd 100644 (file)
@@ -36,6 +36,7 @@ snd_seq_oss_ioctl(seq_oss_devinfo_t *dp, unsigned int cmd, unsigned long carg)
        struct midi_info minf;
        unsigned char ev[8];
        void __user *arg = (void __user *)carg;
+       int __user *p = arg;
        snd_seq_event_t tmpev;
 
        switch (cmd) {
@@ -72,7 +73,7 @@ snd_seq_oss_ioctl(seq_oss_devinfo_t *dp, unsigned int cmd, unsigned long carg)
 
        case SNDCTL_SEQ_TESTMIDI:
                debug_printk(("test midi\n"));
-               if (get_user(dev, (int *)arg))
+               if (get_user(dev, p))
                        return -EFAULT;
                return snd_seq_oss_midi_open(dp, dev, dp->file_mode);
 
@@ -80,42 +81,42 @@ snd_seq_oss_ioctl(seq_oss_devinfo_t *dp, unsigned int cmd, unsigned long carg)
                debug_printk(("get in count\n"));
                if (dp->readq == NULL || ! is_read_mode(dp->file_mode))
                        return 0;
-               return put_user(dp->readq->qlen, (int *)arg) ? -EFAULT : 0;
+               return put_user(dp->readq->qlen, p) ? -EFAULT : 0;
 
        case SNDCTL_SEQ_GETOUTCOUNT:
                debug_printk(("get out count\n"));
                if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
                        return 0;
-               return put_user(snd_seq_oss_writeq_get_free_size(dp->writeq), (int *)arg) ? -EFAULT : 0;
+               return put_user(snd_seq_oss_writeq_get_free_size(dp->writeq), p) ? -EFAULT : 0;
 
        case SNDCTL_SEQ_GETTIME:
                debug_printk(("get time\n"));
-               return put_user(snd_seq_oss_timer_cur_tick(dp->timer), (int *)arg) ? -EFAULT : 0;
+               return put_user(snd_seq_oss_timer_cur_tick(dp->timer), p) ? -EFAULT : 0;
 
        case SNDCTL_SEQ_RESETSAMPLES:
                debug_printk(("reset samples\n"));
-               if (get_user(dev, (int *)arg))
+               if (get_user(dev, p))
                        return -EFAULT;
                return snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
 
        case SNDCTL_SEQ_NRSYNTHS:
                debug_printk(("nr synths\n"));
-               return put_user(dp->max_synthdev, (int *)arg) ? -EFAULT : 0;
+               return put_user(dp->max_synthdev, p) ? -EFAULT : 0;
 
        case SNDCTL_SEQ_NRMIDIS:
                debug_printk(("nr midis\n"));
-               return put_user(dp->max_mididev, (int *)arg) ? -EFAULT : 0;
+               return put_user(dp->max_mididev, p) ? -EFAULT : 0;
 
        case SNDCTL_SYNTH_MEMAVL:
                debug_printk(("mem avail\n"));
-               if (get_user(dev, (int *)arg))
+               if (get_user(dev, p))
                        return -EFAULT;
                val = snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
-               return put_user(val, (int *)arg) ? -EFAULT : 0;
+               return put_user(val, p) ? -EFAULT : 0;
 
        case SNDCTL_FM_4OP_ENABLE:
                debug_printk(("4op\n"));
-               if (get_user(dev, (int *)arg))
+               if (get_user(dev, p))
                        return -EFAULT;
                snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
                return 0;
@@ -157,7 +158,7 @@ snd_seq_oss_ioctl(seq_oss_devinfo_t *dp, unsigned int cmd, unsigned long carg)
                debug_printk(("threshold\n"));
                if (! is_write_mode(dp->file_mode))
                        return 0;
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val < 1)
                        val = 1;
@@ -170,14 +171,14 @@ snd_seq_oss_ioctl(seq_oss_devinfo_t *dp, unsigned int cmd, unsigned long carg)
                debug_printk(("pretime\n"));
                if (dp->readq == NULL || !is_read_mode(dp->file_mode))
                        return 0;
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val <= 0)
                        val = -1;
                else
                        val = (HZ * val) / 10;
                dp->readq->pre_event_timeout = val;
-               return put_user(val, (int *)arg) ? -EFAULT : 0;
+               return put_user(val, p) ? -EFAULT : 0;
 
        default:
                debug_printk(("others\n"));
index 40fef22..9e67d06 100644 (file)
@@ -2154,17 +2154,17 @@ static int snd_seq_do_ioctl(client_t *client, unsigned int cmd, void __user *arg
        switch (cmd) {
        case SNDRV_SEQ_IOCTL_PVERSION:
                /* return sequencer version number */
-               return put_user(SNDRV_SEQ_VERSION, (int *)arg) ? -EFAULT : 0;
+               return put_user(SNDRV_SEQ_VERSION, (int __user *)arg) ? -EFAULT : 0;
        case SNDRV_SEQ_IOCTL_CLIENT_ID:
                /* return the id of this client */
-               return put_user(client->number, (int *)arg) ? -EFAULT : 0;
+               return put_user(client->number, (int __user *)arg) ? -EFAULT : 0;
        }
 
        if (! arg)
                return -EFAULT;
        for (p = ioctl_tables; p->cmd; p++) {
                if (p->cmd == cmd)
-                       return p->func(client, (void __user *) arg);
+                       return p->func(client, arg);
        }
        snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%2x)\n",
                   cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
@@ -2348,7 +2348,7 @@ int snd_seq_kernel_client_dispatch(int client, snd_seq_event_t * ev,
  * exported, called by kernel clients to perform same functions as with
  * userland ioctl() 
  */
-int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void __user *arg)
+int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
 {
        client_t *client;
        mm_segment_t fs;
index 298cfd3..fbcfd3c 100644 (file)
@@ -90,7 +90,7 @@ int snd_seq_dump_var_event(const snd_seq_event_t *event, snd_seq_dump_func_t fun
 
        if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) {
                char buf[32];
-               char *curptr = event->data.ext.ptr;
+               char __user *curptr = event->data.ext.ptr;
                while (len > 0) {
                        int size = sizeof(buf);
                        if (len < size)
index 956ea2a..6f6d89c 100644 (file)
@@ -1253,7 +1253,7 @@ static void snd_timer_user_copy_id(snd_timer_id_t *id, snd_timer_t *timer)
        id->subdevice = timer->tmr_subdevice;
 }
 
-static int snd_timer_user_next_device(snd_timer_id_t *_tid)
+static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
 {
        snd_timer_id_t id;
        snd_timer_t *timer;
@@ -1344,7 +1344,7 @@ static int snd_timer_user_next_device(snd_timer_id_t *_tid)
        return 0;
 } 
 
-static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t *_ginfo)
+static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo)
 {
        snd_timer_ginfo_t ginfo;
        snd_timer_id_t tid;
@@ -1382,7 +1382,7 @@ static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t *_ginfo)
        return err;
 }
 
-static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t *_gparams)
+static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user *_gparams)
 {
        snd_timer_gparams_t gparams;
        snd_timer_t *t;
@@ -1408,7 +1408,7 @@ static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t *_gpara
        return err;
 }
 
-static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t *_gstatus)
+static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user *_gstatus)
 {
        snd_timer_gstatus_t gstatus;
        snd_timer_id_t tid;
@@ -1437,12 +1437,12 @@ static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t *_gstat
                err = -ENODEV;
        }
        up(&register_mutex);
-       if (err >= 0 && copy_from_user(_gstatus, &gstatus, sizeof(gstatus)))
+       if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus)))
                err = -EFAULT;
        return err;
 }
 
-static int snd_timer_user_tselect(struct file *file, snd_timer_select_t *_tselect)
+static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *_tselect)
 {
        snd_timer_user_t *tu;
        snd_timer_select_t tselect;
@@ -1489,7 +1489,7 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t *_tselec
        return 0;
 }
 
-static int snd_timer_user_info(struct file *file, snd_timer_info_t *_info)
+static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info)
 {
        snd_timer_user_t *tu;
        snd_timer_info_t info;
@@ -1511,7 +1511,7 @@ static int snd_timer_user_info(struct file *file, snd_timer_info_t *_info)
        return 0;
 }
 
-static int snd_timer_user_params(struct file *file, snd_timer_params_t *_params)
+static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params)
 {
        snd_timer_user_t *tu;
        snd_timer_params_t params;
@@ -1603,7 +1603,7 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t *_params)
        return err;
 }
 
-static int snd_timer_user_status(struct file *file, snd_timer_status_t *_status)
+static int snd_timer_user_status(struct file *file, snd_timer_status_t __user *_status)
 {
        snd_timer_user_t *tu;
        snd_timer_status_t status;
@@ -1661,38 +1661,40 @@ static int snd_timer_user_ioctl(struct inode *inode, struct file *file,
                                unsigned int cmd, unsigned long arg)
 {
        snd_timer_user_t *tu;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        
        tu = snd_magic_cast(snd_timer_user_t, file->private_data, return -ENXIO);
        switch (cmd) {
        case SNDRV_TIMER_IOCTL_PVERSION:
-               return put_user(SNDRV_TIMER_VERSION, (int *)arg) ? -EFAULT : 0;
+               return put_user(SNDRV_TIMER_VERSION, p) ? -EFAULT : 0;
        case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
-               return snd_timer_user_next_device((snd_timer_id_t *)arg);
+               return snd_timer_user_next_device(argp);
        case SNDRV_TIMER_IOCTL_TREAD:
        {
                int xarg;
                
                if (tu->timeri)         /* too late */
                        return -EBUSY;
-               if (get_user(xarg, (int *) arg))
+               if (get_user(xarg, p))
                        return -EFAULT;
                tu->tread = xarg ? 1 : 0;
                return 0;
        }
        case SNDRV_TIMER_IOCTL_GINFO:
-               return snd_timer_user_ginfo(file, (snd_timer_ginfo_t *)arg);
+               return snd_timer_user_ginfo(file, argp);
        case SNDRV_TIMER_IOCTL_GPARAMS:
-               return snd_timer_user_gparams(file, (snd_timer_gparams_t *)arg);
+               return snd_timer_user_gparams(file, argp);
        case SNDRV_TIMER_IOCTL_GSTATUS:
-               return snd_timer_user_gstatus(file, (snd_timer_gstatus_t *)arg);
+               return snd_timer_user_gstatus(file, argp);
        case SNDRV_TIMER_IOCTL_SELECT:
-               return snd_timer_user_tselect(file, (snd_timer_select_t *)arg);
+               return snd_timer_user_tselect(file, argp);
        case SNDRV_TIMER_IOCTL_INFO:
-               return snd_timer_user_info(file, (snd_timer_info_t *)arg);
+               return snd_timer_user_info(file, argp);
        case SNDRV_TIMER_IOCTL_PARAMS:
-               return snd_timer_user_params(file, (snd_timer_params_t *)arg);
+               return snd_timer_user_params(file, argp);
        case SNDRV_TIMER_IOCTL_STATUS:
-               return snd_timer_user_status(file, (snd_timer_status_t *)arg);
+               return snd_timer_user_status(file, argp);
        case SNDRV_TIMER_IOCTL_START:
                return snd_timer_user_start(file);
        case SNDRV_TIMER_IOCTL_STOP:
@@ -1715,7 +1717,7 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on)
        return 0;
 }
 
-static ssize_t snd_timer_user_read(struct file *file, char *buffer, size_t count, loff_t *offset)
+static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_t count, loff_t *offset)
 {
        snd_timer_user_t *tu;
        long result = 0, unit;
index dac8fb1..4b00250 100644 (file)
@@ -52,9 +52,6 @@ static int acpipnp[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 1 };
 #endif
 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;    /* MPU-401 port number */
 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;       /* MPU-401 IRQ */
-#ifdef CONFIG_X86_PC9800
-static int pc98ii[SNDRV_CARDS];                                /* PC98-II dauther board */
-#endif
 static int boot_devs;
 
 module_param_array(index, int, boot_devs, 0444);
@@ -77,11 +74,6 @@ MODULE_PARM_SYNTAX(port, SNDRV_PORT12_DESC);
 module_param_array(irq, int, boot_devs, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
 MODULE_PARM_SYNTAX(irq, SNDRV_IRQ_DESC);
-#ifdef CONFIG_X86_PC9800
-module_param_array(pc98ii, bool, boot_devs, 0444);
-MODULE_PARM_DESC(pc98ii, "Roland MPU-PC98II support.");
-MODULE_PARM_SYNTAX(pc98ii, SNDRV_BOOLEAN_FALSE_DESC);
-#endif
 
 #ifndef CONFIG_ACPI_BUS
 struct acpi_device;
@@ -188,9 +180,6 @@ static int __devinit snd_card_mpu401_probe(int dev, struct acpi_device *device)
        }
 #endif
        if (snd_mpu401_uart_new(card, 0,
-#ifdef CONFIG_X86_PC9800
-                               pc98ii[dev] ? MPU401_HW_PC98II :
-#endif
                                MPU401_HW_MPU401,
                                port[dev], 0,
                                irq[dev], irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL) < 0) {
index e3fa31d..965ffd0 100644 (file)
@@ -415,26 +415,6 @@ int snd_opl3_create(snd_card_t * card,
        case OPL3_HW_OPL3_CS:
        case OPL3_HW_OPL3_FM801:
                opl3->command = &snd_opl3_command;
-               break;
-       case OPL3_HW_OPL3_PC98:
-               opl3->command = &snd_opl3_command;
-
-               /* Initialize? */
-               opl3->command(opl3, OPL3_RIGHT | 0x05, 0x05);
-               opl3->command(opl3, OPL3_RIGHT | 0x08, 0x04);
-               opl3->command(opl3, OPL3_RIGHT | 0x08, 0x00);
-               opl3->command(opl3, OPL3_LEFT | 0xf7, 0x00);
-               opl3->command(opl3, OPL3_LEFT | 0x04, 0x60);
-               opl3->command(opl3, OPL3_LEFT | 0x04, 0x80);
-               inb(opl3->l_port);
-               
-               opl3->command(opl3, OPL3_LEFT | 0x02, 0xff);
-               opl3->command(opl3, OPL3_LEFT | 0x04, 0x21);
-               inb(opl3->l_port);
-               
-               opl3->command(opl3, OPL3_LEFT | 0x04, 0x60);
-               opl3->command(opl3, OPL3_LEFT | 0x04, 0x80);
-
                break;
        case OPL3_HW_OPL3_CS4281:
                opl3->command = &snd_opl3_cs4281_command;
index bd39864..1e6472e 100644 (file)
@@ -94,6 +94,7 @@ int snd_opl3_ioctl(snd_hwdep_t * hw, struct file *file,
                   unsigned int cmd, unsigned long arg)
 {
        opl3_t *opl3 = snd_magic_cast(opl3_t, hw->private_data, return -ENXIO);
+       void __user *argp = (void __user *)arg;
 
        snd_assert(opl3 != NULL, return -EINVAL);
 
@@ -105,7 +106,7 @@ int snd_opl3_ioctl(snd_hwdep_t * hw, struct file *file,
 
                        info.fm_mode = opl3->fm_mode;
                        info.rhythm = opl3->rhythm;
-                       if (copy_to_user((snd_dm_fm_info_t *) arg, &info, sizeof(snd_dm_fm_info_t)))
+                       if (copy_to_user(argp, &info, sizeof(snd_dm_fm_info_t)))
                                return -EFAULT;
                        return 0;
                }
@@ -123,7 +124,7 @@ int snd_opl3_ioctl(snd_hwdep_t * hw, struct file *file,
 #endif
                {
                        snd_dm_fm_note_t note;
-                       if (copy_from_user(&note, (snd_dm_fm_note_t *) arg, sizeof(snd_dm_fm_note_t)))
+                       if (copy_from_user(&note, argp, sizeof(snd_dm_fm_note_t)))
                                return -EFAULT;
                        return snd_opl3_play_note(opl3, &note);
                }
@@ -134,7 +135,7 @@ int snd_opl3_ioctl(snd_hwdep_t * hw, struct file *file,
 #endif
                {
                        snd_dm_fm_voice_t voice;
-                       if (copy_from_user(&voice, (snd_dm_fm_voice_t *) arg, sizeof(snd_dm_fm_voice_t)))
+                       if (copy_from_user(&voice, argp, sizeof(snd_dm_fm_voice_t)))
                                return -EFAULT;
                        return snd_opl3_set_voice(opl3, &voice);
                }
@@ -145,7 +146,7 @@ int snd_opl3_ioctl(snd_hwdep_t * hw, struct file *file,
 #endif
                {
                        snd_dm_fm_params_t params;
-                       if (copy_from_user(&params, (snd_dm_fm_params_t *) arg, sizeof(snd_dm_fm_params_t)))
+                       if (copy_from_user(&params, argp, sizeof(snd_dm_fm_params_t)))
                                return -EFAULT;
                        return snd_opl3_set_params(opl3, &params);
                }
index 2b346d6..f2f364d 100644 (file)
@@ -50,7 +50,7 @@ static int snd_opl4_mem_proc_release(snd_info_entry_t *entry,
 }
 
 static long snd_opl4_mem_proc_read(snd_info_entry_t *entry, void *file_private_data,
-                                  struct file *file, char *_buf, long count)
+                                  struct file *file, char __user *_buf, long count)
 {
        opl4_t *opl4 = snd_magic_cast(opl4_t, entry->private_data, return -ENXIO);
        long size;
@@ -76,7 +76,7 @@ static long snd_opl4_mem_proc_read(snd_info_entry_t *entry, void *file_private_d
 }
 
 static long snd_opl4_mem_proc_write(snd_info_entry_t *entry, void *file_private_data,
-                                   struct file *file, const char *_buf, long count)
+                                   struct file *file, const char __user *_buf, long count)
 {
        opl4_t *opl4 = snd_magic_cast(opl4_t, entry->private_data, return -ENXIO);
        long size;
index 1f954b6..04b2c3a 100644 (file)
@@ -51,16 +51,6 @@ config SND_CS4236
          Say 'Y' or 'M' to include support for CS4235,CS4236,CS4237B,CS4238B,CS4239
          chips from Cirrus Logic - Crystal Semiconductors.
 
-config SND_PC98_CS4232
-       tristate "NEC PC9800 CS4232 driver"
-       depends on SND && X86_PC9800
-       select SND_OPL3_LIB
-       select SND_MPU401_UART
-       select SND_PCM
-       help
-         Say 'Y' or 'M' to include support for NEC PC-9801/PC-9821 on-board
-         soundchip based on CS4232.
-
 config SND_ES968
        tristate "Generic ESS ES968 driver"
        depends on SND && ISAPNP
index cfc32c6..d2afaea 100644 (file)
@@ -8,7 +8,6 @@ snd-cs4236-lib-objs := cs4236_lib.o
 snd-cs4231-objs := cs4231.o
 snd-cs4232-objs := cs4232.o
 snd-cs4236-objs := cs4236.o
-snd-pc98-cs4232-objs := pc98.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_AZT2320) += snd-cs4231-lib.o
@@ -22,6 +21,5 @@ obj-$(CONFIG_SND_INTERWAVE_STB) += snd-cs4231-lib.o
 obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-cs4231-lib.o
 obj-$(CONFIG_SND_WAVEFRONT) += snd-cs4231-lib.o
 obj-$(CONFIG_SND_SSCAPE) += snd-cs4231-lib.o
-obj-$(CONFIG_SND_PC98_CS4232) += snd-pc98-cs4232.o snd-cs4231-lib.o
 
 obj-m := $(sort $(obj-m))
index 44895d3..0b73d4c 100644 (file)
@@ -26,7 +26,7 @@
 #include <sound/info.h>
 
 
-static int snd_gus_dram_poke(snd_gus_card_t *gus, char *_buffer,
+static int snd_gus_dram_poke(snd_gus_card_t *gus, char __user *_buffer,
                             unsigned int address, unsigned int size)
 {
        unsigned long flags;
@@ -57,13 +57,13 @@ static int snd_gus_dram_poke(snd_gus_card_t *gus, char *_buffer,
 }
 
 
-int snd_gus_dram_write(snd_gus_card_t *gus, char *buffer,
+int snd_gus_dram_write(snd_gus_card_t *gus, char __user *buffer,
                       unsigned int address, unsigned int size)
 {
        return snd_gus_dram_poke(gus, buffer, address, size);
 }
 
-static int snd_gus_dram_peek(snd_gus_card_t *gus, char *_buffer,
+static int snd_gus_dram_peek(snd_gus_card_t *gus, char __user *_buffer,
                             unsigned int address, unsigned int size,
                             int rom)
 {
@@ -95,7 +95,7 @@ static int snd_gus_dram_peek(snd_gus_card_t *gus, char *_buffer,
        return 0;
 }
 
-int snd_gus_dram_read(snd_gus_card_t *gus, char *buffer,
+int snd_gus_dram_read(snd_gus_card_t *gus, char __user *buffer,
                      unsigned int address, unsigned int size,
                      int rom)
 {
index 031a779..e819e90 100644 (file)
@@ -29,7 +29,7 @@
  */
 
 int snd_gus_iwffff_put_sample(void *private_data, iwffff_wave_t *wave,
-                             char *data, long len, int atomic)
+                             char __user *data, long len, int atomic)
 {
        snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return -ENXIO);
        snd_gf1_mem_block_t *block;
@@ -59,7 +59,7 @@ int snd_gus_iwffff_put_sample(void *private_data, iwffff_wave_t *wave,
 }
 
 int snd_gus_iwffff_get_sample(void *private_data, iwffff_wave_t *wave,
-                             char *data, long len, int atomic)
+                             char __user *data, long len, int atomic)
 {
        snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return -ENXIO);
 
@@ -82,7 +82,7 @@ int snd_gus_iwffff_remove_sample(void *private_data, iwffff_wave_t *wave,
  */
 
 int snd_gus_gf1_put_sample(void *private_data, gf1_wave_t *wave,
-                          char *data, long len, int atomic)
+                          char __user *data, long len, int atomic)
 {
        snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return -ENXIO);
        snd_gf1_mem_block_t *block;
@@ -110,7 +110,7 @@ int snd_gus_gf1_put_sample(void *private_data, gf1_wave_t *wave,
 }
 
 int snd_gus_gf1_get_sample(void *private_data, gf1_wave_t *wave,
-                          char *data, long len, int atomic)
+                          char __user *data, long len, int atomic)
 {
        snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return -ENXIO);
 
@@ -130,7 +130,7 @@ int snd_gus_gf1_remove_sample(void *private_data, gf1_wave_t *wave,
  */
 
 int snd_gus_simple_put_sample(void *private_data, simple_instrument_t *instr,
-                             char *data, long len, int atomic)
+                             char __user *data, long len, int atomic)
 {
        snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return -ENXIO);
        snd_gf1_mem_block_t *block;
@@ -157,7 +157,7 @@ int snd_gus_simple_put_sample(void *private_data, simple_instrument_t *instr,
 }
 
 int snd_gus_simple_get_sample(void *private_data, simple_instrument_t *instr,
-                             char *data, long len, int atomic)
+                             char __user *data, long len, int atomic)
 {
        snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return -ENXIO);
 
index 32f02ad..95071a0 100644 (file)
@@ -33,7 +33,7 @@ typedef struct gus_proc_private {
 } gus_proc_private_t;
 
 static long snd_gf1_mem_proc_dump(snd_info_entry_t *entry, void *file_private_data,
-                                 struct file *file, char *buf, long count)
+                                 struct file *file, char __user *buf, long count)
 {
        long size;
        gus_proc_private_t *priv = snd_magic_cast(gus_proc_private_t, entry->private_data, return -ENXIO);
index a0f96cd..040804c 100644 (file)
@@ -346,7 +346,7 @@ static int snd_gf1_pcm_poke_block(snd_gus_card_t *gus, unsigned char *buf,
 static int snd_gf1_pcm_playback_copy(snd_pcm_substream_t *substream,
                                     int voice,
                                     snd_pcm_uframes_t pos,
-                                    void *src,
+                                    void __user *src,
                                     snd_pcm_uframes_t count)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
index 2590aba..9ecd53c 100644 (file)
@@ -87,14 +87,14 @@ read_word(const void __user *buf, int offset, int mode)
        unsigned short c;
        if (mode & SNDRV_SFNT_SAMPLE_8BITS) {
                unsigned char cc;
-               get_user(cc, (unsigned char*)buf + offset);
+               get_user(cc, (unsigned char __user *)buf + offset);
                c = cc << 8; /* convert 8bit -> 16bit */
        } else {
 #ifdef SNDRV_LITTLE_ENDIAN
-               get_user(c, (unsigned short*)buf + offset);
+               get_user(c, (unsigned short __user *)buf + offset);
 #else
                unsigned short cc;
-               get_user(cc, (unsigned short*)buf + offset);
+               get_user(cc, (unsigned short __user *)buf + offset);
                c = swab16(cc);
 #endif
        }
index 51e4f20..4d84f25 100644 (file)
@@ -515,12 +515,12 @@ static int emu8k_pcm_silence(snd_pcm_substream_t *subs,
 static int emu8k_pcm_copy(snd_pcm_substream_t *subs,
                          int voice,
                          snd_pcm_uframes_t pos,
-                         void *src,
+                         void __user *src,
                          snd_pcm_uframes_t count)
 {
        emu8k_pcm_t *rec = subs->runtime->private_data;
        emu8000_t *emu = rec->emu;
-       unsigned short *buf = src;
+       unsigned short __user *buf = src;
 
        snd_emu8000_write_wait(emu, 1);
        EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]);
index 80d576a..6cbef46 100644 (file)
@@ -89,9 +89,9 @@ static int read_register(sb_t *chip, unsigned char reg);
 static int set_mode_register(sb_t *chip, unsigned char mode);
 static int get_version(sb_t *chip);
 
-static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t * code);
+static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user * code);
 static int snd_sb_csp_unload(snd_sb_csp_t * p);
-static int snd_sb_csp_load(snd_sb_csp_t * p, const unsigned char *buf, int size, int load_flags);
+static int snd_sb_csp_load_user(snd_sb_csp_t * p, const unsigned char __user *buf, int size, int load_flags);
 static int snd_sb_csp_autoload(snd_sb_csp_t * p, int pcm_sfmt, int play_rec_mode);
 static int snd_sb_csp_check_version(snd_sb_csp_t * p);
 
@@ -213,7 +213,7 @@ static int snd_sb_csp_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cm
                info.run_width = p->run_width;
                info.version = p->version;
                info.state = p->running;
-               if (copy_to_user((void *) arg, &info, sizeof(info)))
+               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
                        err = -EFAULT;
                else
                        err = 0;
@@ -222,7 +222,7 @@ static int snd_sb_csp_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cm
                /* load CSP microcode */
        case SNDRV_SB_CSP_IOCTL_LOAD_CODE:
                err = (p->running & SNDRV_SB_CSP_ST_RUNNING ?
-                      -EBUSY : snd_sb_csp_riff_load(p, (snd_sb_csp_microcode_t *) arg));
+                      -EBUSY : snd_sb_csp_riff_load(p, (snd_sb_csp_microcode_t __user *) arg));
                break;
        case SNDRV_SB_CSP_IOCTL_UNLOAD_CODE:
                err = (p->running & SNDRV_SB_CSP_ST_RUNNING ?
@@ -231,7 +231,7 @@ static int snd_sb_csp_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cm
 
                /* change CSP running state */
        case SNDRV_SB_CSP_IOCTL_START:
-               if (copy_from_user(&start_info, (void *) arg, sizeof(start_info)))
+               if (copy_from_user(&start_info, (void __user *) arg, sizeof(start_info)))
                        err = -EFAULT;
                else
                        err = snd_sb_csp_start(p, start_info.sample_width, start_info.channels);
@@ -297,11 +297,12 @@ static int snd_sb_csp_unuse(snd_sb_csp_t * p)
  * load microcode via ioctl: 
  * code is user-space pointer
  */
-static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t * mcode)
+static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user * mcode)
 {
        snd_sb_csp_mc_header_t info;
 
-       unsigned char *data_ptr, *data_end;
+       unsigned char __user *data_ptr;
+       unsigned char __user *data_end;
        unsigned short func_nr = 0;
 
        riff_header_t file_h, item_h, code_h;
@@ -372,8 +373,8 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t * mcode
                                if (code_h.name != INIT_HEADER)
                                        break;
                                data_ptr += sizeof(code_h);
-                               err = snd_sb_csp_load(p, data_ptr, LE_INT(code_h.len),
-                                                     SNDRV_SB_CSP_LOAD_INITBLOCK | SNDRV_SB_CSP_LOAD_FROMUSER);
+                               err = snd_sb_csp_load_user(p, data_ptr, LE_INT(code_h.len),
+                                                     SNDRV_SB_CSP_LOAD_INITBLOCK);
                                if (err)
                                        return err;
                                data_ptr += LE_INT(code_h.len);
@@ -387,8 +388,8 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t * mcode
                                return -EINVAL;
                        }
                        data_ptr += sizeof(code_h);
-                       err = snd_sb_csp_load(p, data_ptr, LE_INT(code_h.len),
-                                             SNDRV_SB_CSP_LOAD_FROMUSER);
+                       err = snd_sb_csp_load_user(p, data_ptr,
+                                                  LE_INT(code_h.len), 0);
                        if (err)
                                return err;
 
@@ -627,28 +628,10 @@ static int snd_sb_csp_load(snd_sb_csp_t * p, const unsigned char *buf, int size,
        /* Send high byte */
        snd_sbdsp_command(p->chip, (unsigned char)((size - 1) >> 8));
        /* send microcode sequence */
-       if (load_flags & SNDRV_SB_CSP_LOAD_FROMUSER) {
-               /* copy microcode from user space */
-               unsigned char *kbuf, *_kbuf;
-               _kbuf = kbuf = kmalloc (size, GFP_KERNEL);
-               if (copy_from_user(kbuf, buf, size)) {
-                       result = -EFAULT;
-                       kfree (_kbuf);
+       /* load from kernel space */
+       while (size--) {
+               if (!snd_sbdsp_command(p->chip, *buf++))
                        goto __fail;
-               }
-               while (size--) {
-                       if (!snd_sbdsp_command(p->chip, *kbuf++)) {
-                               kfree (_kbuf);
-                               goto __fail;
-                       }
-               }
-               kfree (_kbuf);
-       } else {
-               /* load from kernel space */
-               while (size--) {
-                       if (!snd_sbdsp_command(p->chip, *buf++))
-                               goto __fail;
-               }
        }
        if (snd_sbdsp_get_byte(p->chip))
                goto __fail;
@@ -692,6 +675,20 @@ static int snd_sb_csp_load(snd_sb_csp_t * p, const unsigned char *buf, int size,
        spin_unlock_irqrestore(&p->chip->reg_lock, flags);
        return result;
 }
+static int snd_sb_csp_load_user(snd_sb_csp_t * p, const unsigned char __user *buf, int size, int load_flags)
+{
+       int err = -ENOMEM;
+       unsigned char *kbuf = kmalloc(size, GFP_KERNEL);
+       if (kbuf) {
+               if (copy_from_user(kbuf, buf, size))
+                       err = -EFAULT;
+               else
+                       err = snd_sb_csp_load(p, kbuf, size, load_flags);
+               kfree(kbuf);
+       }
+       return err;
+}
 
 #include "sb16_csp_codecs.h"
 
index 29e9df7..c450613 100644 (file)
@@ -455,7 +455,7 @@ static int host_startup_ack(struct soundscape *s, unsigned timeout)
  * Upload a byte-stream into the SoundScape using DMA channel A.
  */
 static int upload_dma_data(struct soundscape *s,
-                           const unsigned char *data,
+                           const unsigned char __user *data,
                            size_t size)
 {
        unsigned long flags;
@@ -569,7 +569,7 @@ static int upload_dma_data(struct soundscape *s,
  *       However, we have already verified its memory
  *       addresses by the time we get here.
  */
-static int sscape_upload_bootblock(struct soundscape *sscape, struct sscape_bootblock *bb)
+static int sscape_upload_bootblock(struct soundscape *sscape, struct sscape_bootblock __user *bb)
 {
        unsigned long flags;
        int data = 0;
@@ -604,10 +604,10 @@ static int sscape_upload_bootblock(struct soundscape *sscape, struct sscape_boot
  * SPACE, and save ourselves from copying it at all.
  */
 static int sscape_upload_microcode(struct soundscape *sscape,
-                                   const struct sscape_microcode *mc)
+                                   const struct sscape_microcode __user *mc)
 {
        unsigned long flags;
-       char *code;
+       char __user *code;
        int err, ret;
 
        /*
@@ -683,7 +683,7 @@ static int sscape_hw_ioctl(snd_hwdep_t * hw, struct file *file,
        switch (cmd) {
        case SND_SSCAPE_LOAD_BOOTB:
                {
-                       register struct sscape_bootblock *bb = (struct sscape_bootblock *) arg;
+                       register struct sscape_bootblock __user *bb = (struct sscape_bootblock __user *) arg;
 
                        /*
                         * We are going to have to copy this data into a special
@@ -705,7 +705,7 @@ static int sscape_hw_ioctl(snd_hwdep_t * hw, struct file *file,
 
        case SND_SSCAPE_LOAD_MCODE:
                {
-                       register const struct sscape_microcode *mc = (const struct sscape_microcode *) arg;
+                       register const struct sscape_microcode __user *mc = (const struct sscape_microcode __user *) arg;
 
                        err = sscape_upload_microcode(sscape, mc);
                }
index 01d6647..92d9c85 100644 (file)
@@ -179,7 +179,7 @@ snd_wavefront_fx_ioctl (snd_hwdep_t *sdev, struct file *file,
        acard = card->private_data;
        dev = &acard->wavefront;
 
-       if (copy_from_user (&r, (unsigned char *) arg, sizeof (wavefront_fx_info)))
+       if (copy_from_user (&r, (void __user *)arg, sizeof (wavefront_fx_info)))
                return -EFAULT;
 
        switch (r.request) {
@@ -201,7 +201,7 @@ snd_wavefront_fx_ioctl (snd_hwdep_t *sdev, struct file *file,
                                return -EIO;
                        }
                        if (copy_from_user (page_data,
-                                           (unsigned char *) r.data[3],
+                                           (unsigned char __user *) r.data[3],
                                            r.data[2]))
                                return -EFAULT;
                        pd = page_data;
index af561df..9b65db0 100644 (file)
@@ -861,7 +861,7 @@ wavefront_freemem (snd_wavefront_t *dev)
 static int
 wavefront_send_sample (snd_wavefront_t *dev, 
                       wavefront_patch_info *header,
-                      u16 *dataptr,
+                      u16 __user *dataptr,
                       int data_is_unsigned)
 
 {
@@ -876,7 +876,7 @@ wavefront_send_sample (snd_wavefront_t *dev,
 
        u16 sample_short;
        u32 length;
-       u16 *data_end = 0;
+       u16 __user *data_end = 0;
        unsigned int i;
        const unsigned int max_blksize = 4096/2;
        unsigned int written;
@@ -1355,7 +1355,7 @@ wavefront_find_free_patch (snd_wavefront_t *dev)
 #endif
 
 static int
-wavefront_load_patch (snd_wavefront_t *dev, const char *addr)
+wavefront_load_patch (snd_wavefront_t *dev, const char __user *addr)
 
 {
        wavefront_patch_info header;
@@ -1377,8 +1377,7 @@ wavefront_load_patch (snd_wavefront_t *dev, const char *addr)
        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 *) header.hdrptr,
+               if (copy_from_user (&header.hdr.s, header.hdrptr,
                                    sizeof (wavefront_sample)))
                        return -EFAULT;
 
@@ -1386,8 +1385,7 @@ wavefront_load_patch (snd_wavefront_t *dev, const char *addr)
 
        case WF_ST_MULTISAMPLE:
 
-               if (copy_from_user ((unsigned char *) &header.hdr.s,
-                                   (unsigned char *) header.hdrptr,
+               if (copy_from_user (&header.hdr.s, header.hdrptr,
                                    sizeof (wavefront_multisample)))
                        return -EFAULT;
 
@@ -1396,32 +1394,28 @@ wavefront_load_patch (snd_wavefront_t *dev, const char *addr)
 
        case WF_ST_ALIAS:
 
-               if (copy_from_user ((unsigned char *) &header.hdr.a,
-                                   (unsigned char *) header.hdrptr,
+               if (copy_from_user (&header.hdr.a, header.hdrptr,
                                    sizeof (wavefront_alias)))
                        return -EFAULT;
 
                return wavefront_send_alias (dev, &header);
 
        case WF_ST_DRUM:
-               if (copy_from_user ((unsigned char *) &header.hdr.d, 
-                                   (unsigned char *) header.hdrptr,
+               if (copy_from_user (&header.hdr.d, header.hdrptr,
                                    sizeof (wavefront_drum)))
                        return -EFAULT;
 
                return wavefront_send_drum (dev, &header);
 
        case WF_ST_PATCH:
-               if (copy_from_user ((unsigned char *) &header.hdr.p, 
-                                   (unsigned char *) header.hdrptr,
+               if (copy_from_user (&header.hdr.p, header.hdrptr,
                                    sizeof (wavefront_patch)))
                        return -EFAULT;
 
                return wavefront_send_patch (dev, &header);
 
        case WF_ST_PROGRAM:
-               if (copy_from_user ((unsigned char *) &header.hdr.pr, 
-                                   (unsigned char *) header.hdrptr,
+               if (copy_from_user (&header.hdr.pr, header.hdrptr,
                                    sizeof (wavefront_program)))
                        return -EFAULT;
 
@@ -1627,6 +1621,7 @@ snd_wavefront_synth_ioctl (snd_hwdep_t *hw, struct file *file,
        snd_wavefront_t *dev;
        snd_wavefront_card_t *acard;
        wavefront_control wc;
+       void __user *argp = (void __user *)arg;
 
        card = (snd_card_t *) hw->card;
 
@@ -1639,18 +1634,18 @@ snd_wavefront_synth_ioctl (snd_hwdep_t *hw, struct file *file,
        
        switch (cmd) {
        case WFCTL_LOAD_SPP:
-               if (wavefront_load_patch (dev, (char *) arg) != 0) {
+               if (wavefront_load_patch (dev, argp) != 0) {
                        return -EIO;
                }
                break;
 
        case WFCTL_WFCMD:
-               if (copy_from_user (&wc, (void *) arg, sizeof (wc)))
+               if (copy_from_user (&wc, argp, sizeof (wc)))
                        return -EFAULT;
                if (wavefront_synth_control (acard, &wc) < 0) {
                        return -EIO;
                }
-               if (copy_to_user ((void *) arg, &wc, sizeof (wc)))
+               if (copy_to_user (argp, &wc, sizeof (wc)))
                        return -EFAULT;
                break;
 
index 98515fe..89543f3 100644 (file)
@@ -437,13 +437,13 @@ XXX
 
 /************************* /dev/dsp interfaces ************************* */
 
-static ssize_t ad1889_read(struct file *file, char *buffer, size_t count,
+static ssize_t ad1889_read(struct file *file, char __user *buffer, size_t count,
        loff_t *ppos)
 {
        return 0;
 }
 
-static ssize_t ad1889_write(struct file *file, const char *buffer, size_t count,
+static ssize_t ad1889_write(struct file *file, const char __user *buffer, size_t count,
        loff_t *ppos)
 {
        ad1889_dev_t *dev = (ad1889_dev_t *)file->private_data;
@@ -617,11 +617,12 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd
        ad1889_dev_t *dev = (ad1889_dev_t *)file->private_data;
        struct dmabuf *dmabuf;
        audio_buf_info abinfo;
+       int __user *p = (int __user *)arg;
 
        switch (cmd)
        {
        case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_RESET:
                break;
@@ -631,7 +632,7 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 
        case SNDCTL_DSP_SPEED:
                /* set sampling rate */
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val > 5400 && val < 48000)
                {
@@ -643,7 +644,7 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
        case SNDCTL_DSP_STEREO: /* undocumented? */
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        val = AD1889_READW(ad1889_dev, AD_DSWSMC);
@@ -667,13 +668,13 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
        case SNDCTL_DSP_GETBLKSIZE:
-               return put_user(DMA_SIZE, (int *)arg);
+               return put_user(DMA_SIZE, p);
 
        case SNDCTL_DSP_GETFMTS:
-               return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+               return put_user(AFMT_S16_LE|AFMT_U8, p);
 
        case SNDCTL_DSP_SETFMT:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                if (file->f_mode & FMODE_READ) 
@@ -682,7 +683,7 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                if (file->f_mode & FMODE_WRITE) 
                        ad1889_set_wav_fmt(dev, val);
 
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
 
        case SNDCTL_DSP_CHANNELS:
                break;
@@ -696,7 +697,7 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 
        case SNDCTL_DSP_SETFRAGMENT:
                /* not supported; uses fixed fragment sizes */
-               return put_user(DMA_SIZE, (int *)arg);
+               return put_user(DMA_SIZE, p);
 
        case SNDCTL_DSP_GETOSPACE:
        case SNDCTL_DSP_GETISPACE:
@@ -709,13 +710,13 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                abinfo.fragstotal = 1;
                abinfo.fragsize = DMA_SIZE;
                abinfo.bytes = DMA_SIZE;
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(p, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
        case SNDCTL_DSP_NONBLOCK:
                file->f_flags |= O_NONBLOCK;
                return 0;
 
        case SNDCTL_DSP_GETCAPS:
-               return put_user(0, (int *)arg);
+               return put_user(0, p);
 
        case SNDCTL_DSP_GETTRIGGER:
        case SNDCTL_DSP_SETTRIGGER:
@@ -732,7 +733,7 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                break;
 
        case SOUND_PCM_READ_RATE:
-               return put_user(AD1889_READW(ad1889_dev, AD_DSWAS), (int *)arg);
+               return put_user(AD1889_READW(ad1889_dev, AD_DSWAS), p);
 
        case SOUND_PCM_READ_CHANNELS:
        case SOUND_PCM_READ_BITS:
index 8a905b3..3f3a456 100644 (file)
@@ -1579,7 +1579,7 @@ static irqreturn_t ali_interrupt(int irq, void *dev_id, struct pt_regs *regs)
    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 *buffer,
+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;
@@ -1721,7 +1721,7 @@ done:
 /* 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 *buffer, size_t count, loff_t * ppos)
+                        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 : 0;
@@ -1981,16 +1981,19 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
        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 ? *(int *) arg : 0);
+              arg ? *p : 0);
 #endif
        switch (cmd) {
        case OSS_GETVERSION:
 #ifdef DEBUG
                printk("OSS_GETVERSION\n");
 #endif
-               return put_user(SOUND_VERSION, (int *) arg);
+               return put_user(SOUND_VERSION, p);
        case SNDCTL_DSP_RESET:
 #ifdef DEBUG
                printk("SNDCTL_DSP_RESET\n");
@@ -2058,7 +2061,7 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
 #ifdef DEBUG
                printk("SNDCTL_DSP_SPEED\n");
 #endif
-               if (get_user(val, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_WRITE) {
@@ -2136,7 +2139,7 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                                spin_unlock_irqrestore(&state->card->lock, flags);
                        }
                }
-               return put_user(dmabuf->rate, (int *) arg);
+               return put_user(dmabuf->rate, p);
        case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
 #ifdef DEBUG
                printk("SNDCTL_DSP_STEREO\n");
@@ -2153,7 +2156,7 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) {
                        stop_spdifout(state);
                }
-               return put_user(1, (int *) arg);
+               return put_user(1, p);
        case SNDCTL_DSP_GETBLKSIZE:
                if (file->f_mode & FMODE_WRITE) {
                        if (codec_independent_spdif_locked > 0) {
@@ -2177,22 +2180,22 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
 #ifdef DEBUG
                printk("SNDCTL_DSP_GETBLKSIZE %d\n", dmabuf->userfragsize);
 #endif
-               return put_user(dmabuf->userfragsize, (int *) arg);
+               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, (int *) arg);
+               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, (int *) arg);
+               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, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val > 0) {
                        if (dmabuf->enable & DAC_RUNNING) {
@@ -2208,7 +2211,7 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                                stop_adc(state);
                        }
                } else {
-                       return put_user(state->card->channels, (int *) arg);
+                       return put_user(state->card->channels, p);
                }
 
                i_scr = inl(state->card->iobase + ALI_SCR);
@@ -2243,7 +2246,7 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                        val = ret;
                        break;
                }
-               return put_user(val, (int *) arg);
+               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
@@ -2270,7 +2273,7 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
        case SNDCTL_DSP_SUBDIVIDE:
                if (dmabuf->subdivision)
                        return -EINVAL;
-               if (get_user(val, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
@@ -2281,7 +2284,7 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                dmabuf->ready = 0;
                return 0;
        case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
                dmabuf->ossfragsize = 1 << (val & 0xffff);
                dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
@@ -2360,7 +2363,7 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                       abinfo.bytes, abinfo.fragsize, abinfo.fragments,
                       abinfo.fragstotal);
 #endif
-               return copy_to_user((void *) arg, &abinfo,
+               return copy_to_user(argp, &abinfo,
                                    sizeof(abinfo)) ? -EFAULT : 0;
        case SNDCTL_DSP_GETOPTR:
                if (!(file->f_mode & FMODE_WRITE))
@@ -2408,7 +2411,7 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes,
                       cinfo.blocks, cinfo.ptr, dmabuf->count);
 #endif
-               return copy_to_user((void *) arg, &cinfo, sizeof(cinfo))? -EFAULT : 0;
+               return copy_to_user(argp, &cinfo, sizeof(cinfo))? -EFAULT : 0;
        case SNDCTL_DSP_GETISPACE:
                if (!(file->f_mode & FMODE_READ))
                        return -EINVAL;
@@ -2425,7 +2428,7 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                       abinfo.bytes, abinfo.fragsize, abinfo.fragments,
                       abinfo.fragstotal);
 #endif
-               return copy_to_user((void *) arg, &abinfo,
+               return copy_to_user(argp, &abinfo,
                                    sizeof(abinfo)) ? -EFAULT : 0;
        case SNDCTL_DSP_GETIPTR:
                if (!(file->f_mode & FMODE_READ))
@@ -2447,7 +2450,7 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes,
                       cinfo.blocks, cinfo.ptr, dmabuf->count);
 #endif
-               return copy_to_user((void *) arg, &cinfo, sizeof(cinfo))? -EFAULT: 0;
+               return copy_to_user(argp, &cinfo, sizeof(cinfo))? -EFAULT: 0;
        case SNDCTL_DSP_NONBLOCK:
 #ifdef DEBUG
                printk("SNDCTL_DSP_NONBLOCK\n");
@@ -2459,15 +2462,15 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                printk("SNDCTL_DSP_GETCAPS\n");
 #endif
                return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER |
-                               DSP_CAP_MMAP | DSP_CAP_BIND, (int *) arg);
+                               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, (int *) arg);
+               return put_user(dmabuf->trigger, p);
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
 #if defined(DEBUG) || defined(DEBUG_MMAP)
                printk("SNDCTL_DSP_SETTRIGGER 0x%x\n", val);
@@ -2586,27 +2589,27 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
 #ifdef DEBUG
                printk("SNDCTL_DSP_GETODELAY %d\n", dmabuf->count);
 #endif
-               return put_user(val, (int *) arg);
+               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, (int *) arg);
+               return put_user(dmabuf->rate, p);
        case SOUND_PCM_READ_CHANNELS:
 #ifdef DEBUG
                printk("SOUND_PCM_READ_CHANNELS\n");
 #endif
-               return put_user(2, (int *) arg);
+               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, (int *) arg);
+               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, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
                /* Check to make sure the codec supports S/PDIF transmitter */
                if ((state->card->ac97_features & 4)) {
@@ -2625,12 +2628,12 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                else
                        printk(KERN_WARNING "ali_audio: S/PDIF transmitter not avalible.\n");
 #endif
-               return put_user(val, (int *) arg);
+               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, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
                /* Check to make sure the codec supports S/PDIF transmitter */
                if (!(state->card->ac97_features & 4)) {
@@ -2642,14 +2645,14 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                        val = ali_ac97_get(codec, AC97_SPDIF_CONTROL);
                }
 
-               return put_user(val, (int *) arg);
+               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, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
                /* Based on AC'97 DAC support, not ICH hardware */
                val = DSP_BIND_FRONT;
@@ -2659,12 +2662,12 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                        val |= DSP_BIND_SURR;
                if (state->card->ac97_features & 0x0140)
                        val |= DSP_BIND_CENTER_LFE;
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
        case SNDCTL_DSP_BIND_CHANNEL:
 #ifdef DEBUG
                printk("SNDCTL_DSP_BIND_CHANNEL\n");
 #endif
-               if (get_user(val, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val == DSP_BIND_QUERY) {
                        val = DSP_BIND_FRONT;   /* Always report this as being enabled */
@@ -2749,7 +2752,7 @@ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                                        val &= ~DSP_BIND_CENTER_LFE;
                        }
                }
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
        case SNDCTL_DSP_MAPINBUF:
        case SNDCTL_DSP_MAPOUTBUF:
        case SNDCTL_DSP_SETSYNCRO:
index e53bd26..f49a2de 100644 (file)
@@ -3344,10 +3344,10 @@ readbuf_word(int pos)
        /* read from user buffer */
        if (readbuf_flags & AWE_SAMPLE_8BITS) {
                unsigned char cc;
-               get_user(cc, (unsigned __user char*)(readbuf_addr + readbuf_offs + pos));
+               get_user(cc, (unsigned char __user *)(readbuf_addr + readbuf_offs + pos));
                c = (unsigned short)cc << 8; /* convert 8bit -> 16bit */
        } else {
-               get_user(c, (unsigned __user short*)(readbuf_addr + readbuf_offs + pos * 2));
+               get_user(c, (unsigned short __user *)(readbuf_addr + readbuf_offs + pos * 2));
        }
        if (readbuf_flags & AWE_SAMPLE_UNSIGNED)
                c ^= 0x8000; /* unsigned -> signed */
index c8866da..2a7ea80 100644 (file)
@@ -327,6 +327,7 @@ static int btaudio_mixer_ioctl(struct inode *inode, struct file *file,
 {
        struct btaudio *bta = file->private_data;
        int ret,val=0,i=0;
+       void __user *argp = (void __user *)arg;
 
        if (cmd == SOUND_MIXER_INFO) {
                mixer_info info;
@@ -334,7 +335,7 @@ static int btaudio_mixer_ioctl(struct inode *inode, struct file *file,
                 strlcpy(info.id,"bt878",sizeof(info.id));
                 strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
                 info.modify_counter = bta->mixcount;
-                if (copy_to_user((void *)arg, &info, sizeof(info)))
+                if (copy_to_user(argp, &info, sizeof(info)))
                         return -EFAULT;
                return 0;
        }
@@ -343,16 +344,16 @@ static int btaudio_mixer_ioctl(struct inode *inode, struct file *file,
                memset(&info,0,sizeof(info));
                 strlcpy(info.id,"bt878",sizeof(info.id)-1);
                 strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
-                if (copy_to_user((void *)arg, &info, sizeof(info)))
+                if (copy_to_user(argp, &info, sizeof(info)))
                         return -EFAULT;
                return 0;
        }
        if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, (int *)arg);
+               return put_user(SOUND_VERSION, (int __user *)argp);
 
        /* read */
        if (_SIOC_DIR(cmd) & _SIOC_WRITE)
-               if (get_user(val, (int *)arg))
+               if (get_user(val, (int __user *)argp))
                        return -EFAULT;
 
        switch (cmd) {
@@ -421,7 +422,7 @@ static int btaudio_mixer_ioctl(struct inode *inode, struct file *file,
        default:
                return -EINVAL;
        }
-       if (put_user(ret, (int *)arg))
+       if (put_user(ret, (int __user *)argp))
                return -EFAULT;
        return 0;
 }
@@ -503,7 +504,7 @@ static int btaudio_dsp_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
+static ssize_t btaudio_dsp_read(struct file *file, char __user *buffer,
                                size_t swcount, loff_t *ppos)
 {
        struct btaudio *bta = file->private_data;
@@ -554,7 +555,7 @@ static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
                } else if (!bta->analog) {
                        /* stereo => mono (digital audio) */
                        __s16 *src = (__s16*)(bta->buf_cpu + bta->read_offset);
-                       __s16 *dst = (__s16*)(buffer + ret);
+                       __s16 __user *dst = (__s16 __user *)(buffer + ret);
                        __s16 avg;
                        int n = ndst>>1;
                        if (0 != verify_area(VERIFY_WRITE,dst,ndst)) {
@@ -565,13 +566,13 @@ static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
                        for (; n; n--, dst++) {
                                avg  = (__s16)le16_to_cpu(*src) / 2; src++;
                                avg += (__s16)le16_to_cpu(*src) / 2; src++;
-                               __put_user(cpu_to_le16(avg),(__u16*)(dst));
+                               __put_user(cpu_to_le16(avg),dst);
                        }
 
                } else if (8 == bta->bits) {
                        /* copy + byte downsampling (audio A/D) */
                        __u8 *src = bta->buf_cpu + bta->read_offset;
-                       __u8 *dst = buffer + ret;
+                       __u8 __user *dst = buffer + ret;
                        int n = ndst;
                        if (0 != verify_area(VERIFY_WRITE,dst,ndst)) {
                                if (0 == ret)
@@ -579,12 +580,12 @@ static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
                                break;
                        }
                        for (; n; n--, src += (1 << bta->sampleshift), dst++)
-                               __put_user(*src,(__u8*)(dst));
+                               __put_user(*src, dst);
 
                } else {
                        /* copy + word downsampling (audio A/D) */
                        __u16 *src = (__u16*)(bta->buf_cpu + bta->read_offset);
-                       __u16 *dst = (__u16*)(buffer + ret);
+                       __u16 __user *dst = (__u16 __user *)(buffer + ret);
                        int n = ndst>>1;
                        if (0 != verify_area(VERIFY_WRITE,dst,ndst)) {
                                if (0 == ret)
@@ -592,7 +593,7 @@ static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
                                break;
                        }
                        for (; n; n--, src += (1 << bta->sampleshift), dst++)
-                               __put_user(*src,(__u16*)(dst));
+                               __put_user(*src, dst);
                }
 
                ret     += ndst;
@@ -609,7 +610,7 @@ static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
        return ret;
 }
 
-static ssize_t btaudio_dsp_write(struct file *file, const char *buffer,
+static ssize_t btaudio_dsp_write(struct file *file, const char __user *buffer,
                                 size_t count, loff_t *ppos)
 {
        return -EINVAL;
@@ -620,15 +621,17 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
 {
        struct btaudio *bta = file->private_data;
        int s, i, ret, val = 0;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
        
         switch (cmd) {
         case OSS_GETVERSION:
-                return put_user(SOUND_VERSION, (int *)arg);
+                return put_user(SOUND_VERSION, p);
         case SNDCTL_DSP_GETCAPS:
                return 0;
 
         case SNDCTL_DSP_SPEED:
-               if (get_user(val, (int*)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (bta->analog) {
                        for (s = 0; s < 16; s++)
@@ -656,14 +659,14 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
                /* fall through */
         case SOUND_PCM_READ_RATE:
                if (bta->analog) {
-                       return put_user(HWBASE_AD*4/bta->decimation>>bta->sampleshift, (int*)arg);
+                       return put_user(HWBASE_AD*4/bta->decimation>>bta->sampleshift, p);
                } else {
-                       return put_user(bta->rate, (int*)arg);
+                       return put_user(bta->rate, p);
                }
 
         case SNDCTL_DSP_STEREO:
                if (!bta->analog) {
-                       if (get_user(val, (int*)arg))
+                       if (get_user(val, p))
                                return -EFAULT;
                        bta->channels    = (val > 0) ? 2 : 1;
                        bta->sampleshift = (bta->channels == 2) ? 0 : 1;
@@ -681,11 +684,11 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
                                               "btaudio: stereo=0 channels=1\n");
                        }
                }
-               return put_user((bta->channels)-1, (int *)arg);
+               return put_user((bta->channels)-1, p);
 
         case SNDCTL_DSP_CHANNELS:
                if (!bta->analog) {
-                       if (get_user(val, (int*)arg))
+                       if (get_user(val, p))
                                return -EFAULT;
                        bta->channels    = (val > 1) ? 2 : 1;
                        bta->sampleshift = (bta->channels == 2) ? 0 : 1;
@@ -696,16 +699,16 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
                }
                /* fall through */
         case SOUND_PCM_READ_CHANNELS:
-               return put_user(bta->channels, (int *)arg);
+               return put_user(bta->channels, p);
                
         case SNDCTL_DSP_GETFMTS: /* Returns a mask */
                if (bta->analog)
-                       return put_user(AFMT_S16_LE|AFMT_S8, (int*)arg);
+                       return put_user(AFMT_S16_LE|AFMT_S8, p);
                else
-                       return put_user(AFMT_S16_LE, (int*)arg);
+                       return put_user(AFMT_S16_LE, p);
 
         case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, (int*)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                 if (val != AFMT_QUERY) {
                        if (bta->analog)
@@ -722,10 +725,10 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
                if (debug)
                        printk(KERN_DEBUG "btaudio: fmt: bits=%d\n",bta->bits);
                 return put_user((bta->bits==16) ? AFMT_S16_LE : AFMT_S8,
-                               (int*)arg);
+                               p);
                break;
         case SOUND_PCM_READ_BITS:
-               return put_user(bta->bits, (int*)arg);
+               return put_user(bta->bits, p);
 
         case SNDCTL_DSP_NONBLOCK:
                 file->f_flags |= O_NONBLOCK;
@@ -745,7 +748,7 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
                        if (0 != (ret = make_risc(bta)))
                                return ret;
                }
-               return put_user(bta->block_bytes>>bta->sampleshift,(int*)arg);
+               return put_user(bta->block_bytes>>bta->sampleshift,p);
 
         case SNDCTL_DSP_SYNC:
                /* NOP */
@@ -764,7 +767,7 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
                               "returns %d/%d/%d/%d\n",
                               info.fragsize, info.fragstotal,
                               info.bytes, info.fragments);
-               if (copy_to_user((void *)arg, &info, sizeof(info)))
+               if (copy_to_user(argp, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
index 42c9041..c0da38b 100644 (file)
@@ -980,13 +980,13 @@ static void set_ac3(struct cm_state *s, unsigned rate)
        spin_unlock_irqrestore(&s->lock, flags);
 }
 
-static int trans_ac3(struct cm_state *s, void *dest, const char *source, int size)
+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 *src = (unsigned short *)source;
+       unsigned short __user *src = (unsigned short __user *)source;
        int err;
 
        do {
@@ -1639,6 +1639,8 @@ 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) {
@@ -1647,7 +1649,7 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
                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((void *)arg, &info, sizeof(info)))
+               if (copy_to_user(argp, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
@@ -1656,50 +1658,50 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
                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((void *)arg, &info, sizeof(info)))
+               if (copy_to_user(argp, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
        if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, (int *)arg);
+               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, (int *)arg);
+                       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, (int *)arg);
+                       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, (int *)arg);
+                       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, (int *)arg);
+                       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, (int *)arg);
+                       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, (int *)arg);
+                       return put_user(val, p);
 
                 case SOUND_MIXER_CAPS:
-                       return put_user(0, (int *)arg);
+                       return put_user(0, p);
 
                default:
                        i = _IOC_NR(cmd);
@@ -1707,7 +1709,7 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
                                 return -EINVAL;
                        if (!volidx[i])
                                return -EINVAL;
-                       return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
+                       return put_user(s->mix.vol[volidx[i]-1], p);
                }
        }
         if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE))
@@ -1715,7 +1717,7 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
        s->mix.modcnt++;
        switch (_IOC_NR(cmd)) {
        case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                i = generic_hweight32(val);
                for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
@@ -1734,7 +1736,7 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
                return 0;
 
        case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
                        if (!(val & (1 << i)))
@@ -1754,7 +1756,7 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
                i = _IOC_NR(cmd);
                if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
                        return -EINVAL;
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                l = val & 0xff;
                r = (val >> 8) & 0xff;
@@ -1829,7 +1831,7 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
                if (!volidx[i])
                        return -EINVAL;
                s->mix.vol[volidx[i]-1] = val;
-               return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
+               return put_user(s->mix.vol[volidx[i]-1], p);
        }
 }
 
@@ -1914,7 +1916,7 @@ static int drain_dac(struct cm_state *s, int nonblock)
 
 /* --------------------------------------------------------------------- */
 
-static ssize_t cm_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+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);
@@ -1975,11 +1977,11 @@ static ssize_t cm_read(struct file *file, char *buffer, size_t count, loff_t *pp
                }
                if (s->status & DO_BIGENDIAN_R) {
                        int     i, err;
-                       unsigned char *src, *dst;
+                       unsigned char *src;
+                       char __user *dst = buffer;
                        unsigned char data[2];
 
                        src = (unsigned char *) (s->dma_adc.rawbuf + swptr);
-                       dst = (unsigned char *) buffer;
                        // copy left/right sample at one time
                        for (i = 0; i < cnt / 2; i++) {
                                data[0] = src[1];
@@ -2016,7 +2018,7 @@ out:
        return ret;
 }
 
-static ssize_t cm_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+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);
@@ -2116,10 +2118,10 @@ static ssize_t cm_write(struct file *file, const char *buffer, size_t count, lof
                        swptr = (swptr + 2 * cnt) % s->dma_dac.dmasize;
                } else if ((s->status & DO_DUAL_DAC) && (s->status & DO_BIGENDIAN_W)) {
                        int     i, err;
-                       unsigned char *src, *dst0, *dst1;
+                       const char __user *src = buffer;
+                       unsigned char *dst0, *dst1;
                        unsigned char data[8];
 
-                       src = (unsigned char *) buffer;
                        dst0 = (unsigned char *) (s->dma_dac.rawbuf + swptr);
                        dst1 = (unsigned char *) (s->dma_adc.rawbuf + swptr);
                        // copy left/right sample at one time
@@ -2170,9 +2172,9 @@ static ssize_t cm_write(struct file *file, const char *buffer, size_t count, lof
                        swptr = (swptr + cnt) % s->dma_dac.dmasize;
                } else if (s->status & DO_DUAL_DAC) {
                        int     i, err;
-                       unsigned long *src, *dst0, *dst1;
+                       unsigned long __user *src = (unsigned long __user *) buffer;
+                       unsigned long *dst0, *dst1;
 
-                       src = (unsigned long *) buffer;
                        dst0 = (unsigned long *) (s->dma_dac.rawbuf + swptr);
                        dst1 = (unsigned long *) (s->dma_adc.rawbuf + swptr);
                        // copy left/right sample at one time
@@ -2189,10 +2191,10 @@ static ssize_t cm_write(struct file *file, const char *buffer, size_t count, lof
                        swptr = (swptr + cnt) % s->dma_dac.dmasize;
                } else if (s->status & DO_BIGENDIAN_W) {
                        int     i, err;
-                       unsigned char *src, *dst;
+                       const char __user *src = buffer;
+                       unsigned char *dst;
                        unsigned char data[2];
 
-                       src = (unsigned char *) buffer;
                        dst = (unsigned char *) (s->dma_dac.rawbuf + swptr);
                        // swap hi/lo bytes for each sample
                        for (i = 0; i < cnt / 2; i++) {
@@ -2330,13 +2332,15 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         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, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_SYNC:
                if (file->f_mode & FMODE_WRITE)
@@ -2347,7 +2351,7 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
        case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP | DSP_CAP_BIND, (int *)arg);
+               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) {
@@ -2365,7 +2369,7 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
         case SNDCTL_DSP_SPEED:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_READ) {
@@ -2383,10 +2387,10 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                                set_dac_rate(s, val);
                        }
                }
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
 
         case SNDCTL_DSP_STEREO:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                fmtd = 0;
                fmtm = ~0;
@@ -2417,7 +2421,7 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != 0) {
                        fmtd = 0;
@@ -2449,18 +2453,18 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        if ((s->capability & CAN_MULTI_CH)
                             && (file->f_mode & FMODE_WRITE)) {
                                val = set_dac_channels(s, val);
-                               return put_user(val, (int *)arg);
+                               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, (int *)arg);
+                                          : (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), (int *)arg);
+                       ((s->capability & CAN_AC3) ? AFMT_AC3 : 0), p);
 
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != AFMT_QUERY) {
                        fmtd = 0;
@@ -2503,9 +2507,9 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        }
                        set_fmt(s, fmtm, fmtd);
                }
-               if (s->status & DO_AC3) return put_user(AFMT_AC3, (int *)arg);
+               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, (int *)arg);
+                                          : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? val : AFMT_U8, p);
 
        case SNDCTL_DSP_POST:
                 return 0;
@@ -2517,16 +2521,16 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                         (s->enable & ENDAC) &&
                         (s->enable & ENADC))
                                val |= PCM_ENABLE_OUTPUT;
-                       return put_user(val, (int *)arg);
+                       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, (int *)arg);
+               return put_user(val, p);
 
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
@@ -2568,7 +2572,7 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                 abinfo.fragstotal = s->dma_dac.numfrag;
                 abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETISPACE:
                if (!(file->f_mode & FMODE_READ))
@@ -2582,7 +2586,7 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                 abinfo.fragstotal = s->dma_adc.numfrag;
                 abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_NONBLOCK:
                 file->f_flags |= O_NONBLOCK;
@@ -2595,7 +2599,7 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                cm_update_ptr(s);
                 val = s->dma_dac.count;
                spin_unlock_irqrestore(&s->lock, flags);
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
 
         case SNDCTL_DSP_GETIPTR:
                if (!(file->f_mode & FMODE_READ))
@@ -2608,7 +2612,7 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                if (s->dma_adc.mapped)
                        s->dma_adc.count &= s->dma_adc.fragsize-1;
                spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo))  ? -EFAULT : 0;
+                return copy_to_user(argp, &cinfo, sizeof(cinfo))  ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETOPTR:
                if (!(file->f_mode & FMODE_WRITE))
@@ -2625,7 +2629,7 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                                s->dma_adc.count &= s->dma_adc.fragsize-1;
                }
                spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+                return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
                if (file->f_mode & FMODE_WRITE) {
@@ -2634,16 +2638,16 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        if (s->status & DO_DUAL_DAC) {
                                if ((val = prog_dmabuf(s, 1)))
                                        return val;
-                               return put_user(2 * s->dma_dac.fragsize, (int *)arg);
+                               return put_user(2 * s->dma_dac.fragsize, p);
                        }
-                       return put_user(s->dma_dac.fragsize, (int *)arg);
+                       return put_user(s->dma_dac.fragsize, p);
                }
                if ((val = prog_dmabuf(s, 1)))
                        return val;
-               return put_user(s->dma_adc.fragsize, (int *)arg);
+               return put_user(s->dma_adc.fragsize, p);
 
         case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        s->dma_adc.ossfragshift = val & 0xffff;
@@ -2675,7 +2679,7 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                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))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
@@ -2689,22 +2693,22 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
         case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+               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, (int *)arg);
+               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, (int *)arg);
+               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, (int *)arg);
+               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, (int *)arg);
+               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, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val == DSP_BIND_QUERY) {
                        val = DSP_BIND_FRONT;
@@ -2757,7 +2761,7 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                                }
                        }
                }
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
 
        case SOUND_PCM_WRITE_FILTER:
        case SNDCTL_DSP_MAPINBUF:
@@ -2765,47 +2769,47 @@ static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         case SNDCTL_DSP_SETSYNCRO:
                 return -EINVAL;
        case SNDCTL_SPDIF_COPYRIGHT:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                set_spdif_copyright(s, val);
                 return 0;
        case SNDCTL_SPDIF_LOOP:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                set_spdif_loop(s, val);
                 return 0;
        case SNDCTL_SPDIF_MONITOR:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                set_spdif_monitor(s, val);
                 return 0;
        case SNDCTL_SPDIF_LEVEL:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                set_spdifout_level(s, val);
                 return 0;
        case SNDCTL_SPDIF_INV:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                set_spdifin_inverse(s, val);
                 return 0;
        case SNDCTL_SPDIF_SEL2:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                set_spdifin_channel2(s, val);
                 return 0;
        case SNDCTL_SPDIF_VALID:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                set_spdifin_valid(s, val);
                 return 0;
        case SNDCTL_SPDIFOUT:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                set_spdifout(s, val ? s->ratedac : 0);
                 return 0;
        case SNDCTL_SPDIFIN:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                set_spdifin(s, val ? s->rateadc : 0);
                 return 0;
@@ -3276,7 +3280,7 @@ MODULE_AUTHOR("ChenLi Tien, cltien@cmedia.com.tw");
 MODULE_DESCRIPTION("CM8x38 Audio Driver");
 MODULE_LICENSE("GPL");
 
-static void __devinit cm_remove(struct pci_dev *dev)
+static void __devexit cm_remove(struct pci_dev *dev)
 {
        struct cm_state *s = pci_get_drvdata(dev);
 
@@ -3333,7 +3337,7 @@ static struct pci_driver cm_driver = {
        .name    = "cmpci",
        .id_table = id_table,
        .probe   = cm_probe,
-       .remove  = cm_remove
+       .remove  = __devexit_p(cm_remove)
 };
 
 static int __init init_cmpci(void)
index 2f38ae7..c2b496e 100644 (file)
@@ -1694,7 +1694,7 @@ static void start_adc(struct cs4281_state *s)
 #define DMABUF_MINORDER 1      // ==> min buffer size = 8K.
 
 
-extern void dealloc_dmabuf(struct cs4281_state *s, struct dmabuf *db)
+void dealloc_dmabuf(struct cs4281_state *s, struct dmabuf *db)
 {
        struct page *map, *mapend;
 
@@ -2148,6 +2148,7 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
                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.
@@ -2195,26 +2196,26 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
 
                case SOUND_MIXER_CS_GETDBGMASK:
                        return put_user(cs_debugmask,
-                                       (unsigned long *) arg);
+                                       (unsigned long __user *) argp);
 
                case SOUND_MIXER_CS_GETDBGLEVEL:
                        return put_user(cs_debuglevel,
-                                       (unsigned long *) arg);
+                                       (unsigned long __user *) argp);
 
                case SOUND_MIXER_CS_SETDBGMASK:
-                       if (get_user(val, (unsigned long *) arg))
+                       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 *) arg))
+                       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 *) arg))
+                       if (get_user(val, (unsigned long __user *) argp))
                                return -EFAULT;
                        if(val == CS_IOCTL_CMD_SUSPEND)
                                cs4281_suspend(s);
@@ -2238,7 +2239,7 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
 
        if (cmd == SOUND_MIXER_PRIVATE1) {
                // enable/disable/query mixer preamp 
-               if (get_user(val, (int *) arg))
+               if (get_user(val, (int __user *) argp))
                        return -EFAULT;
                if (val != -1) {
                        cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
@@ -2247,11 +2248,11 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
                }
                cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
                val = (temp1 & 0x40) ? 1 : 0;
-               return put_user(val, (int *) arg);
+               return put_user(val, (int __user *) argp);
        }
        if (cmd == SOUND_MIXER_PRIVATE2) {
                // enable/disable/query spatializer 
-               if (get_user(val, (int *) arg))
+               if (get_user(val, (int __user *)argp))
                        return -EFAULT;
                if (val != -1) {
                        temp1 = (val & 0x3f) >> 2;
@@ -2262,14 +2263,14 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
                                          temp1 | 0x2000);
                }
                cs4281_read_ac97(s, BA0_AC97_3D_CONTROL, &temp1);
-               return put_user((temp1 << 2) | 3, (int *) arg);
+               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((void *) arg, &info, sizeof(info)))
+               if (copy_to_user(argp, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
@@ -2277,12 +2278,12 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
                _old_mixer_info info;
                strlcpy(info.id, "CS4281", sizeof(info.id));
                strlcpy(info.name, "Crystal CS4281", sizeof(info.name));
-               if (copy_to_user((void *) arg, &info, sizeof(info)))
+               if (copy_to_user(argp, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
        if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, (int *) arg);
+               return put_user(SOUND_VERSION, (int __user *) argp);
 
        if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
                return -EINVAL;
@@ -2292,9 +2293,8 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
        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 *) arg);
+                       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 |
@@ -2302,29 +2302,29 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
                                        SOUND_MASK_LINE1 | SOUND_MASK_MIC |
                                        SOUND_MASK_VOLUME |
                                        SOUND_MASK_RECLEV |
-                                       SOUND_MASK_SPEAKER, (int *) arg);
+                                       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 *) arg);
+                                       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 *) arg);
+                                       SOUND_MASK_RECLEV, (int __user *)argp);
 
                case SOUND_MIXER_CAPS:
-                       return put_user(SOUND_CAP_EXCL_INPUT, (int *) arg);
+                       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 *) arg);
+                       return put_user(s->mix.vol[vidx - 1], (int __user *)argp);
                }
        }
        // If ioctl doesn't have both the SIOC_READ and 
@@ -2339,7 +2339,7 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
        switch (_IOC_NR(cmd)) {
 
        case SOUND_MIXER_RECSRC:        // Arg contains a bit for each recording source 
-               if (get_user(val, (int *) arg))
+               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.
@@ -2356,7 +2356,7 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
                return 0;
 
        case SOUND_MIXER_VOLUME:
-               if (get_user(val, (int *) arg))
+               if (get_user(val, (int __user *)argp))
                        return -EFAULT;
                l = val & 0xff;
                if (l > 100)
@@ -2391,10 +2391,10 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
 #else
                s->mix.vol[8] = val;
 #endif
-               return put_user(s->mix.vol[8], (int *) arg);
+               return put_user(s->mix.vol[8], (int __user *)argp);
 
        case SOUND_MIXER_SPEAKER:
-               if (get_user(val, (int *) arg))
+               if (get_user(val, (int __user *)argp))
                        return -EFAULT;
                l = val & 0xff;
                if (l > 100)
@@ -2421,10 +2421,10 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
 #else
                s->mix.vol[6] = val;
 #endif
-               return put_user(s->mix.vol[6], (int *) arg);
+               return put_user(s->mix.vol[6], (int __user *)argp);
 
        case SOUND_MIXER_RECLEV:
-               if (get_user(val, (int *) arg))
+               if (get_user(val, (int __user *)argp))
                        return -EFAULT;
                l = val & 0xff;
                if (l > 100)
@@ -2447,10 +2447,10 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
 #else
                s->mix.vol[7] = val;
 #endif
-               return put_user(s->mix.vol[7], (int *) arg);
+               return put_user(s->mix.vol[7], (int __user *)argp);
 
        case SOUND_MIXER_MIC:
-               if (get_user(val, (int *) arg))
+               if (get_user(val, (int __user *)argp))
                        return -EFAULT;
                l = val & 0xff;
                if (l > 100)
@@ -2477,16 +2477,16 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
 #else
                s->mix.vol[5] = val;
 #endif
-               return put_user(s->mix.vol[5], (int *) arg);
+               return put_user(s->mix.vol[5], (int __user *)argp);
 
 
        case SOUND_MIXER_SYNTH:
-               if (get_user(val, (int *) arg))
+               if (get_user(val, (int __user *)argp))
                        return -EFAULT;
                l = val & 0xff;
                if (l > 100)
                        l = 100;
-               if (get_user(val, (int *) arg))
+               if (get_user(val, (int __user *)argp))
                        return -EFAULT;
                r = (val >> 8) & 0xff;
                if (r > 100)
@@ -2512,7 +2512,7 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
 #else
                s->mix.vol[4] = val;
 #endif
-               return put_user(s->mix.vol[4], (int *) arg);
+               return put_user(s->mix.vol[4], (int __user *)argp);
 
 
        default:
@@ -2522,7 +2522,7 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
                i = _IOC_NR(cmd);
                if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
                        return -EINVAL;
-               if (get_user(val, (int *) arg))
+               if (get_user(val, (int __user *)argp))
                        return -EFAULT;
                l = val & 0xff;
                if (l > 100)
@@ -2558,7 +2558,7 @@ static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
                        "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 *) arg);
+               return put_user(s->mix.vol[vidx - 1], (int __user *)argp);
        }
 }
 
@@ -2817,7 +2817,7 @@ static void CopySamples(char *dst, char *src, int count, int iChannels,
 // 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 *dest,
+static unsigned cs_copy_to_user(struct cs4281_state *s, void __user *dest,
                                unsigned *hwsrc, unsigned cnt,
                                unsigned *copied)
 {
@@ -2859,7 +2859,7 @@ static unsigned cs_copy_to_user(struct cs4281_state *s, void *dest,
 
 // --------------------------------------------------------------------- 
 
-static ssize_t cs4281_read(struct file *file, char *buffer, size_t count,
+static ssize_t cs4281_read(struct file *file, char __user *buffer, size_t count,
                           loff_t * ppos)
 {
        struct cs4281_state *s =
@@ -2975,7 +2975,7 @@ static ssize_t cs4281_read(struct file *file, char *buffer, size_t count,
 }
 
 
-static ssize_t cs4281_write(struct file *file, const char *buffer,
+static ssize_t cs4281_write(struct file *file, const char __user *buffer,
                            size_t count, loff_t * ppos)
 {
        struct cs4281_state *s =
@@ -3161,6 +3161,7 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
        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));
@@ -3175,7 +3176,7 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                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, (int *) arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_SYNC:
                CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
@@ -3192,7 +3193,7 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
        case SNDCTL_DSP_GETCAPS:
                return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
                                DSP_CAP_TRIGGER | DSP_CAP_MMAP,
-                               (int *) arg);
+                               p);
 
        case SNDCTL_DSP_RESET:
                CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
@@ -3216,7 +3217,7 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                return 0;
 
        case SNDCTL_DSP_SPEED:
-               if (get_user(val, (int *) arg))
+               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));
@@ -3257,10 +3258,10 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                else if (file->f_mode & FMODE_READ)
                        val = s->prop_adc.rate;
 
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
 
        case SNDCTL_DSP_STEREO:
-               if (get_user(val, (int *) arg))
+               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));
@@ -3279,7 +3280,7 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                return 0;
 
        case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, (int *) arg))
+               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",
@@ -3310,7 +3311,7 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                else if (file->f_mode & FMODE_READ)
                        val = s->prop_adc.channels;
 
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
 
        case SNDCTL_DSP_GETFMTS:        // Returns a mask 
                CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
@@ -3318,10 +3319,10 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                                 AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
                                 AFMT_U8));
                return put_user(AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
-                               AFMT_U8, (int *) arg);
+                               AFMT_U8, p);
 
        case SNDCTL_DSP_SETFMT:
-               if (get_user(val, (int *) arg))
+               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",
@@ -3358,7 +3359,7 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                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, (int *) arg);
+               return put_user(val, p);
 
        case SNDCTL_DSP_POST:
                CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
@@ -3371,10 +3372,10 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                        val |= PCM_ENABLE_INPUT;
                if (file->f_mode & s->ena & FMODE_WRITE)
                        val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
 
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
@@ -3416,7 +3417,7 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                                abinfo.fragsize,abinfo.bytes,abinfo.fragstotal,
                                abinfo.fragments));
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *) arg, &abinfo,
+               return copy_to_user(p, &abinfo,
                                    sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETISPACE:
@@ -3440,7 +3441,7 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                            abinfo.bytes >> s->dma_adc.fragshift;
                }
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *) arg, &abinfo,
+               return copy_to_user(p, &abinfo,
                                    sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_NONBLOCK:
@@ -3456,7 +3457,7 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                cs4281_update_ptr(s,CS_FALSE);
                val = s->dma_dac.count;
                spin_unlock_irqrestore(&s->lock, flags);
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
 
        case SNDCTL_DSP_GETIPTR:
                if (!(file->f_mode & FMODE_READ))
@@ -3489,7 +3490,7 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                if (s->dma_adc.mapped)
                        s->dma_adc.count &= s->dma_adc.fragsize - 1;
                spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+               if (copy_to_user(p, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -3515,7 +3516,7 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                if (s->dma_dac.mapped)
                        s->dma_dac.count &= s->dma_dac.fragsize - 1;
                spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+               if (copy_to_user(p, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -3523,18 +3524,17 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                if (file->f_mode & FMODE_WRITE) {
                        if ((val = prog_dmabuf_dac(s)))
                                return val;
-                       return put_user(s->dma_dac.fragsize, (int *) arg);
+                       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,
-                                       (int *) arg);
+                       return put_user(s->dma_adc.fragsize / 2, p);
                else
-                       return put_user(s->dma_adc.fragsize, (int *) arg);
+                       return put_user(s->dma_adc.fragsize, p);
 
        case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
                return 0;       // Say OK, but do nothing.
 
@@ -3542,7 +3542,7 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                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))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
@@ -3554,15 +3554,15 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
 
        case SOUND_PCM_READ_RATE:
                if (file->f_mode & FMODE_READ)
-                       return put_user(s->prop_adc.rate, (int *) arg);
+                       return put_user(s->prop_adc.rate, p);
                else if (file->f_mode & FMODE_WRITE)
-                       return put_user(s->prop_dac.rate, (int *) arg);
+                       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, (int *) arg);
+                       return put_user(s->prop_adc.channels, p);
                else if (file->f_mode & FMODE_WRITE)
-                       return put_user(s->prop_dac.channels, (int *) arg);
+                       return put_user(s->prop_dac.channels, p);
 
        case SOUND_PCM_READ_BITS:
                if (file->f_mode & FMODE_READ)
@@ -3570,13 +3570,13 @@ static int cs4281_ioctl(struct inode *inode, struct file *file,
                            put_user(
                                     (s->prop_adc.
                                      fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
-                                    (int *) arg);
+                                    p);
                else if (file->f_mode & FMODE_WRITE)
                        return
                            put_user(
                                     (s->prop_dac.
                                      fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
-                                    (int *) arg);
+                                    p);
 
        case SOUND_PCM_WRITE_FILTER:
        case SNDCTL_DSP_SETSYNCRO:
@@ -3831,7 +3831,7 @@ static void cs4281_midi_timer(unsigned long data)
 
 // --------------------------------------------------------------------- 
 
-static ssize_t cs4281_midi_read(struct file *file, char *buffer,
+static ssize_t cs4281_midi_read(struct file *file, char __user *buffer,
                                size_t count, loff_t * ppos)
 {
        struct cs4281_state *s =
@@ -3879,7 +3879,7 @@ static ssize_t cs4281_midi_read(struct file *file, char *buffer,
 }
 
 
-static ssize_t cs4281_midi_write(struct file *file, const char *buffer,
+static ssize_t cs4281_midi_write(struct file *file, const char __user *buffer,
                                 size_t count, loff_t * ppos)
 {
        struct cs4281_state *s =
index c50e45e..60fc6c6 100644 (file)
@@ -1717,7 +1717,7 @@ static irqreturn_t cs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 /**********************************************************************/
 
-static ssize_t cs_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t cs_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
         struct cs_card *card = (struct cs_card *)file->private_data;
         ssize_t ret;
@@ -1762,7 +1762,7 @@ static ssize_t cs_midi_read(struct file *file, char *buffer, size_t count, loff_
 }
 
 
-static ssize_t cs_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t cs_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
         struct cs_card *card = (struct cs_card *)file->private_data;
         ssize_t ret;
@@ -2037,7 +2037,7 @@ static void CopySamples(char *dst, char *src, int count, unsigned fmt,
  */
 static unsigned cs_copy_to_user(
        struct cs_state *s, 
-       void *dest, 
+       void __user *dest, 
        void *hwsrc, 
        unsigned cnt, 
        unsigned *copied)
@@ -2046,8 +2046,8 @@ static unsigned cs_copy_to_user(
        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 cnt=%d dest=0x%.8x\n",
-               dmabuf->fmt,(unsigned)cnt,(unsigned)dest) );
+               "cs_copy_to_user()+ fmt=0x%x cnt=%d dest=%p\n",
+               dmabuf->fmt,(unsigned)cnt,dest) );
 
        if(cnt > dmabuf->dmasize)
        {
@@ -2074,8 +2074,8 @@ static unsigned cs_copy_to_user(
         if (copy_to_user(dest, src, cnt))
        {
                CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR 
-                       "cs46xx: cs_copy_to_user()- fault dest=0x%x src=0x%x cnt=%d\n",
-                               (unsigned)dest,(unsigned)src,cnt) );
+                       "cs46xx: cs_copy_to_user()- fault dest=%p src=%p cnt=%d\n",
+                               dest,src,cnt) );
                *copied = 0;
                return -EFAULT;
        }
@@ -2087,7 +2087,7 @@ static unsigned cs_copy_to_user(
 
 /* 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 cs_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
        struct cs_card *card = (struct cs_card *) file->private_data;
        struct cs_state *state;
@@ -2165,8 +2165,8 @@ static ssize_t cs_read(struct file *file, char *buffer, size_t count, loff_t *pp
                CS_DBGOUT(CS_WAVE_READ, 2, printk(KERN_INFO 
                        "_read() copy_to cnt=%d count=%d ", cnt,count) );
                CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO 
-                       " .dmasize=%d .count=%d buffer=0x%.8x ret=%d\n",
-                       dmabuf->dmasize,dmabuf->count,(unsigned)buffer,ret) );
+                       " .dmasize=%d .count=%d buffer=%p ret=%d\n",
+                       dmabuf->dmasize,dmabuf->count,buffer,ret) );
 
                 if (cs_copy_to_user(state, buffer, 
                        (void *)((unsigned)dmabuf->rawbuf + swptr), cnt, &copied))
@@ -2196,7 +2196,7 @@ out2:
 
 /* 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 cs_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t cs_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
        struct cs_card *card = (struct cs_card *) file->private_data;
        struct cs_state *state;
@@ -2486,6 +2486,8 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
        audio_buf_info abinfo;
        count_info cinfo;
        int val, valsave, mapped, ret;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
 
        state = (struct cs_state *)card->states[0];
        if(state)
@@ -2507,7 +2509,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
        switch (cmd) 
        {
        case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_RESET:
                /* FIXME: spin_lock ? */
@@ -2550,7 +2552,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
        case SNDCTL_DSP_SPEED: /* set sample rate */
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_READ) {
@@ -2582,12 +2584,12 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                                file->f_mode & FMODE_WRITE ? "DAC" : "",
                                file->f_mode & FMODE_READ ? "ADC" : "",
                                dmabuf->rate ) );
-                       return put_user(dmabuf->rate, (int *)arg);
+                       return put_user(dmabuf->rate, p);
                }
-               return put_user(0, (int *)arg);
+               return put_user(0, p);
 
        case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_WRITE) {
                        state = (struct cs_state *)card->states[1];
@@ -2637,7 +2639,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                                dmabuf = &state->dmabuf;
                                if ((val = prog_dmabuf(state)))
                                        return val;
-                               return put_user(dmabuf->fragsize, (int *)arg);
+                               return put_user(dmabuf->fragsize, p);
                        }
                }
                if (file->f_mode & FMODE_READ) {
@@ -2648,16 +2650,16 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                                if ((val = prog_dmabuf(state)))
                                        return val;
                                return put_user(dmabuf->fragsize/dmabuf->divisor, 
-                                               (int *)arg);
+                                               p);
                        }
                }
-               return put_user(0, (int *)arg);
+               return put_user(0, p);
 
        case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format*/
-               return put_user(AFMT_S16_LE | AFMT_U8, (int *)arg);
+               return put_user(AFMT_S16_LE | AFMT_U8, p);
 
        case SNDCTL_DSP_SETFMT: /* Select sample format */
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(
                    "cs46xx: cs_ioctl() DSP_SETFMT %s %s %s %s\n",
@@ -2730,14 +2732,14 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                if(dmabuf)
                {
                        if(dmabuf->fmt & CS_FMT_16BIT)
-                               return put_user(AFMT_S16_LE, (int *)arg);
+                               return put_user(AFMT_S16_LE, p);
                        else
-                               return put_user(AFMT_U8, (int *)arg);
+                               return put_user(AFMT_U8, p);
                }
-               return put_user(0, (int *)arg);
+               return put_user(0, p);
 
        case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != 0) {
                        if (file->f_mode & FMODE_WRITE) {
@@ -2776,7 +2778,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        }
                }
                return put_user((dmabuf->fmt & CS_FMT_STEREO) ? 2 : 1,
-                               (int *)arg);
+                               p);
 
        case SNDCTL_DSP_POST:
                /*
@@ -2793,7 +2795,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                                dmabuf = &state->dmabuf;
                                if (dmabuf->subdivision)
                                        return -EINVAL;
-                               if (get_user(val, (int *)arg))
+                               if (get_user(val, p))
                                        return -EFAULT;
                                if (val != 1 && val != 2)
                                        return -EINVAL;
@@ -2807,7 +2809,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                                dmabuf = &state->dmabuf;
                                if (dmabuf->subdivision)
                                        return -EINVAL;
-                               if (get_user(val, (int *)arg))
+                               if (get_user(val, p))
                                        return -EFAULT;
                                if (val != 1 && val != 2)
                                        return -EINVAL;
@@ -2817,7 +2819,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
        case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                if (file->f_mode & FMODE_WRITE) {
@@ -2861,7 +2863,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
 
                        abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
                        spin_unlock_irqrestore(&state->card->lock, flags);
-                       return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+                       return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
                }
                return -ENODEV;
 
@@ -2879,7 +2881,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        abinfo.fragstotal = dmabuf->numfrag;
                        abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
                        spin_unlock_irqrestore(&state->card->lock, flags);
-                       return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+                       return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
                }
                return -ENODEV;
 
@@ -2889,7 +2891,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
 
        case SNDCTL_DSP_GETCAPS:
                return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP,
-                           (int *)arg);
+                           p);
 
        case SNDCTL_DSP_GETTRIGGER:
                val = 0;
@@ -2915,10 +2917,10 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        }
                }
                CS_DBGOUT(CS_IOCTL, 2, printk("cs46xx: DSP_GETTRIGGER()- val=0x%x\n",val) );
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
 
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        state = (struct cs_state *)card->states[0];
@@ -2961,7 +2963,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        cinfo.blocks = dmabuf->count/dmabuf->divisor >> dmabuf->fragshift;
                        cinfo.ptr = dmabuf->hwptr/dmabuf->divisor;
                        spin_unlock_irqrestore(&state->card->lock, flags);
-                       if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+                       if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                                return -EFAULT;
                        return 0;
                }
@@ -2996,7 +2998,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                            "cs46xx: GETOPTR bytes=%d blocks=%d ptr=%d\n",
                                cinfo.bytes,cinfo.blocks,cinfo.ptr) );
                        spin_unlock_irqrestore(&state->card->lock, flags);
-                       if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+                       if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                                return -EFAULT;
                        return 0;
                }
@@ -3019,7 +3021,7 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                }
                else
                        val = 0;
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
 
        case SOUND_PCM_READ_RATE:
                if(file->f_mode & FMODE_READ)
@@ -3029,9 +3031,9 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                if(state)
                {
                        dmabuf = &state->dmabuf;
-                       return put_user(dmabuf->rate, (int *)arg);
+                       return put_user(dmabuf->rate, p);
                }
-               return put_user(0, (int *)arg);
+               return put_user(0, p);
                
 
        case SOUND_PCM_READ_CHANNELS:
@@ -3043,9 +3045,9 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                {
                        dmabuf = &state->dmabuf;
                        return put_user((dmabuf->fmt & CS_FMT_STEREO) ? 2 : 1,
-                               (int *)arg);
+                               p);
                }
-               return put_user(0, (int *)arg);
+               return put_user(0, p);
 
        case SOUND_PCM_READ_BITS:
                if(file->f_mode & FMODE_READ)
@@ -3056,10 +3058,10 @@ static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                {
                        dmabuf = &state->dmabuf;
                        return put_user((dmabuf->fmt & CS_FMT_16BIT) ? 
-                               AFMT_S16_LE : AFMT_U8, (int *)arg);
+                               AFMT_S16_LE : AFMT_U8, p);
 
                }
-               return put_user(0, (int *)arg);
+               return put_user(0, p);
 
        case SNDCTL_DSP_MAPINBUF:
        case SNDCTL_DSP_MAPOUTBUF:
@@ -4164,6 +4166,7 @@ static int cs_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int
        struct ac97_codec *codec = (struct ac97_codec *)file->private_data;
        struct cs_card *card=NULL;
        struct list_head *entry;
+       unsigned long __user *p = (long __user *)arg;
 
 #if CSDEBUG_INTERFACE
         int val;
@@ -4178,25 +4181,25 @@ static int cs_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int
            {
 
                case SOUND_MIXER_CS_GETDBGMASK:
-                       return put_user(cs_debugmask, (unsigned long *)arg);
+                       return put_user(cs_debugmask, p);
                
                case SOUND_MIXER_CS_GETDBGLEVEL:
-                       return put_user(cs_debuglevel, (unsigned long *)arg);
+                       return put_user(cs_debuglevel, p);
 
                case SOUND_MIXER_CS_SETDBGMASK:
-                       if (get_user(val, (unsigned long *)arg))
+                       if (get_user(val, p))
                                return -EFAULT;
                        cs_debugmask = val;
                        return 0;
 
                case SOUND_MIXER_CS_SETDBGLEVEL:
-                       if (get_user(val, (unsigned long *)arg))
+                       if (get_user(val, p))
                                return -EFAULT;
                        cs_debuglevel = val;
                        return 0;
 
                case SOUND_MIXER_CS_APM:
-                       if (get_user(val, (unsigned long *) arg))
+                       if (get_user(val, p))
                                return -EFAULT;
                        if(val == CS_IOCTL_CMD_SUSPEND) 
                        {
index da68171..fc19d66 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 
-#include <asm/pgalloc.h>
 #include <asm/uaccess.h>
 #include <asm/atariints.h>
 #include <asm/atari_stram.h>
index 42fae03..1aac365 100644 (file)
@@ -50,7 +50,7 @@ static void calculate_ofrag(struct woinst *);
 static void calculate_ifrag(struct wiinst *);
 
 /* Audio file operations */
-static ssize_t emu10k1_audio_read(struct file *file, char *buffer, size_t count, loff_t * ppos)
+static ssize_t emu10k1_audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
 {
        struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
        struct wiinst *wiinst = wave_dev->wiinst;
@@ -112,7 +112,7 @@ static ssize_t emu10k1_audio_read(struct file *file, char *buffer, size_t count,
                    || (bytestocopy >= count)) {
                        bytestocopy = min_t(u32, bytestocopy, count);
 
-                       emu10k1_wavein_xferdata(wiinst, (u8 *) buffer, &bytestocopy);
+                       emu10k1_wavein_xferdata(wiinst, (u8 __user *)buffer, &bytestocopy);
 
                        count -= bytestocopy;
                        buffer += bytestocopy;
@@ -137,7 +137,7 @@ static ssize_t emu10k1_audio_read(struct file *file, char *buffer, size_t count,
        return ret;
 }
 
-static ssize_t emu10k1_audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
+static ssize_t emu10k1_audio_write(struct file *file, const char __user *buffer, size_t count, loff_t * ppos)
 {
        struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
        struct woinst *woinst = wave_dev->woinst;
@@ -212,7 +212,7 @@ static ssize_t emu10k1_audio_write(struct file *file, const char *buffer, size_t
 
                        bytestocopy = min_t(u32, bytestocopy, count);
 
-                       emu10k1_waveout_xferdata(woinst, (u8 *) buffer, &bytestocopy);
+                       emu10k1_waveout_xferdata(woinst, (u8 __user *) buffer, &bytestocopy);
 
                        count -= bytestocopy;
                        buffer += bytestocopy * woinst->num_voices;
@@ -254,6 +254,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        int val = 0;
        u32 bytestocopy;
        unsigned long flags;
+       int __user *p = (int __user *)arg;
 
        DPF(4, "emu10k1_audio_ioctl()\n");
 
@@ -266,7 +267,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        switch (cmd) {
        case OSS_GETVERSION:
                DPF(2, "OSS_GETVERSION:\n");
-               return put_user(SOUND_VERSION, (int *) arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_RESET:
                DPF(2, "SNDCTL_DSP_RESET:\n");
@@ -352,11 +353,11 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                DPF(2, "SNDCTL_DSP_GETCAPS:\n");
                return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
                                DSP_CAP_TRIGGER | DSP_CAP_MMAP |
-                               DSP_CAP_COPROC| DSP_CAP_MULTI, (int *) arg);
+                               DSP_CAP_COPROC| DSP_CAP_MULTI, p);
        case SNDCTL_DSP_SPEED:
                DPF(2, "SNDCTL_DSP_SPEED:\n");
 
-               if (get_user(val, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                DPD(2, "val is %d\n", val);
@@ -402,21 +403,21 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                                DPD(2, "set playback sampling rate -> %d\n", val);
                        }
 
-                       return put_user(val, (int *) arg);
+                       return put_user(val, p);
                } else {
                        if (file->f_mode & FMODE_READ)
                                val = wiinst->format.samplingrate;
                        else if (file->f_mode & FMODE_WRITE)
                                val = woinst->format.samplingrate;
 
-                       return put_user(val, (int *) arg);
+                       return put_user(val, p);
                }
                break;
 
        case SNDCTL_DSP_STEREO:
                DPF(2, "SNDCTL_DSP_STEREO:\n");
 
-               if (get_user(val, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                DPD(2, " val is %d\n", val);
@@ -460,14 +461,14 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                        DPD(2, "set playback stereo -> %d\n", val);
                }
 
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
 
                break;
 
        case SNDCTL_DSP_CHANNELS:
                DPF(2, "SNDCTL_DSP_CHANNELS:\n");
 
-               if (get_user(val, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                DPD(2, " val is %d\n", val);
@@ -510,14 +511,14 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                                DPD(2, "set playback number of channels -> %d\n", val);
                        }
 
-                       return put_user(val, (int *) arg);
+                       return put_user(val, p);
                } else {
                        if (file->f_mode & FMODE_READ)
                                val = wiinst->format.channels;
                        else if (file->f_mode & FMODE_WRITE)
                                val = woinst->format.channels;
 
-                       return put_user(val, (int *) arg);
+                       return put_user(val, p);
                }
                break;
 
@@ -533,12 +534,12 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                                                     wave_dev->card->pt.enable_gpr_name) >= 0)
                                val |= AFMT_AC3;
                }
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
 
        case SNDCTL_DSP_SETFMT: /* Same as SNDCTL_DSP_SAMPLESIZE */
                DPF(2, "SNDCTL_DSP_SETFMT:\n");
 
-               if (get_user(val, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                DPD(2, " val is %d\n", val);
@@ -582,14 +583,14 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                                DPD(2, "set playback format -> %d\n", val);
                        }
 
-                       return put_user(val, (int *) arg);
+                       return put_user(val, p);
                } else {
                        if (file->f_mode & FMODE_READ)
                                val = wiinst->format.id;
                        else if (file->f_mode & FMODE_WRITE)
                                val = woinst->format.id;
 
-                       return put_user(val, (int *) arg);
+                       return put_user(val, p);
                }
                break;
 
@@ -600,7 +601,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                else if (file->f_mode & FMODE_WRITE)
                        val = woinst->format.bitsperchannel;
 
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
 
        case SOUND_PCM_READ_RATE:
 
@@ -609,7 +610,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                else if (file->f_mode & FMODE_WRITE)
                        val = woinst->format.samplingrate;
 
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
 
        case SOUND_PCM_READ_CHANNELS:
 
@@ -618,7 +619,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                else if (file->f_mode & FMODE_WRITE)
                        val = woinst->format.channels;
 
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
 
        case SOUND_PCM_WRITE_FILTER:
                DPF(2, "SOUND_PCM_WRITE_FILTER: not implemented\n");
@@ -641,12 +642,12 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                if (file->f_mode & FMODE_READ && (wave_dev->enablebits & PCM_ENABLE_INPUT))
                        val |= PCM_ENABLE_INPUT;
 
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
 
        case SNDCTL_DSP_SETTRIGGER:
                DPF(2, "SNDCTL_DSP_SETTRIGGER:\n");
 
-               if (get_user(val, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                if (file->f_mode & FMODE_WRITE) {
@@ -708,7 +709,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                        info.fragstotal = woinst->buffer.numfrags * woinst->num_voices;
                        info.fragments = info.bytes / info.fragsize;
 
-                       if (copy_to_user((int *) arg, &info, sizeof(info)))
+                       if (copy_to_user(p, &info, sizeof(info)))
                                return -EFAULT;
                }
                break;
@@ -737,7 +738,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                        info.fragments = info.bytes / wiinst->buffer.fragment_size;
                        info.fragsize = wiinst->buffer.fragment_size;
 
-                       if (copy_to_user((int *) arg, &info, sizeof(info)))
+                       if (copy_to_user(p, &info, sizeof(info)))
                                return -EFAULT;
                }
                break;
@@ -765,7 +766,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                val *= woinst->num_voices;
                spin_unlock_irqrestore(&woinst->lock, flags);
 
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
 
        case SNDCTL_DSP_GETIPTR:
                {
@@ -795,7 +796,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
 
                        spin_unlock_irqrestore(&wiinst->lock, flags);
 
-                       if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+                       if (copy_to_user(p, &cinfo, sizeof(cinfo)))
                                return -EFAULT;
                }
                break;
@@ -841,7 +842,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
 
                        spin_unlock_irqrestore(&woinst->lock, flags);
 
-                       if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+                       if (copy_to_user(p, &cinfo, sizeof(cinfo)))
                                return -EFAULT;
                }
                break;
@@ -867,7 +868,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                        spin_unlock_irqrestore(&wiinst->lock, flags);
                }
 
-               return put_user(val, (int *) arg);
+               return put_user(val, p);
 
                break;
 
@@ -892,7 +893,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        case SNDCTL_DSP_SETFRAGMENT:
                DPF(2, "SNDCTL_DSP_SETFRAGMENT:\n");
 
-               if (get_user(val, (int *) arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                DPD(2, "val is %#x\n", val);
@@ -930,7 +931,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                        if (!buf)
                                return -ENOMEM;
 
-                       if (copy_from_user(buf, (copr_buffer *) arg, sizeof(copr_buffer))) {
+                       if (copy_from_user(buf, p, sizeof(copr_buffer))) {
                                kfree (buf);
                                return -EFAULT;
                        }
@@ -969,7 +970,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
                                for (i = 0; i < buf->len; i++)
                                        ((u32 *) buf->data)[i] = sblive_readptr(wave_dev->card, buf->offs + i, buf->flags);
 
-                               if (copy_to_user((copr_buffer *) arg, buf, sizeof(copr_buffer))) {
+                               if (copy_to_user(p, buf, sizeof(copr_buffer))) {
                                        kfree(buf);
                                        return -EFAULT;
                                }
index ce6f698..a6b0495 100644 (file)
@@ -304,7 +304,7 @@ void emu10k1_wavein_getxfersize(struct wiinst *wiinst, u32 * size)
        }
 }
 
-static void copy_block(u8 *dst, u8 * src, u32 str, u32 len, u8 cov)
+static void copy_block(u8 __user *dst, u8 * src, u32 str, u32 len, u8 cov)
 {
        if (cov == 1)
                __copy_to_user(dst, src + str, len);
@@ -321,7 +321,7 @@ static void copy_block(u8 *dst, u8 * src, u32 str, u32 len, u8 cov)
        }
 }
 
-void emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 data, u32 * size)
+void emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 __user *data, u32 * size)
 {
        struct wavein_buffer *buffer = &wiinst->buffer;
        u32 sizetocopy, sizetocopy_now, start;
index c08e53b..15cfb9b 100644 (file)
@@ -83,7 +83,7 @@ void emu10k1_wavein_close(struct emu10k1_wavedevice *);
 void emu10k1_wavein_start(struct emu10k1_wavedevice *);
 void emu10k1_wavein_stop(struct emu10k1_wavedevice *);
 void emu10k1_wavein_getxfersize(struct wiinst *, u32 *);
-void emu10k1_wavein_xferdata(struct wiinst *, u8 *, u32 *);
+void emu10k1_wavein_xferdata(struct wiinst *, u8 __user *, u32 *);
 int emu10k1_wavein_setformat(struct emu10k1_wavedevice *, struct wave_format *);
 void emu10k1_wavein_update(struct emu10k1_card *, struct wiinst *);
 
index 5cc3afa..54daca4 100644 (file)
@@ -417,7 +417,7 @@ void emu10k1_waveout_getxfersize(struct woinst *woinst, u32 *total_free_bytes)
  * Notice that the voice buffer is actually a set of disjointed memory pages.
  *
  */
-static void copy_block(void **dst, u32 str, u8 *src, u32 len)
+static void copy_block(void **dst, u32 str, u8 __user *src, u32 len)
 {
        unsigned int pg;
        unsigned int pgoff;
@@ -451,7 +451,7 @@ static void copy_block(void **dst, u32 str, u8 *src, u32 len)
  * Notice that the voice buffer is actually a set of disjointed memory pages.
  *
  */
-static void copy_ilv_block(struct woinst *woinst, u32 str, u8 *src, u32 len) 
+static void copy_ilv_block(struct woinst *woinst, u32 str, u8 __user *src, u32 len) 
 {
         unsigned int pg;
        unsigned int pgoff;
@@ -524,7 +524,7 @@ static void fill_block(struct woinst *woinst, u32 str, u8 data, u32 len)
  * previously added to the buffer are overwritten.
  *
  */
-void emu10k1_waveout_xferdata(struct woinst *woinst, u8 *data, u32 *size)
+void emu10k1_waveout_xferdata(struct woinst *woinst, u8 __user *data, u32 *size)
 {
        struct waveout_buffer *buffer = &woinst->buffer;
        struct voice_mem *mem = &woinst->voice[0].mem;
index 70eb9a3..1dece88 100644 (file)
@@ -82,7 +82,7 @@ void emu10k1_waveout_close(struct emu10k1_wavedevice *);
 void emu10k1_waveout_start(struct emu10k1_wavedevice *);
 void emu10k1_waveout_stop(struct emu10k1_wavedevice *);
 void emu10k1_waveout_getxfersize(struct woinst*, u32 *);
-void emu10k1_waveout_xferdata(struct woinst*, u8*, u32 *);
+void emu10k1_waveout_xferdata(struct woinst*, u8 __user *, u32 *);
 void emu10k1_waveout_fillsilence(struct woinst*);
 int emu10k1_waveout_setformat(struct emu10k1_wavedevice*, struct wave_format*);
 void emu10k1_waveout_update(struct woinst*);
index 06a7899..1aa768f 100644 (file)
@@ -244,7 +244,7 @@ static int emu10k1_midi_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t emu10k1_midi_read(struct file *file, char *buffer, size_t count, loff_t * pos)
+static ssize_t emu10k1_midi_read(struct file *file, char __user *buffer, size_t count, loff_t * pos)
 {
        struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
        ssize_t ret = 0;
@@ -319,7 +319,7 @@ static ssize_t emu10k1_midi_read(struct file *file, char *buffer, size_t count,
        return ret;
 }
 
-static ssize_t emu10k1_midi_write(struct file *file, const char *buffer, size_t count, loff_t * pos)
+static ssize_t emu10k1_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t * pos)
 {
        struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
        struct midi_hdr *midihdr;
index bc252de..cbcaaa3 100644 (file)
@@ -188,6 +188,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
        u32 size, page;
        int addr, size_reg, i, ret;
        unsigned int id, ch;
+       void __user *argp = (void __user *)arg;
 
        switch (cmd) {
 
@@ -197,7 +198,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
                if (ctl == NULL)
                        return -ENOMEM;
 
-               if (copy_from_user(ctl, (void *) arg, sizeof(struct mixer_private_ioctl))) {
+               if (copy_from_user(ctl, argp, sizeof(struct mixer_private_ioctl))) {
                        kfree(ctl);
                        return -EFAULT;
                }
@@ -228,7 +229,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
                case CMD_READFN0:
                        ctl->val[2] = emu10k1_readfn0(card, ctl->val[0]);
 
-                       if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+                       if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
                                ret = -EFAULT;
 
                        break;
@@ -244,7 +245,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
 
                        ctl->val[2] = sblive_readptr(card, ctl->val[0], ctl->val[1]);
 
-                       if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+                       if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
                                ret = -EFAULT;
 
                        break;
@@ -282,7 +283,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
                case CMD_GETRECSRC:
                        ctl->val[0] = card->wavein.recsrc;
                        ctl->val[1] = card->wavein.fxwc;
-                       if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+                       if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
                                ret = -EFAULT;
 
                        break;
@@ -297,7 +298,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
                        ctl->val[4] = card->waveout.send_routing[2];
                        ctl->val[5] = card->waveout.send_dcba[2];
 
-                       if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+                       if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
                                ret = -EFAULT;
 
                        break;
@@ -320,7 +321,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
                
                case CMD_GETPATCH:
                        if (ctl->val[0] == 0) {
-                               if (copy_to_user((void *) arg, &card->mgr.rpatch, sizeof(struct dsp_rpatch)))
+                               if (copy_to_user(argp, &card->mgr.rpatch, sizeof(struct dsp_rpatch)))
                                        ret = -EFAULT;
                        } else {
                                if ((ctl->val[0] - 1) / PATCHES_PER_PAGE >= card->mgr.current_pages) {
@@ -328,7 +329,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
                                        break;
                                }
 
-                               if (copy_to_user((void *) arg, PATCH(&card->mgr, ctl->val[0] - 1), sizeof(struct dsp_patch)))
+                               if (copy_to_user(argp, PATCH(&card->mgr, ctl->val[0] - 1), sizeof(struct dsp_patch)))
                                        ret = -EFAULT;
                        }
 
@@ -342,7 +343,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
                                break;
                        }
 
-                       if (copy_to_user((void *) arg, &card->mgr.gpr[id], sizeof(struct dsp_gpr)))
+                       if (copy_to_user(argp, &card->mgr.gpr[id], sizeof(struct dsp_gpr)))
                                ret = -EFAULT;
 
                        break;
@@ -351,7 +352,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
                        addr = emu10k1_find_control_gpr(&card->mgr, (char *) ctl->val, &((char *) ctl->val)[PATCH_NAME_SIZE]);
                        ctl->val[0] = sblive_readptr(card, addr, 0);
 
-                       if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+                       if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
                                ret = -EFAULT;
 
                        break;
@@ -430,7 +431,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
 
                        ctl->val[2] = card->mgr.ctrl_gpr[id][ch];
 
-                       if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+                       if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
                                ret = -EFAULT;
 
                        break;
@@ -496,7 +497,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
                        if (card->is_audigy)
                                ctl->val[4]=emu10k1_readfn0(card, 0x18);
 
-                       if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+                       if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
                                ret = -EFAULT;
                        break;
 
@@ -517,7 +518,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
 
        case SOUND_MIXER_PRIVATE4:
 
-               if (copy_from_user(&size, (void *) arg, sizeof(size)))
+               if (copy_from_user(&size, argp, sizeof(size)))
                        return -EFAULT;
 
                DPD(2, "External tram size %#x\n", size);
@@ -581,7 +582,7 @@ static int emu10k1_dsp_mixer(struct emu10k1_card *card, unsigned int oss_mixer,
 
        card->ac97->modcnt++;
 
-       if (get_user(val, (int *)arg))
+       if (get_user(val, (int __user *)arg))
                return -EFAULT;
 
        /* cleanse input a little */
@@ -634,7 +635,7 @@ static int emu10k1_mixer_ioctl(struct inode *inode, struct file *file, unsigned
                                
                        info.modify_counter = card->ac97->modcnt;
 
-                       if (copy_to_user((void *)arg, &info, sizeof(info)))
+                       if (copy_to_user((void __user *)arg, &info, sizeof(info)))
                                return -EFAULT;
 
                        return 0;
index 805840e..4094be5 100644 (file)
@@ -131,7 +131,7 @@ int emu10k1_pt_setup(struct emu10k1_wavedevice *wave_dev)
        return 0;
 }
 
-ssize_t emu10k1_pt_write(struct file *file, const char *buffer, size_t count)
+ssize_t emu10k1_pt_write(struct file *file, const char __user *buffer, size_t count)
 {
        struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
        struct emu10k1_card *card = wave_dev->card;
@@ -177,10 +177,9 @@ ssize_t emu10k1_pt_write(struct file *file, const char *buffer, size_t count)
        blocks = (count-bytes_copied)/PT_BLOCKSIZE;
        blocks_copied = 0;
        while (blocks > 0) {
-               u16 *bufptr = (u16 *) buffer + (bytes_copied/2);
+               u16 __user *bufptr = (u16 __user *) buffer + (bytes_copied/2);
                copy_from_user(pt->buf, bufptr, PT_BLOCKSIZE);
-               bufptr = (u16 *) pt->buf;
-               r = pt_putblock(wave_dev, bufptr, nonblock);
+               r = pt_putblock(wave_dev, (u16 *)pt->buf, nonblock);
                if (r) {
                        if (bytes_copied)
                                return bytes_copied;
index 3c78553..420cc97 100644 (file)
@@ -90,7 +90,7 @@ struct pt_data
 #define USE_PT_METHOD2  (card->is_audigy)
 #define USE_PT_METHOD1 !USE_PT_METHOD2
 
-ssize_t emu10k1_pt_write(struct file *file, const char *buf, size_t count);
+ssize_t emu10k1_pt_write(struct file *file, const char __user *buf, size_t count);
 
 int emu10k1_pt_setup(struct emu10k1_wavedevice *wave_dev);
 void emu10k1_pt_stop(struct emu10k1_card *card);
index 4478d7d..6818985 100644 (file)
@@ -845,21 +845,22 @@ static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long a
        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, (int *)arg))
+               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, (int *)arg);
+               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, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != -1) {
                        spin_lock_irqsave(&s->lock, flags);
@@ -870,11 +871,11 @@ static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long a
                        outl(s->ctrl, s->io+ES1370_REG_CONTROL);
                        spin_unlock_irqrestore(&s->lock, flags);
                }
-               return put_user((s->ctrl & CTRL_XCTL0) ? 1 : 0, (int *)arg);
+               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, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != -1) {
                        spin_lock_irqsave(&s->lock, flags);
@@ -885,14 +886,14 @@ static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long a
                        outl(s->ctrl, s->io+ES1370_REG_CONTROL);
                        spin_unlock_irqrestore(&s->lock, flags);
                }
-               return put_user((s->ctrl & CTRL_XCTL1) ? 1 : 0, (int *)arg);
+               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 *)arg, &info, sizeof(info)))
+               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
@@ -900,49 +901,49 @@ static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long a
                _old_mixer_info info;
                strncpy(info.id, "ES1370", sizeof(info.id));
                strncpy(info.name, "Ensoniq ES1370", sizeof(info.name));
-               if (copy_to_user((void *)arg, &info, sizeof(info)))
+               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
        if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, (int *)arg);
+               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, (int *)arg);
+                       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, (int *)arg);
+                       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, (int *)arg);
+                       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, (int *)arg);
+                       return put_user(val, p);
                        
                 case SOUND_MIXER_CAPS:
-                       return put_user(0, (int *)arg);
+                       return put_user(0, p);
                
                case SOUND_MIXER_IMIX:
-                       return put_user(s->mix.imix, (int *)arg);
+                       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], (int *)arg);
+                       return put_user(s->mix.vol[mixtable[i].volidx], p);
                }
        }
         if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) 
@@ -951,13 +952,13 @@ static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long a
        switch (_IOC_NR(cmd)) {
 
        case SOUND_MIXER_IMIX:
-               if (get_user(s->mix.imix, (int *)arg))
+               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, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                set_recsrc(s, val);
                return 0;
@@ -966,7 +967,7 @@ static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long a
                i = _IOC_NR(cmd);
                if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
                        return -EINVAL;
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                l = val & 0xff;
                if (l > 100)
@@ -1015,7 +1016,7 @@ static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long a
 #else
                s->mix.vol[mixtable[i].volidx] = val;
 #endif
-                return put_user(s->mix.vol[mixtable[i].volidx], (int *)arg);
+                return put_user(s->mix.vol[mixtable[i].volidx], p);
        }
 }
 
@@ -1136,7 +1137,7 @@ static int drain_dac2(struct es1370_state *s, int nonblock)
 
 /* --------------------------------------------------------------------- */
 
-static ssize_t es1370_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+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);
@@ -1214,7 +1215,7 @@ out:
        return ret;
 }
 
-static ssize_t es1370_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+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);
@@ -1386,13 +1387,15 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
         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, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_SYNC:
                if (file->f_mode & FMODE_WRITE)
@@ -1403,7 +1406,7 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
        case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+               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) {
@@ -1419,7 +1422,7 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val >= 0) {
                        if (s->open_mode & (~file->f_mode) & (FMODE_READ|FMODE_WRITE))
@@ -1436,10 +1439,10 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        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), (int *)arg);
+               return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), p);
                
         case SNDCTL_DSP_STEREO:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        stop_adc(s);
@@ -1466,7 +1469,7 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 0) {
                        if (file->f_mode & FMODE_READ) {
@@ -1492,13 +1495,13 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                                spin_unlock_irqrestore(&s->lock, flags);
                        }
                }
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, (int *)arg);
+               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, (int *)arg);
+                return put_user(AFMT_S16_LE|AFMT_U8, p);
                
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != AFMT_QUERY) {
                        if (file->f_mode & FMODE_READ) {
@@ -1525,7 +1528,7 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        }
                }
                return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 
-                               AFMT_S16_LE : AFMT_U8, (int *)arg);
+                               AFMT_S16_LE : AFMT_U8, p);
                
        case SNDCTL_DSP_POST:
                 return 0;
@@ -1536,10 +1539,10 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        val |= PCM_ENABLE_INPUT;
                if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) 
                        val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
                
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
@@ -1580,7 +1583,7 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                 abinfo.fragstotal = s->dma_dac2.numfrag;
                 abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift;      
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETISPACE:
                if (!(file->f_mode & FMODE_READ))
@@ -1597,7 +1600,7 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                 abinfo.fragstotal = s->dma_adc.numfrag;
                 abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
                
         case SNDCTL_DSP_NONBLOCK:
                 file->f_flags |= O_NONBLOCK;
@@ -1614,7 +1617,7 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                spin_unlock_irqrestore(&s->lock, flags);
                if (count < 0)
                        count = 0;
-               return put_user(count, (int *)arg);
+               return put_user(count, p);
 
         case SNDCTL_DSP_GETIPTR:
                if (!(file->f_mode & FMODE_READ))
@@ -1632,7 +1635,7 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                if (s->dma_adc.mapped)
                        s->dma_adc.count &= s->dma_adc.fragsize-1;
                spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -1652,7 +1655,7 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                if (s->dma_dac2.mapped)
                        s->dma_dac2.count &= s->dma_dac2.fragsize-1;
                spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -1660,14 +1663,14 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                if (file->f_mode & FMODE_WRITE) {
                        if ((val = prog_dmabuf_dac2(s)))
                                return val;
-                       return put_user(s->dma_dac2.fragsize, (int *)arg);
+                       return put_user(s->dma_dac2.fragsize, p);
                }
                if ((val = prog_dmabuf_adc(s)))
                        return val;
-               return put_user(s->dma_adc.fragsize, (int *)arg);
+               return put_user(s->dma_adc.fragsize, p);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        s->dma_adc.ossfragshift = val & 0xffff;
@@ -1695,7 +1698,7 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                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, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
@@ -1706,15 +1709,15 @@ static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
         case SOUND_PCM_READ_RATE:
-               return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), (int *)arg);
+               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, (int *)arg);
+                               2 : 1, p);
 
         case SOUND_PCM_READ_BITS:
                return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 
-                               16 : 8, (int *)arg);
+                               16 : 8, p);
 
         case SOUND_PCM_WRITE_FILTER:
         case SNDCTL_DSP_SETSYNCRO:
@@ -1828,7 +1831,7 @@ static /*const*/ struct file_operations es1370_audio_fops = {
 
 /* --------------------------------------------------------------------- */
 
-static ssize_t es1370_write_dac(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+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);
@@ -1961,11 +1964,12 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
        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, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_SYNC:
                return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/);
@@ -1974,7 +1978,7 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return -EINVAL;
 
        case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+               return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
                
         case SNDCTL_DSP_RESET:
                stop_dac1(s);
@@ -1983,7 +1987,7 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val >= 0) {
                        stop_dac1(s);
@@ -1996,10 +2000,10 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                        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], (int *)arg);
+               return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], p);
                
         case SNDCTL_DSP_STEREO:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                stop_dac1(s);
                s->dma_dac1.ready = 0;
@@ -2013,7 +2017,7 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 0) {
                        if (s->dma_dac1.mapped)
@@ -2028,13 +2032,13 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                        outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
                        spin_unlock_irqrestore(&s->lock, flags);
                }
-               return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, (int *)arg);
+               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, (int *)arg);
+                return put_user(AFMT_S16_LE|AFMT_U8, p);
                
         case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != AFMT_QUERY) {
                        stop_dac1(s);
@@ -2047,16 +2051,16 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                        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, (int *)arg);
+               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, (int *)arg);
+               return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, p);
                                                
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val & PCM_ENABLE_OUTPUT) {
                        if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
@@ -2082,7 +2086,7 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                 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 *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_NONBLOCK:
                 file->f_flags |= O_NONBLOCK;
@@ -2097,7 +2101,7 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                spin_unlock_irqrestore(&s->lock, flags);
                if (count < 0)
                        count = 0;
-               return put_user(count, (int *)arg);
+               return put_user(count, p);
 
         case SNDCTL_DSP_GETOPTR:
                if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
@@ -2113,17 +2117,17 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                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 *)arg, &cinfo, sizeof(cinfo)))
+               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, (int *)arg);
+                return put_user(s->dma_dac1.fragsize, p);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                s->dma_dac1.ossfragshift = val & 0xffff;
                s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff;
@@ -2138,7 +2142,7 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
         case SNDCTL_DSP_SUBDIVIDE:
                if (s->dma_dac1.subdivision)
                        return -EINVAL;
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
@@ -2146,13 +2150,13 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return 0;
 
         case SOUND_PCM_READ_RATE:
-               return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], (int *)arg);
+               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, (int *)arg);
+               return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
 
         case SOUND_PCM_READ_BITS:
-               return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, (int *)arg);
+               return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, p);
 
         case SOUND_PCM_WRITE_FILTER:
         case SNDCTL_DSP_SETSYNCRO:
@@ -2251,7 +2255,7 @@ static /*const*/ struct file_operations es1370_dac_fops = {
 
 /* --------------------------------------------------------------------- */
 
-static ssize_t es1370_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+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);
@@ -2314,7 +2318,7 @@ static ssize_t es1370_midi_read(struct file *file, char *buffer, size_t count, l
        return ret;
 }
 
-static ssize_t es1370_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+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);
index 3cc4fb2..7d1a108 100644 (file)
@@ -1170,7 +1170,7 @@ static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned lon
                return 0;
 
        case SOUND_MIXER_WRITE_PCM:   /* use SRC for PCM volume */
-               if (get_user(val, (int *)arg))
+               if (get_user(val, (int __user *)arg))
                        return -EFAULT;
                right = ((val >> 8)  & 0xff);
                left = (val  & 0xff);
@@ -1186,7 +1186,7 @@ static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned lon
                return 0;
        
        case SOUND_MIXER_READ_PCM:
-               return put_user(s->spdif_volume, (int *)arg);
+               return put_user(s->spdif_volume, (int __user *)arg);
        }
        return codec->mixer_ioctl(codec, cmd, arg);
 }
@@ -1324,7 +1324,7 @@ static int drain_dac2(struct es1371_state *s, int nonblock)
 
 /* --------------------------------------------------------------------- */
 
-static ssize_t es1371_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
        struct es1371_state *s = (struct es1371_state *)file->private_data;
        DECLARE_WAITQUEUE(wait, current);
@@ -1403,7 +1403,7 @@ out2:
        return ret;
 }
 
-static ssize_t es1371_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
        struct es1371_state *s = (struct es1371_state *)file->private_data;
        DECLARE_WAITQUEUE(wait, current);
@@ -1578,13 +1578,15 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
         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, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_SYNC:
                if (file->f_mode & FMODE_WRITE)
@@ -1595,7 +1597,7 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
        case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+               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) {
@@ -1611,7 +1613,7 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_READ) {
@@ -1625,10 +1627,10 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                                set_dac2_rate(s, val);
                        }
                }
-               return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, (int *)arg);
+               return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p);
 
         case SNDCTL_DSP_STEREO:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        stop_adc(s);
@@ -1655,7 +1657,7 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 0) {
                        if (file->f_mode & FMODE_READ) {
@@ -1681,13 +1683,13 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                                spin_unlock_irqrestore(&s->lock, flags);
                        }
                }
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, (int *)arg);
+               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, (int *)arg);
+                return put_user(AFMT_S16_LE|AFMT_U8, p);
                
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != AFMT_QUERY) {
                        if (file->f_mode & FMODE_READ) {
@@ -1714,7 +1716,7 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        }
                }
                return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 
-                               AFMT_S16_LE : AFMT_U8, (int *)arg);
+                               AFMT_S16_LE : AFMT_U8, p);
                
        case SNDCTL_DSP_POST:
                 return 0;
@@ -1725,10 +1727,10 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        val |= PCM_ENABLE_INPUT;
                if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) 
                        val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
                
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
@@ -1769,7 +1771,7 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                 abinfo.fragstotal = s->dma_dac2.numfrag;
                 abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift;      
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETISPACE:
                if (!(file->f_mode & FMODE_READ))
@@ -1786,7 +1788,7 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                 abinfo.fragstotal = s->dma_adc.numfrag;
                 abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
                
         case SNDCTL_DSP_NONBLOCK:
                 file->f_flags |= O_NONBLOCK;
@@ -1803,7 +1805,7 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                spin_unlock_irqrestore(&s->lock, flags);
                if (count < 0)
                        count = 0;
-               return put_user(count, (int *)arg);
+               return put_user(count, p);
 
         case SNDCTL_DSP_GETIPTR:
                if (!(file->f_mode & FMODE_READ))
@@ -1821,7 +1823,7 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                if (s->dma_adc.mapped)
                        s->dma_adc.count &= s->dma_adc.fragsize-1;
                spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -1841,7 +1843,7 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                if (s->dma_dac2.mapped)
                        s->dma_dac2.count &= s->dma_dac2.fragsize-1;
                spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -1849,14 +1851,14 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                if (file->f_mode & FMODE_WRITE) {
                        if ((val = prog_dmabuf_dac2(s)))
                                return val;
-                       return put_user(s->dma_dac2.fragsize, (int *)arg);
+                       return put_user(s->dma_dac2.fragsize, p);
                }
                if ((val = prog_dmabuf_adc(s)))
                        return val;
-               return put_user(s->dma_adc.fragsize, (int *)arg);
+               return put_user(s->dma_adc.fragsize, p);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        s->dma_adc.ossfragshift = val & 0xffff;
@@ -1884,7 +1886,7 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                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, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
@@ -1895,13 +1897,13 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                return 0;
 
         case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, (int *)arg);
+               return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p);
 
         case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, (int *)arg);
+               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, (int *)arg);
+               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:
@@ -2017,7 +2019,7 @@ static /*const*/ struct file_operations es1371_audio_fops = {
 
 /* --------------------------------------------------------------------- */
 
-static ssize_t es1371_write_dac(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1371_write_dac(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
        struct es1371_state *s = (struct es1371_state *)file->private_data;
        DECLARE_WAITQUEUE(wait, current);
@@ -2149,11 +2151,12 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
         count_info cinfo;
        int count;
        int val, ret;
+       int __user *p = (int __user *)arg;
 
        VALIDATE_STATE(s);
        switch (cmd) {
        case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_SYNC:
                return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/);
@@ -2162,7 +2165,7 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return -EINVAL;
 
        case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+               return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
                
         case SNDCTL_DSP_RESET:
                stop_dac1(s);
@@ -2171,17 +2174,17 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val >= 0) {
                        stop_dac1(s);
                        s->dma_dac1.ready = 0;
                        set_dac1_rate(s, val);
                }
-               return put_user(s->dac1rate, (int *)arg);
+               return put_user(s->dac1rate, p);
 
         case SNDCTL_DSP_STEREO:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                stop_dac1(s);
                s->dma_dac1.ready = 0;
@@ -2195,7 +2198,7 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 0) {
                        stop_dac1(s);
@@ -2208,13 +2211,13 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                        outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
                        spin_unlock_irqrestore(&s->lock, flags);
                }
-               return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, (int *)arg);
+               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, (int *)arg);
+                return put_user(AFMT_S16_LE|AFMT_U8, p);
                
         case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != AFMT_QUERY) {
                        stop_dac1(s);
@@ -2227,16 +2230,16 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                        outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
                        spin_unlock_irqrestore(&s->lock, flags);
                }
-               return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, (int *)arg);
+               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, (int *)arg);
+               return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, p);
                                                
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val & PCM_ENABLE_OUTPUT) {
                        if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
@@ -2262,7 +2265,7 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                 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 *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_NONBLOCK:
                 file->f_flags |= O_NONBLOCK;
@@ -2277,7 +2280,7 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                spin_unlock_irqrestore(&s->lock, flags);
                if (count < 0)
                        count = 0;
-               return put_user(count, (int *)arg);
+               return put_user(count, p);
 
         case SNDCTL_DSP_GETOPTR:
                if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
@@ -2293,17 +2296,17 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                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 *)arg, &cinfo, sizeof(cinfo)))
+               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, (int *)arg);
+                return put_user(s->dma_dac1.fragsize, p);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                s->dma_dac1.ossfragshift = val & 0xffff;
                s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff;
@@ -2318,7 +2321,7 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
         case SNDCTL_DSP_SUBDIVIDE:
                if (s->dma_dac1.subdivision)
                        return -EINVAL;
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
@@ -2326,13 +2329,13 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                return 0;
 
         case SOUND_PCM_READ_RATE:
-               return put_user(s->dac1rate, (int *)arg);
+               return put_user(s->dac1rate, p);
 
         case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, (int *)arg);
+               return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
 
         case SOUND_PCM_READ_BITS:
-               return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, (int *)arg);
+               return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, p);
 
         case SOUND_PCM_WRITE_FILTER:
         case SNDCTL_DSP_SETSYNCRO:
@@ -2430,7 +2433,7 @@ static /*const*/ struct file_operations es1371_dac_fops = {
 
 /* --------------------------------------------------------------------- */
 
-static ssize_t es1371_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1371_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
        struct es1371_state *s = (struct es1371_state *)file->private_data;
        DECLARE_WAITQUEUE(wait, current);
@@ -2493,7 +2496,7 @@ static ssize_t es1371_midi_read(struct file *file, char *buffer, size_t count, l
        return ret;
 }
 
-static ssize_t es1371_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1371_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
        struct es1371_state *s = (struct es1371_state *)file->private_data;
        DECLARE_WAITQUEUE(wait, current);
index cbd78ed..b5096b5 100644 (file)
@@ -694,37 +694,38 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
        };
        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, (int *)arg))
+               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, (int *)arg);
+               return put_user(val, p);
        }
        if (cmd == SOUND_MIXER_PRIVATE2) {
                /* enable/disable/query spatializer */
-               if (get_user(val, (int *)arg))
+               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), (int *)arg);
+               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 *)arg, &info, sizeof(info)))
+               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
@@ -732,41 +733,41 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
                _old_mixer_info info;
                strncpy(info.id, "Solo1", sizeof(info.id));
                strncpy(info.name, "ESS Solo1", sizeof(info.name));
-               if (copy_to_user((void *)arg, &info, sizeof(info)))
+               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
        if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, (int *)arg);
+               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], (int *)arg);
+                       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, (int *)arg);
+                                       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, (int *)arg);
+                       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, (int *)arg);
+                                       SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV, p);
                        
                 case SOUND_MIXER_CAPS:
-                       return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg);
+                       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], (int *)arg);
+                       return put_user(s->mix.vol[vidx-1], p);
                }
        }
         if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) 
@@ -788,7 +789,7 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
                               0xb4, read_ctrl(s, 0xb4));
                }
 #endif
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                 i = hweight32(val);
                 if (i == 0)
@@ -805,7 +806,7 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
                return 0;
 
        case SOUND_MIXER_VOLUME:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                l = val & 0xff;
                if (l > 100)
@@ -834,10 +835,10 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
 #else
                 s->mix.vol[9] = val;
 #endif
-               return put_user(s->mix.vol[9], (int *)arg);
+               return put_user(s->mix.vol[9], p);
 
        case SOUND_MIXER_SPEAKER:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                l = val & 0xff;
                if (l > 100)
@@ -852,10 +853,10 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
 #else
                 s->mix.vol[7] = val;
 #endif
-               return put_user(s->mix.vol[7], (int *)arg);
+               return put_user(s->mix.vol[7], p);
 
        case SOUND_MIXER_RECLEV:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                l = (val << 1) & 0x1fe;
                if (l > 200)
@@ -877,13 +878,13 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
 #else
                 s->mix.vol[8] = val;
 #endif
-               return put_user(s->mix.vol[8], (int *)arg);
+               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, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                l = (val << 1) & 0x1fe;
                if (l > 200)
@@ -905,7 +906,7 @@ static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long ar
 #else
                 s->mix.vol[vidx-1] = val;
 #endif
-               return put_user(s->mix.vol[vidx-1], (int *)arg);
+               return put_user(s->mix.vol[vidx-1], p);
        }
 }
 
@@ -999,7 +1000,7 @@ static int drain_dac(struct solo1_state *s, int nonblock)
 
 /* --------------------------------------------------------------------- */
 
-static ssize_t solo1_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+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);
@@ -1095,7 +1096,7 @@ static ssize_t solo1_read(struct file *file, char *buffer, size_t count, loff_t
        return ret;
 }
 
-static ssize_t solo1_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+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);
@@ -1263,13 +1264,15 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        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, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_SYNC:
                if (file->f_mode & FMODE_WRITE)
@@ -1280,7 +1283,7 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return 0;
 
        case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+               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) {
@@ -1297,7 +1300,7 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val >= 0) {
                        stop_adc(s);
@@ -1322,10 +1325,10 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                        s->clkdiv = div1;
                        prog_codec(s);
                }
-               return put_user(s->rate, (int *)arg);
+               return put_user(s->rate, p);
                
         case SNDCTL_DSP_STEREO:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                stop_adc(s);
                stop_dac(s);
@@ -1336,7 +1339,7 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 0) {
                        stop_adc(s);
@@ -1346,13 +1349,13 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                        s->channels = (val >= 2) ? 2 : 1;
                        prog_codec(s);
                }
-               return put_user(s->channels, (int *)arg);
+               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, (int *)arg);
+                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, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != AFMT_QUERY) {
                        stop_adc(s);
@@ -1365,7 +1368,7 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                        s->fmt = val;
                        prog_codec(s);
                }
-               return put_user(s->fmt, (int *)arg);
+               return put_user(s->fmt, p);
 
        case SNDCTL_DSP_POST:
                 return 0;
@@ -1376,10 +1379,10 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                        val |= PCM_ENABLE_INPUT;
                if (file->f_mode & s->ena & FMODE_WRITE)
                        val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
 
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
@@ -1422,7 +1425,7 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                 abinfo.fragstotal = s->dma_dac.numfrag;
                 abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETISPACE:
                if (!(file->f_mode & FMODE_READ))
@@ -1436,7 +1439,7 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                 abinfo.fragstotal = s->dma_adc.numfrag;
                 abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_NONBLOCK:
                 file->f_flags |= O_NONBLOCK;
@@ -1453,7 +1456,7 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                spin_unlock_irqrestore(&s->lock, flags);
                if (count < 0)
                        count = 0;
-               return put_user(count, (int *)arg);
+               return put_user(count, p);
 
         case SNDCTL_DSP_GETIPTR:
                if (!(file->f_mode & FMODE_READ))
@@ -1468,7 +1471,7 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                if (s->dma_adc.mapped)
                        s->dma_adc.count &= s->dma_adc.fragsize-1;
                spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -1494,7 +1497,7 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                       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((void *)arg, &cinfo, sizeof(cinfo)))
+               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -1502,14 +1505,14 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                if (file->f_mode & FMODE_WRITE) {
                        if ((val = prog_dmabuf_dac(s)))
                                return val;
-                       return put_user(s->dma_dac.fragsize, (int *)arg);
+                       return put_user(s->dma_dac.fragsize, p);
                }
                if ((val = prog_dmabuf_adc(s)))
                        return val;
-               return put_user(s->dma_adc.fragsize, (int *)arg);
+               return put_user(s->dma_adc.fragsize, p);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        s->dma_adc.ossfragshift = val & 0xffff;
@@ -1537,7 +1540,7 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                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))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
@@ -1548,13 +1551,13 @@ static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return 0;
 
         case SOUND_PCM_READ_RATE:
-               return put_user(s->rate, (int *)arg);
+               return put_user(s->rate, p);
 
         case SOUND_PCM_READ_CHANNELS:
-               return put_user(s->channels, (int *)arg);
+               return put_user(s->channels, p);
 
         case SOUND_PCM_READ_BITS:
-               return put_user((s->fmt & (AFMT_S8|AFMT_U8)) ? 8 : 16, (int *)arg);
+               return put_user((s->fmt & (AFMT_S8|AFMT_U8)) ? 8 : 16, p);
 
         case SOUND_PCM_WRITE_FILTER:
         case SNDCTL_DSP_SETSYNCRO:
@@ -1727,7 +1730,7 @@ static void solo1_midi_timer(unsigned long data)
 
 /* --------------------------------------------------------------------- */
 
-static ssize_t solo1_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+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);
@@ -1790,7 +1793,7 @@ static ssize_t solo1_midi_read(struct file *file, char *buffer, size_t count, lo
        return ret;
 }
 
-static ssize_t solo1_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+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);
@@ -2032,7 +2035,7 @@ static int solo1_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int
                return 0;
 
        case FM_IOCTL_PLAY_NOTE:
-               if (copy_from_user(&n, (void *)arg, sizeof(n)))
+               if (copy_from_user(&n, (void __user *)arg, sizeof(n)))
                        return -EFAULT;
                if (n.voice >= 18)
                        return -EINVAL;
@@ -2050,7 +2053,7 @@ static int solo1_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int
                return 0;
 
        case FM_IOCTL_SET_VOICE:
-               if (copy_from_user(&v, (void *)arg, sizeof(v)))
+               if (copy_from_user(&v, (void __user *)arg, sizeof(v)))
                        return -EFAULT;
                if (v.voice >= 18)
                        return -EINVAL;
@@ -2080,7 +2083,7 @@ static int solo1_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int
                return 0;
                
        case FM_IOCTL_SET_PARAMS:
-               if (copy_from_user(&p, (void *)arg, sizeof(p)))
+               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);
index 06a31b7..c7e23fc 100644 (file)
@@ -849,6 +849,8 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
        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;
        
@@ -865,24 +867,24 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
        switch (cmd) {
 
        case OSS_GETVERSION:
-               return put_user (SOUND_VERSION, (int *) arg);
+               return put_user (SOUND_VERSION, p);
 
        case SNDCTL_DSP_GETCAPS:
                DPRINTK ("%s: GETCAPS\n", __FUNCTION__);
 
                ival = FORTE_CAPS; /* DUPLEX */
-               return put_user (ival, (int *) arg);
+               return put_user (ival, p);
 
        case SNDCTL_DSP_GETFMTS:
                DPRINTK ("%s: GETFMTS\n", __FUNCTION__);
 
                ival = FORTE_FMTS; /* U8, 16LE */
-               return put_user (ival, (int *) arg);
+               return put_user (ival, p);
 
        case SNDCTL_DSP_SETFMT: /* U8, 16LE */
                DPRINTK ("%s: SETFMT\n", __FUNCTION__);
 
-               if (get_user (ival, (int *) arg))
+               if (get_user (ival, p))
                        return -EFAULT;
 
                spin_lock_irq (&chip->lock);
@@ -899,12 +901,12 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
 
                spin_unlock_irq (&chip->lock);
        
-               return put_user (rval, (int *) arg);
+               return put_user (rval, p);
 
        case SNDCTL_DSP_STEREO: /* 0 - mono, 1 - stereo */
                DPRINTK ("%s: STEREO\n", __FUNCTION__);
 
-               if (get_user (ival, (int *) arg))
+               if (get_user (ival, p))
                        return -EFAULT;
 
                spin_lock_irq (&chip->lock);
@@ -921,12 +923,12 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
 
                spin_unlock_irq (&chip->lock);
 
-                return put_user (rval, (int *) arg);
+                return put_user (rval, p);
 
        case SNDCTL_DSP_CHANNELS: /* 1 - mono, 2 - stereo */
                DPRINTK ("%s: CHANNELS\n", __FUNCTION__);
 
-               if (get_user (ival, (int *) arg))
+               if (get_user (ival, p))
                        return -EFAULT;
 
                spin_lock_irq (&chip->lock);
@@ -943,12 +945,12 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
 
                spin_unlock_irq (&chip->lock);
 
-                return put_user (rval, (int *) arg);
+                return put_user (rval, p);
 
        case SNDCTL_DSP_SPEED:
                DPRINTK ("%s: SPEED\n", __FUNCTION__);
 
-               if (get_user (ival, (int *) arg))
+               if (get_user (ival, p))
                         return -EFAULT;
 
                spin_lock_irq (&chip->lock);
@@ -965,7 +967,7 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
 
                spin_unlock_irq (&chip->lock);
 
-                return put_user(rval, (int*) arg);
+                return put_user(rval, p);
 
        case SNDCTL_DSP_GETBLKSIZE:
                DPRINTK ("%s: GETBLKSIZE\n", __FUNCTION__);
@@ -980,7 +982,7 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
 
                spin_unlock_irq (&chip->lock);
 
-                return put_user (ival, (int *) arg);
+                return put_user (ival, p);
 
        case SNDCTL_DSP_RESET:
                DPRINTK ("%s: RESET\n", __FUNCTION__);
@@ -1022,7 +1024,7 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
        case SNDCTL_DSP_SETFRAGMENT:
                DPRINTK ("%s: SETFRAGMENT\n", __FUNCTION__);
 
-               if (get_user (ival, (int *) arg))
+               if (get_user (ival, p))
                        return -EFAULT;
 
                spin_lock_irq (&chip->lock);
@@ -1041,7 +1043,7 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
 
                spin_unlock_irq (&chip->lock);
 
-               return put_user (ival, (int *) arg);
+               return put_user (ival, p);
                 
         case SNDCTL_DSP_GETISPACE:
                DPRINTK ("%s: GETISPACE\n", __FUNCTION__);
@@ -1065,7 +1067,7 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
 
                spin_unlock_irq (&chip->lock);
 
-               return copy_to_user ((void *) arg, &abi, sizeof (abi)) ? -EFAULT : 0;
+               return copy_to_user (argp, &abi, sizeof (abi)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETIPTR:
                DPRINTK ("%s: GETIPTR\n", __FUNCTION__);
@@ -1086,7 +1088,7 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
 
                spin_unlock_irq (&chip->lock);
 
-               return copy_to_user ((void *) arg, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
+               return copy_to_user (argp, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETOSPACE:
                if (!wr)
@@ -1114,7 +1116,7 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
 
                spin_unlock_irq (&chip->lock);
                
-               return copy_to_user ((void *) arg, &abi, sizeof (abi)) ? -EFAULT : 0;
+               return copy_to_user (argp, &abi, sizeof (abi)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETOPTR:
                if (!wr)
@@ -1133,7 +1135,7 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
 
                spin_unlock_irq (&chip->lock);
 
-               return copy_to_user ((void *) arg, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
+               return copy_to_user (argp, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETODELAY:
                if (!wr)
@@ -1157,7 +1159,7 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
 
                spin_unlock_irq (&chip->lock);
 
-               return put_user (ival, (int *) arg);
+               return put_user (ival, p);
 
        case SNDCTL_DSP_SETDUPLEX:
                DPRINTK ("%s: SETDUPLEX\n", __FUNCTION__);
@@ -1167,11 +1169,11 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
        case SNDCTL_DSP_GETTRIGGER:
                DPRINTK ("%s: GETTRIGGER\n", __FUNCTION__);
                
-               return put_user (chip->trigger, (int *) arg);
+               return put_user (chip->trigger, p);
                
        case SNDCTL_DSP_SETTRIGGER:
 
-               if (get_user (ival, (int *) arg))
+               if (get_user (ival, p))
                        return -EFAULT;
 
                DPRINTK ("%s: SETTRIGGER %d\n", __FUNCTION__, ival);
@@ -1207,15 +1209,15 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
                
        case SOUND_PCM_READ_RATE:
                DPRINTK ("%s: PCM_READ_RATE\n", __FUNCTION__);          
-               return put_user (chip->play.rate, (int *) arg);
+               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, (int *) arg);
+               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, (int *) arg);
+               return put_user (chip->play.format, p);
 
        case SNDCTL_DSP_NONBLOCK:
                DPRINTK ("%s: DSP_NONBLOCK\n", __FUNCTION__);           
@@ -1223,7 +1225,7 @@ forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
                return 0;
 
        default:
-               DPRINTK ("Unsupported ioctl: %x (%p)\n", cmd, (void *) arg);
+               DPRINTK ("Unsupported ioctl: %x (%p)\n", cmd, argp);
                break;
        }
 
@@ -1428,7 +1430,7 @@ forte_dsp_mmap (struct file *file, struct vm_area_struct *vma)
  */
 
 static ssize_t 
-forte_dsp_write (struct file *file, const char *buffer, size_t bytes, 
+forte_dsp_write (struct file *file, const char __user *buffer, size_t bytes, 
                 loff_t *ppos)
 {
        struct forte_chip *chip;
@@ -1536,7 +1538,7 @@ forte_dsp_write (struct file *file, const char *buffer, size_t bytes,
  */
 
 static ssize_t 
-forte_dsp_read (struct file *file, char *buffer, size_t bytes, 
+forte_dsp_read (struct file *file, char __user *buffer, size_t bytes, 
                loff_t *ppos)
 {
        struct forte_chip *chip;
index c817b39..e4f8542 100644 (file)
@@ -1393,7 +1393,7 @@ static irqreturn_t i810_interrupt(int irq, void *dev_id, struct pt_regs *regs)
    waiting to be copied to the user's buffer.  It is filled by the dma
    machine and drained by this loop. */
 
-static ssize_t i810_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t i810_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
        struct i810_state *state = (struct i810_state *)file->private_data;
        struct i810_card *card=state ? state->card : 0;
@@ -1533,7 +1533,7 @@ static ssize_t i810_read(struct file *file, char *buffer, size_t count, loff_t *
 
 /* 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 i810_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t i810_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
        struct i810_state *state = (struct i810_state *)file->private_data;
        struct i810_card *card=state ? state->card : 0;
@@ -1755,9 +1755,11 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        unsigned int i_glob_cnt;
        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("i810_audio: i810_ioctl, arg=0x%x, cmd=", arg ? *(int *)arg : 0);
+       printk("i810_audio: i810_ioctl, arg=0x%x, cmd=", arg ? *p : 0);
 #endif
 
        switch (cmd) 
@@ -1766,7 +1768,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 #ifdef DEBUG
                printk("OSS_GETVERSION\n");
 #endif
-               return put_user(SOUND_VERSION, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_RESET:
 #ifdef DEBUG
@@ -1813,7 +1815,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 #ifdef DEBUG
                printk("SNDCTL_DSP_SPEED\n");
 #endif
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_WRITE) {
@@ -1851,7 +1853,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                                spin_unlock_irqrestore(&state->card->lock, flags);
                        }
                }
-               return put_user(dmabuf->rate, (int *)arg);
+               return put_user(dmabuf->rate, p);
 
        case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
 #ifdef DEBUG
@@ -1863,7 +1865,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                if (dmabuf->enable & ADC_RUNNING) {
                        stop_adc(state);
                }
-               return put_user(1, (int *)arg);
+               return put_user(1, p);
 
        case SNDCTL_DSP_GETBLKSIZE:
                if (file->f_mode & FMODE_WRITE) {
@@ -1877,25 +1879,25 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 #ifdef DEBUG
                printk("SNDCTL_DSP_GETBLKSIZE %d\n", dmabuf->userfragsize);
 #endif
-               return put_user(dmabuf->userfragsize, (int *)arg);
+               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, (int *)arg);
+               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, (int *)arg);
+               return put_user(AFMT_S16_LE, p);
 
        case SNDCTL_DSP_CHANNELS:
 #ifdef DEBUG
                printk("SNDCTL_DSP_CHANNELS\n");
 #endif
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                if (val > 0) {
@@ -1906,13 +1908,13 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                                stop_adc(state);
                        }
                } else {
-                       return put_user(state->card->channels, (int *)arg);
+                       return put_user(state->card->channels, p);
                }
 
                /* ICH and ICH0 only support 2 channels */
                if ( state->card->pci_id == PCI_DEVICE_ID_INTEL_82801AA_5
                     || state->card->pci_id == PCI_DEVICE_ID_INTEL_82801AB_5) 
-                       return put_user(2, (int *)arg);
+                       return put_user(2, p);
        
                /* Multi-channel support was added with ICH2. Bits in */
                /* Global Status and Global Control register are now  */
@@ -1957,7 +1959,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                                break;
                }
 
-               return put_user(val, (int *)arg);
+               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 */
@@ -1976,7 +1978,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        case SNDCTL_DSP_SUBDIVIDE:
                if (dmabuf->subdivision)
                        return -EINVAL;
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
@@ -1988,7 +1990,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return 0;
 
        case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                dmabuf->ossfragsize = 1<<(val & 0xffff);
@@ -2061,7 +2063,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                printk("SNDCTL_DSP_GETOSPACE %d, %d, %d, %d\n", abinfo.bytes,
                        abinfo.fragsize, abinfo.fragments, abinfo.fragstotal);
 #endif
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETOPTR:
                if (!(file->f_mode & FMODE_WRITE))
@@ -2083,7 +2085,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes,
                        cinfo.blocks, cinfo.ptr, dmabuf->count);
 #endif
-               return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETISPACE:
                if (!(file->f_mode & FMODE_READ))
@@ -2100,7 +2102,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                printk("SNDCTL_DSP_GETISPACE %d, %d, %d, %d\n", abinfo.bytes,
                        abinfo.fragsize, abinfo.fragments, abinfo.fragstotal);
 #endif
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETIPTR:
                if (!(file->f_mode & FMODE_READ))
@@ -2122,7 +2124,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes,
                        cinfo.blocks, cinfo.ptr, dmabuf->count);
 #endif
-               return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_NONBLOCK:
 #ifdef DEBUG
@@ -2136,17 +2138,17 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                printk("SNDCTL_DSP_GETCAPS\n");
 #endif
            return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP|DSP_CAP_BIND,
-                           (int *)arg);
+                           p);
 
        case SNDCTL_DSP_GETTRIGGER:
                val = 0;
 #ifdef DEBUG
                printk("SNDCTL_DSP_GETTRIGGER 0x%x\n", dmabuf->trigger);
 #endif
-               return put_user(dmabuf->trigger, (int *)arg);
+               return put_user(dmabuf->trigger, p);
 
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
 #if defined(DEBUG) || defined(DEBUG_MMAP)
                printk("SNDCTL_DSP_SETTRIGGER 0x%x\n", val);
@@ -2223,31 +2225,31 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 #ifdef DEBUG
                printk("SNDCTL_DSP_GETODELAY %d\n", dmabuf->count);
 #endif
-               return put_user(val, (int *)arg);
+               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, (int *)arg);
+               return put_user(dmabuf->rate, p);
 
        case SOUND_PCM_READ_CHANNELS:
 #ifdef DEBUG
                printk("SOUND_PCM_READ_CHANNELS\n");
 #endif
-               return put_user(2, (int *)arg);
+               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, (int *)arg);
+               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, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                /* Check to make sure the codec supports S/PDIF transmitter */
@@ -2270,13 +2272,13 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                else 
                        printk(KERN_WARNING "i810_audio: S/PDIF transmitter not avalible.\n");
 #endif
-               return put_user(val, (int *)arg);
+               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, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                /* Check to make sure the codec supports S/PDIF transmitter */
@@ -2289,14 +2291,14 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                } else {
                        val = i810_ac97_get(codec, AC97_SPDIF_CONTROL);
                }
-               //return put_user((val & 0xcfff), (int *)arg);
-               return put_user(val, (int *)arg);
+               //return put_user((val & 0xcfff), p);
+               return put_user(val, p);
                        
        case SNDCTL_DSP_GETCHANNELMASK:
 #ifdef DEBUG
                printk("SNDCTL_DSP_GETCHANNELMASK\n");
 #endif
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                
                /* Based on AC'97 DAC support, not ICH hardware */
@@ -2309,13 +2311,13 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                if ( state->card->ac97_features & 0x0140 )
                        val |= DSP_BIND_CENTER_LFE;
 
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
 
        case SNDCTL_DSP_BIND_CHANNEL:
 #ifdef DEBUG
                printk("SNDCTL_DSP_BIND_CHANNEL\n");
 #endif
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if ( val == DSP_BIND_QUERY ) {
                        val = DSP_BIND_FRONT; /* Always report this as being enabled */
@@ -2383,7 +2385,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                                        val &= ~DSP_BIND_CENTER_LFE;
                        }
                }
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
                
        case SNDCTL_DSP_MAPINBUF:
        case SNDCTL_DSP_MAPOUTBUF:
index c09ea88..2c07225 100644 (file)
@@ -218,7 +218,7 @@ static int __init kahlua_init_module(void)
 
 static void __devexit kahlua_cleanup_module(void)
 {
-       return pci_unregister_driver(&kahlua_driver);
+       pci_unregister_driver(&kahlua_driver);
 }
 
 
index 2b17c06..4a670f4 100644 (file)
@@ -2025,7 +2025,9 @@ mixer_push_state(struct ess_card *card)
 static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long arg)
 {
        int i, val=0;
-       unsigned long flags;
+       unsigned long flags;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
 
        VALIDATE_CARD(card);
         if (cmd == SOUND_MIXER_INFO) {
@@ -2034,7 +2036,7 @@ static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long ar
                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((void *)arg, &info, sizeof(info)))
+               if (copy_to_user(argp, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
@@ -2043,12 +2045,12 @@ static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long ar
                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((void *)arg, &info, sizeof(info)))
+               if (copy_to_user(argp, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
        if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
                 return -EINVAL;
@@ -2098,7 +2100,7 @@ static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long ar
 
                        break;
                }
-               return put_user(val,(int *)arg);
+               return put_user(val, p);
        }
        
         if (_IOC_DIR(cmd) != (_IOC_WRITE|_IOC_READ))
@@ -2106,7 +2108,7 @@ static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long ar
        
        card->mix.modcnt++;
 
-       if (get_user(val, (int *)arg))
+       if (get_user(val, p))
                return -EFAULT;
 
        switch (_IOC_NR(cmd)) {
@@ -2262,7 +2264,7 @@ comb_stereo(unsigned char *real_buffer,unsigned char  *tmp_buffer, int offset,
        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 *buffer, size_t count, loff_t *ppos)
+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;
@@ -2361,7 +2363,7 @@ rec_return_free:
 }
 
 static ssize_t 
-ess_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+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;
@@ -2539,6 +2541,8 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
         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);*/
        
@@ -2547,7 +2551,7 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
        switch (cmd) {
        case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_SYNC:
                if (file->f_mode & FMODE_WRITE)
@@ -2559,7 +2563,7 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                return 0;
 
        case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+               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) {
@@ -2575,7 +2579,7 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_READ) {
@@ -2589,10 +2593,10 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                                set_dac_rate(s, val);
                        }
                }
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
                
         case SNDCTL_DSP_STEREO:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                fmtd = 0;
                fmtm = ~0;
@@ -2616,7 +2620,7 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 0) {
                        fmtd = 0;
@@ -2640,13 +2644,13 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                        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, (int *)arg);
+                                          : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
                
        case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_U8|AFMT_S16_LE, (int *)arg);
+                return put_user(AFMT_U8|AFMT_S16_LE, p);
                
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != AFMT_QUERY) {
                        fmtd = 0;
@@ -2678,7 +2682,7 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                        : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 
                                AFMT_S16_LE : 
                                AFMT_U8, 
-                       (int *)arg);
+                       p);
                
        case SNDCTL_DSP_POST:
                 return 0;
@@ -2689,10 +2693,10 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                        val |= PCM_ENABLE_INPUT;
                if ((file->f_mode & FMODE_WRITE) && (s->enable & DAC_RUNNING)) 
                        val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
                
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
@@ -2724,7 +2728,7 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                 abinfo.fragstotal = s->dma_dac.numfrag;
                 abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETISPACE:
                if (!(file->f_mode & FMODE_READ))
@@ -2738,7 +2742,7 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                 abinfo.fragstotal = s->dma_adc.numfrag;
                 abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
                
         case SNDCTL_DSP_NONBLOCK:
                 file->f_flags |= O_NONBLOCK;
@@ -2753,7 +2757,7 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                ess_update_ptr(s);
                 val = s->dma_dac.count;
                spin_unlock_irqrestore(&s->lock, flags);
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
 
         case SNDCTL_DSP_GETIPTR:
                if (!(file->f_mode & FMODE_READ))
@@ -2768,7 +2772,7 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                if (s->dma_adc.mapped)
                        s->dma_adc.count &= s->dma_adc.fragsize-1;
                spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -2785,7 +2789,7 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                if (s->dma_dac.mapped)
                        s->dma_dac.count &= s->dma_dac.fragsize-1;
                spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -2793,14 +2797,14 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                if (file->f_mode & FMODE_WRITE) {
                        if ((val = prog_dmabuf(s, 0)))
                                return val;
-                       return put_user(s->dma_dac.fragsize, (int *)arg);
+                       return put_user(s->dma_dac.fragsize, p);
                }
                if ((val = prog_dmabuf(s, 1)))
                        return val;
-               return put_user(s->dma_adc.fragsize, (int *)arg);
+               return put_user(s->dma_adc.fragsize, p);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                M_printk("maestro: SETFRAGMENT: %0x\n",val);
                if (file->f_mode & FMODE_READ) {
@@ -2829,7 +2833,7 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                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))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
@@ -2840,15 +2844,15 @@ static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                return 0;
 
         case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+               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, (int *)arg);
+                                          : (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, (int *)arg);
+                                          : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, p);
 
         case SOUND_PCM_WRITE_FILTER:
         case SNDCTL_DSP_SETSYNCRO:
index 137cb11..2830f7f 100644 (file)
@@ -1324,7 +1324,7 @@ static int drain_dac(struct m3_state *s, int nonblock)
     return 0;
 }
 
-static ssize_t m3_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+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;
@@ -1405,7 +1405,7 @@ out:
     return ret;
 }
 
-static ssize_t m3_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+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;
@@ -1584,6 +1584,8 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
     count_info cinfo;
     int val, mapped, ret;
     unsigned char fmtm, fmtd;
+    void __user *argp = (void __user *)arg;
+    int __user *p = argp;
 
     VALIDATE_STATE(s);
 
@@ -1594,7 +1596,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
 
     switch (cmd) {
     case OSS_GETVERSION:
-        return put_user(SOUND_VERSION, (int *)arg);
+        return put_user(SOUND_VERSION, p);
 
     case SNDCTL_DSP_SYNC:
         if (file->f_mode & FMODE_WRITE)
@@ -1606,7 +1608,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         return 0;
 
     case SNDCTL_DSP_GETCAPS:
-        return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+        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);
@@ -1624,7 +1626,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         return 0;
 
     case SNDCTL_DSP_SPEED:
-        get_user_ret(val, (int *)arg, -EFAULT);
+        get_user_ret(val, p, -EFAULT);
         spin_lock_irqsave(&card->lock, flags);
         if (val >= 0) {
             if (file->f_mode & FMODE_READ) {
@@ -1639,10 +1641,10 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
             }
         }
         spin_unlock_irqrestore(&card->lock, flags);
-        return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+        return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
         
     case SNDCTL_DSP_STEREO:
-        get_user_ret(val, (int *)arg, -EFAULT);
+        get_user_ret(val, p, -EFAULT);
         spin_lock_irqsave(&card->lock, flags);
         fmtd = 0;
         fmtm = ~0;
@@ -1667,7 +1669,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         return 0;
 
     case SNDCTL_DSP_CHANNELS:
-        get_user_ret(val, (int *)arg, -EFAULT);
+        get_user_ret(val, p, -EFAULT);
         spin_lock_irqsave(&card->lock, flags);
         if (val != 0) {
             fmtd = 0;
@@ -1692,13 +1694,13 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         }
         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, (int *)arg);
+                       : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
         
     case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-        return put_user(AFMT_U8|AFMT_S16_LE, (int *)arg);
+        return put_user(AFMT_U8|AFMT_S16_LE, p);
         
     case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-        get_user_ret(val, (int *)arg, -EFAULT);
+        get_user_ret(val, p, -EFAULT);
         spin_lock_irqsave(&card->lock, flags);
         if (val != AFMT_QUERY) {
             fmtd = 0;
@@ -1727,7 +1729,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
             : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 
                 AFMT_S16_LE : 
                 AFMT_U8, 
-            (int *)arg);
+            p);
         
     case SNDCTL_DSP_POST:
         return 0;
@@ -1738,10 +1740,10 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
             val |= PCM_ENABLE_INPUT;
         if ((file->f_mode & FMODE_WRITE) && (s->enable & DAC_RUNNING)) 
             val |= PCM_ENABLE_OUTPUT;
-        return put_user(val, (int *)arg);
+        return put_user(val, p);
         
     case SNDCTL_DSP_SETTRIGGER:
-        get_user_ret(val, (int *)arg, -EFAULT);
+        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)))
@@ -1772,7 +1774,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         abinfo.fragstotal = s->dma_dac.numfrag;
         abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
         spin_unlock_irqrestore(&card->lock, flags);
-        return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+        return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
     case SNDCTL_DSP_GETISPACE:
         if (!(file->f_mode & FMODE_READ))
@@ -1786,7 +1788,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         abinfo.fragstotal = s->dma_adc.numfrag;
         abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
         spin_unlock_irqrestore(&card->lock, flags);
-        return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+        return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
         
     case SNDCTL_DSP_NONBLOCK:
         file->f_flags |= O_NONBLOCK;
@@ -1799,7 +1801,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         m3_update_ptr(s);
         val = s->dma_dac.count;
         spin_unlock_irqrestore(&card->lock, flags);
-        return put_user(val, (int *)arg);
+        return put_user(val, p);
 
     case SNDCTL_DSP_GETIPTR:
         if (!(file->f_mode & FMODE_READ))
@@ -1812,7 +1814,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         if (s->dma_adc.mapped)
             s->dma_adc.count &= s->dma_adc.fragsize-1;
         spin_unlock_irqrestore(&card->lock, flags);
-       if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+       if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                return -EFAULT;
        return 0;
 
@@ -1827,7 +1829,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         if (s->dma_dac.mapped)
             s->dma_dac.count &= s->dma_dac.fragsize-1;
         spin_unlock_irqrestore(&card->lock, flags);
-       if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+       if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                return -EFAULT;
        return 0;
 
@@ -1835,14 +1837,14 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         if (file->f_mode & FMODE_WRITE) {
             if ((val = prog_dmabuf(s, 0)))
                 return val;
-            return put_user(s->dma_dac.fragsize, (int *)arg);
+            return put_user(s->dma_dac.fragsize, p);
         }
         if ((val = prog_dmabuf(s, 1)))
             return val;
-        return put_user(s->dma_adc.fragsize, (int *)arg);
+        return put_user(s->dma_adc.fragsize, p);
 
     case SNDCTL_DSP_SETFRAGMENT:
-        get_user_ret(val, (int *)arg, -EFAULT);
+        get_user_ret(val, p, -EFAULT);
         spin_lock_irqsave(&card->lock, flags);
         if (file->f_mode & FMODE_READ) {
             s->dma_adc.ossfragshift = val & 0xffff;
@@ -1871,7 +1873,7 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         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, (int *)arg, -EFAULT);
+                get_user_ret(val, p, -EFAULT);
         if (val != 1 && val != 2 && val != 4)
             return -EINVAL;
         if (file->f_mode & FMODE_READ)
@@ -1881,15 +1883,15 @@ static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
         return 0;
 
     case SOUND_PCM_READ_RATE:
-        return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+        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, (int *)arg);
+                       : (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, (int *)arg);
+                       : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, p);
 
     case SOUND_PCM_WRITE_FILTER:
     case SNDCTL_DSP_SETSYNCRO:
index 3fdbaf5..6ccdd09 100644 (file)
@@ -139,13 +139,10 @@ void msnd_fifo_make_empty(msnd_fifo *f)
        f->len = f->tail = f->head = 0;
 }
 
-int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len, int user)
+int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len)
 {
        int count = 0;
 
-       if (f->len == f->n)
-               return 0;
-
        while ((count < len) && (f->len != f->n)) {
 
                int nwritten;
@@ -161,11 +158,7 @@ int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len, int user)
                                nwritten = len - count;
                }
 
-               if (user) {
-                       if (copy_from_user(f->data + f->tail, buf, nwritten))
-                               return -EFAULT;
-               } else
-                       isa_memcpy_fromio(f->data + f->tail, (unsigned long) buf, nwritten);
+               isa_memcpy_fromio(f->data + f->tail, (unsigned long) buf, nwritten);
 
                count += nwritten;
                buf += nwritten;
@@ -177,13 +170,10 @@ int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len, int user)
        return count;
 }
 
-int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len, int user)
+int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len)
 {
        int count = 0;
 
-       if (f->len == 0)
-               return f->len;
-
        while ((count < len) && (f->len > 0)) {
 
                int nread;
@@ -199,11 +189,7 @@ int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len, int user)
                                nread = len - count;
                }
 
-               if (user) {
-                       if (copy_to_user(buf, f->data + f->head, nread))
-                               return -EFAULT;
-               } else
-                       isa_memcpy_toio((unsigned long) buf, f->data + f->head, nread);
+               isa_memcpy_toio((unsigned long) buf, f->data + f->head, nread);
 
                count += nread;
                buf += nread;
index 7b36192..73148d2 100644 (file)
@@ -266,8 +266,8 @@ void                                msnd_fifo_init(msnd_fifo *f);
 void                           msnd_fifo_free(msnd_fifo *f);
 int                            msnd_fifo_alloc(msnd_fifo *f, size_t n);
 void                           msnd_fifo_make_empty(msnd_fifo *f);
-int                            msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len, int user);
-int                            msnd_fifo_read(msnd_fifo *f, char *buf, size_t len, int user);
+int                            msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len);
+int                            msnd_fifo_read(msnd_fifo *f, char *buf, size_t len);
 
 int                            msnd_wait_TXDE(multisound_dev_t *dev);
 int                            msnd_wait_HC0(multisound_dev_t *dev);
index aea4a65..a130ba4 100644 (file)
@@ -212,6 +212,7 @@ static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        LPDAQD lpDAQ, lpDARQ;
         audio_buf_info abinfo;
        unsigned long flags;
+       int __user *p = (int __user *)arg;
 
        lpDAQ = dev.base + DAPQ_DATA_BUFF;
        lpDARQ = dev.base + DARQ_DATA_BUFF;
@@ -238,7 +239,7 @@ static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                 abinfo.fragstotal = dev.DAPF.n / abinfo.fragsize;
                 abinfo.fragments = abinfo.bytes / abinfo.fragsize;
                spin_unlock_irqrestore(&dev.lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETISPACE:
                if (!(file->f_mode & FMODE_READ))
@@ -249,7 +250,7 @@ static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                 abinfo.fragstotal = dev.DARF.n / abinfo.fragsize;
                 abinfo.fragments = abinfo.bytes / abinfo.fragsize;
                spin_unlock_irqrestore(&dev.lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_RESET:
                dev.nresets = 0;
@@ -262,18 +263,18 @@ static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
        case SNDCTL_DSP_GETBLKSIZE:
                tmp = dsp_get_frag_size();
-               if (put_user(tmp, (int *)arg))
+               if (put_user(tmp, p))
                         return -EFAULT;
                return 0;
 
        case SNDCTL_DSP_GETFMTS:
                val = AFMT_S16_LE | AFMT_U8;
-               if (put_user(val, (int *)arg))
+               if (put_user(val, p))
                        return -EFAULT;
                return 0;
 
        case SNDCTL_DSP_SETFMT:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                if (file->f_mode & FMODE_WRITE)
@@ -285,7 +286,7 @@ static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                                ? dev.rec_sample_size
                                : dsp_set_format(file, val);
 
-               if (put_user(data, (int *)arg))
+               if (put_user(data, p))
                        return -EFAULT;
                return 0;
 
@@ -299,12 +300,12 @@ static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
        case SNDCTL_DSP_GETCAPS:
                val = DSP_CAP_DUPLEX | DSP_CAP_BATCH;
-               if (put_user(val, (int *)arg))
+               if (put_user(val, p))
                        return -EFAULT;
                return 0;
 
        case SNDCTL_DSP_SPEED:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                if (val < 8000)
@@ -326,13 +327,13 @@ static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                if (file->f_mode & FMODE_READ)
                        dev.rec_sample_rate = data;
 
-               if (put_user(data, (int *)arg))
+               if (put_user(data, p))
                        return -EFAULT;
                return 0;
 
        case SNDCTL_DSP_CHANNELS:
        case SNDCTL_DSP_STEREO:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
 
                if (cmd == SNDCTL_DSP_CHANNELS) {
@@ -369,7 +370,7 @@ static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                if (file->f_mode & FMODE_READ)
                        dev.rec_channels = data;
 
-               if (put_user(val, (int *)arg))
+               if (put_user(val, p))
                        return -EFAULT;
                return 0;
        }
@@ -565,13 +566,13 @@ static int mixer_ioctl(unsigned int cmd, unsigned long arg)
                mixer_info info;
                set_mixer_info();
                info.modify_counter = dev.mixer_mod_count;
-               if (copy_to_user((void *)arg, &info, sizeof(info)))
+               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        } else if (cmd == SOUND_OLD_MIXER_INFO) {
                _old_mixer_info info;
                set_mixer_info();
-               if (copy_to_user((void *)arg, &info, sizeof(info)))
+               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        } else if (cmd == SOUND_MIXER_PRIVATE1) {
@@ -584,19 +585,19 @@ static int mixer_ioctl(unsigned int cmd, unsigned long arg)
                if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
                        switch (cmd & 0xff) {
                        case SOUND_MIXER_RECSRC:
-                               if (get_user(val, (int *)arg))
+                               if (get_user(val, (int __user *)arg))
                                        return -EFAULT;
                                val = set_recsrc(val);
                                break;
 
                        default:
-                               if (get_user(val, (int *)arg))
+                               if (get_user(val, (int __user *)arg))
                                        return -EFAULT;
                                val = mixer_set(cmd & 0xff, val);
                                break;
                        }
                        ++dev.mixer_mod_count;
-                       return put_user(val, (int *)arg);
+                       return put_user(val, (int __user *)arg);
                } else {
                        switch (cmd & 0xff) {
                        case SOUND_MIXER_RECSRC:
@@ -638,7 +639,7 @@ static int mixer_ioctl(unsigned int cmd, unsigned long arg)
                        }
                }
 
-               return put_user(val, (int *)arg); 
+               return put_user(val, (int __user *)arg); 
        }
 
        return -EINVAL;
@@ -650,7 +651,7 @@ static int dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
 
        if (cmd == OSS_GETVERSION) {
                int sound_version = SOUND_VERSION;
-               return put_user(sound_version, (int *)arg);
+               return put_user(sound_version, (int __user *)arg);
        }
 
        if (minor == dev.dsp_minor)
@@ -809,7 +810,7 @@ static int dev_release(struct inode *inode, struct file *file)
 
 static __inline__ int pack_DARQ_to_DARF(register int bank)
 {
-       register int size, n, timeout = 3;
+       register int size, timeout = 3;
        register WORD wTmp;
        LPDAQD DAQD;
 
@@ -830,13 +831,10 @@ static __inline__ int pack_DARQ_to_DARF(register int bank)
        /* Read data from the head (unprotected bank 1 access okay
            since this is only called inside an interrupt) */
        outb(HPBLKSEL_1, dev.io + HP_BLKS);
-       if ((n = msnd_fifo_write(
+       msnd_fifo_write(
                &dev.DARF,
                (char *)(dev.base + bank * DAR_BUFF_SIZE),
-               size, 0)) <= 0) {
-               outb(HPBLKSEL_0, dev.io + HP_BLKS);
-               return n;
-       }
+               size);
        outb(HPBLKSEL_0, dev.io + HP_BLKS);
 
        return 1;
@@ -858,21 +856,16 @@ static __inline__ int pack_DAPF_to_DAPQ(register int start)
                if (protect) {
                        /* Critical section: protect fifo in non-interrupt */
                        spin_lock_irqsave(&dev.lock, flags);
-                       if ((n = msnd_fifo_read(
+                       n = msnd_fifo_read(
                                &dev.DAPF,
                                (char *)(dev.base + bank_num * DAP_BUFF_SIZE),
-                               DAP_BUFF_SIZE, 0)) < 0) {
-                               spin_unlock_irqrestore(&dev.lock, flags);
-                               return n;
-                       }
+                               DAP_BUFF_SIZE);
                        spin_unlock_irqrestore(&dev.lock, flags);
                } else {
-                       if ((n = msnd_fifo_read(
+                       n = msnd_fifo_read(
                                &dev.DAPF,
                                (char *)(dev.base + bank_num * DAP_BUFF_SIZE),
-                               DAP_BUFF_SIZE, 0)) < 0) {
-                               return n;
-                       }
+                               DAP_BUFF_SIZE);
                }
                if (!n)
                        break;
@@ -896,33 +889,46 @@ static __inline__ int pack_DAPF_to_DAPQ(register int start)
        return nbanks;
 }
 
-static int dsp_read(char *buf, size_t len)
+static int dsp_read(char __user *buf, size_t len)
 {
        int count = len;
+       char *page = (char *)__get_free_page(PAGE_SIZE);
+
+       if (!page)
+               return -ENOMEM;
 
        while (count > 0) {
-               int n;
+               int n, k;
                unsigned long flags;
 
+               k = PAGE_SIZE;
+               if (k > count)
+                       k = count;
+
                /* Critical section: protect fifo in non-interrupt */
                spin_lock_irqsave(&dev.lock, flags);
-               if ((n = msnd_fifo_read(&dev.DARF, buf, count, 1)) < 0) {
-                       printk(KERN_WARNING LOGNAME ": FIFO read error\n");
-                       spin_unlock_irqrestore(&dev.lock, flags);
-                       return n;
-               }
+               n = msnd_fifo_read(&dev.DARF, page, k);
                spin_unlock_irqrestore(&dev.lock, flags);
+               if (copy_to_user(buf, page, n)) {
+                       free_page((unsigned long)page);
+                       return -EFAULT;
+               }
                buf += n;
                count -= n;
 
+               if (n == k && count)
+                       continue;
+
                if (!test_bit(F_READING, &dev.flags) && dev.mode & FMODE_READ) {
                        dev.last_recbank = -1;
                        if (chk_send_dsp_cmd(&dev, HDEX_RECORD_START) == 0)
                                set_bit(F_READING, &dev.flags);
                }
 
-               if (dev.rec_ndelay)
+               if (dev.rec_ndelay) {
+                       free_page((unsigned long)page);
                        return count == len ? -EAGAIN : len - count;
+               }
 
                if (count > 0) {
                        set_bit(F_READBLOCK, &dev.flags);
@@ -931,41 +937,57 @@ static int dsp_read(char *buf, size_t len)
                                get_rec_delay_jiffies(DAR_BUFF_SIZE)))
                                clear_bit(F_READING, &dev.flags);
                        clear_bit(F_READBLOCK, &dev.flags);
-                       if (signal_pending(current))
+                       if (signal_pending(current)) {
+                               free_page((unsigned long)page);
                                return -EINTR;
+                       }
                }
        }
-
+       free_page((unsigned long)page);
        return len - count;
 }
 
-static int dsp_write(const char *buf, size_t len)
+static int dsp_write(const char __user *buf, size_t len)
 {
        int count = len;
+       char *page = (char *)__get_free_page(GFP_KERNEL);
+
+       if (!page)
+               return -ENOMEM;
 
        while (count > 0) {
-               int n;
+               int n, k;
                unsigned long flags;
 
+               k = PAGE_SIZE;
+               if (k > count)
+                       k = count;
+
+               if (copy_from_user(page, buf, k)) {
+                       free_page((unsigned long)page);
+                       return -EFAULT;
+               }
+
                /* Critical section: protect fifo in non-interrupt */
                spin_lock_irqsave(&dev.lock, flags);
-               if ((n = msnd_fifo_write(&dev.DAPF, buf, count, 1)) < 0) {
-                       printk(KERN_WARNING LOGNAME ": FIFO write error\n");
-                       spin_unlock_irqrestore(&dev.lock, flags);
-                       return n;
-               }
+               n = msnd_fifo_write(&dev.DAPF, page, k);
                spin_unlock_irqrestore(&dev.lock, flags);
                buf += n;
                count -= n;
 
+               if (count && n == k)
+                       continue;
+
                if (!test_bit(F_WRITING, &dev.flags) && (dev.mode & FMODE_WRITE)) {
                        dev.last_playbank = -1;
                        if (pack_DAPF_to_DAPQ(1) > 0)
                                set_bit(F_WRITING, &dev.flags);
                }
 
-               if (dev.play_ndelay)
+               if (dev.play_ndelay) {
+                       free_page((unsigned long)page);
                        return count == len ? -EAGAIN : len - count;
+               }
 
                if (count > 0) {
                        set_bit(F_WRITEBLOCK, &dev.flags);
@@ -973,15 +995,18 @@ static int dsp_write(const char *buf, size_t len)
                                &dev.writeblock,
                                get_play_delay_jiffies(DAP_BUFF_SIZE));
                        clear_bit(F_WRITEBLOCK, &dev.flags);
-                       if (signal_pending(current))
+                       if (signal_pending(current)) {
+                               free_page((unsigned long)page);
                                return -EINTR;
+                       }
                }
        }
 
+       free_page((unsigned long)page);
        return len - count;
 }
 
-static ssize_t dev_read(struct file *file, char *buf, size_t count, loff_t *off)
+static ssize_t dev_read(struct file *file, char __user *buf, size_t count, loff_t *off)
 {
        int minor = iminor(file->f_dentry->d_inode);
        if (minor == dev.dsp_minor)
@@ -990,7 +1015,7 @@ static ssize_t dev_read(struct file *file, char *buf, size_t count, loff_t *off)
                return -EINVAL;
 }
 
-static ssize_t dev_write(struct file *file, const char *buf, size_t count, loff_t *off)
+static ssize_t dev_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
 {
        int minor = iminor(file->f_dentry->d_inode);
        if (minor == dev.dsp_minor)
index c69c135..9789c5a 100644 (file)
@@ -822,7 +822,7 @@ static void opl3_hw_control(int dev, unsigned char *event)
 {
 }
 
-static int opl3_load_patch(int dev, int format, const char *addr,
+static int opl3_load_patch(int dev, int format, const char __user *addr,
                int offs, int count, int pmgr_flag)
 {
        struct sbi_instrument ins;
@@ -833,7 +833,11 @@ static int opl3_load_patch(int dev, int format, const char *addr,
                return -EINVAL;
        }
 
-       if(copy_from_user(&((char *) &ins)[offs], &(addr)[offs], sizeof(ins) - offs))
+       /*
+        * What the fuck is going on here?  We leave junk in the beginning
+        * of ins and then check the field pretty close to that beginning?
+        */
+       if(copy_from_user(&((char *) &ins)[offs], addr + offs, sizeof(ins) - offs))
                return -EFAULT;
 
        if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR)
index 9e96693..404ba23 100644 (file)
@@ -661,13 +661,13 @@ inline int rme96xx_getispace(struct dmabuf * dma, unsigned int hwp)
 }
 
 
-inline int rme96xx_copyfromuser(struct dmabuf* dma,const char* buffer,int count,int hop)
+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* buf = (char*)buffer;
+            char __user * buf = (char __user *)buffer;
             int cnt = count/dma->outchannels;
             int i;
             for (i=0;i < dma->outchannels;i++) {
@@ -686,7 +686,7 @@ inline int rme96xx_copyfromuser(struct dmabuf* dma,const char* buffer,int count,
             int i,j;
             int cnt = count/dma->outchannels;
             for (i=0;i < dma->outchannels + dma->mono;i++) {
-                    short* sbuf = (short*)buffer + i*(!dma->mono);
+                    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++) {
@@ -710,13 +710,13 @@ inline int rme96xx_copyfromuser(struct dmabuf* dma,const char* buffer,int count,
 }
 
 /* The count argument is the number of bytes */
-inline int rme96xx_copytouser(struct dmabuf* dma,const char* buffer,int count,int hop)
+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* buf = (char*)buffer;
+            char __user * buf = (char __user *)buffer;
             int cnt = count/dma->inchannels;
             int i;
 
@@ -736,7 +736,7 @@ inline int rme96xx_copytouser(struct dmabuf* dma,const char* buffer,int count,in
             int i,j;
             int cnt = count/dma->inchannels;
             for (i=0;i < dma->inchannels;i++) {
-                 short* sbuf = (short*)buffer + 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++) {
@@ -1121,7 +1121,6 @@ module_exit(cleanup_rme96xx);
 
 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;
@@ -1129,6 +1128,8 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
         count_info cinfo;
        int count;
        int val = 0;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
 
        VALIDATE_STATE(s);
 
@@ -1136,7 +1137,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
 
        switch (cmd) {
        case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_SYNC:
 #if 0
@@ -1149,14 +1150,14 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
                return 0;
 
        case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+               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, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val >= 0) {
 /* generally it's not a problem if we change the speed 
@@ -1195,10 +1196,10 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
                        spin_unlock_irqrestore(&s->lock, flags);
                }
                DBG(printk("speed set to %d\n",val));
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
                
         case SNDCTL_DSP_STEREO: /* this plays a mono file on two channels */
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                
                if (!val) {
@@ -1216,7 +1217,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
                return 0;
         case SNDCTL_DSP_CHANNELS:
                /* remember to check for resonable offset/channel pairs here */
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
 
                if (file->f_mode & FMODE_WRITE) {                       
@@ -1236,14 +1237,14 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
 
                dma->mono=0;
 
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
                
        case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(RME96xx_FMT, (int *)arg);
+                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, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != AFMT_QUERY) {
                        if (val & RME96xx_FMT)
@@ -1257,7 +1258,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
                                break;
                        }
                }
-               return put_user(dma->format, (int *)arg);
+               return put_user(dma->format, p);
                
        case SNDCTL_DSP_POST:
                 return 0;
@@ -1270,10 +1271,10 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
                if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) 
                        val |= PCM_ENABLE_OUTPUT;
 #endif
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
                
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
 #if 0
                if (file->f_mode & FMODE_READ) {
@@ -1309,7 +1310,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
                 abinfo.fragstotal = 2;
                 abinfo.fragments = (count > s->fragsize); 
 
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETISPACE:
                if (!(file->f_mode & FMODE_READ))
@@ -1323,7 +1324,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
                 abinfo.bytes = (count*dma->inchannels)>>dma->formatshift;
                 abinfo.fragstotal = 2;
                 abinfo.fragments = count > s->fragsize; 
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
                
         case SNDCTL_DSP_NONBLOCK:
                 file->f_flags |= O_NONBLOCK;
@@ -1339,7 +1340,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
                if (count < 0)
                        count += s->fragsize<<1;
 
-               return put_user(count, (int *)arg);
+               return put_user(count, p);
 
 
 /* check out how to use mmaped mode (can only be blocked !!!) */
@@ -1359,7 +1360,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
                        dma->readptr &= s->fragsize<<1;
                spin_unlock_irqrestore(&s->lock,flags);
 
-                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+                if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -1378,14 +1379,14 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
                if (dma->mmapped)
                        dma->writeptr &= s->fragsize<<1;
                spin_unlock_irqrestore(&s->lock,flags);
-                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+                if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
         case SNDCTL_DSP_GETBLKSIZE:
-            return put_user(s->fragsize, (int *)arg);
+            return put_user(s->fragsize, p);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                val&=0xffff;
                val -= 7;
@@ -1399,7 +1400,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
                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, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
@@ -1413,10 +1414,10 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
         case SOUND_PCM_READ_RATE:
                /* HP20020201 */
                s->rate = rme96xx_get_sample_rate_status(s);
-               return put_user(s->rate, (int *)arg);
+               return put_user(s->rate, p);
 
         case SOUND_PCM_READ_CHANNELS:
-               return put_user(dma->outchannels, (int *)arg);
+               return put_user(dma->outchannels, p);
 
         case SOUND_PCM_READ_BITS:
                switch (dma->format) {
@@ -1427,7 +1428,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd,
                                val = 16;
                                break;
                }
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
 
         case SOUND_PCM_WRITE_FILTER:
         case SNDCTL_DSP_SETSYNCRO:
@@ -1529,7 +1530,7 @@ static int rme96xx_release(struct inode *in, struct file *file)
 }
 
 
-static ssize_t rme96xx_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+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;
@@ -1597,7 +1598,7 @@ static ssize_t rme96xx_write(struct file *file, const char *buffer, size_t count
        return ret;
 }
 
-static ssize_t rme96xx_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+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;
@@ -1793,6 +1794,8 @@ static int rme96xx_mixer_ioctl(struct inode *inode, struct file *file, unsigned
        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 */
@@ -1802,7 +1805,7 @@ static int rme96xx_mixer_ioctl(struct inode *inode, struct file *file, unsigned
        VALIDATE_STATE(s);
        if (cmd == SOUND_MIXER_PRIVATE1) {
                rme_mixer mixer;
-               if (copy_from_user(&mixer,(void*)arg,sizeof(mixer)))
+               if (copy_from_user(&mixer,argp,sizeof(mixer)))
                        return -EFAULT;
                
                mixer.devnr &= RME96xx_MASK_DEVS;
@@ -1825,14 +1828,14 @@ static int rme96xx_mixer_ioctl(struct inode *inode, struct file *file, unsigned
                mixer.o_offset = s->dma[mixer.devnr].outoffset;
                mixer.i_offset = s->dma[mixer.devnr].inoffset;
 
-               return copy_to_user((void *)arg, &mixer, sizeof(mixer)) ? -EFAULT : 0;
+               return copy_to_user(argp, &mixer, sizeof(mixer)) ? -EFAULT : 0;
        }
        if (cmd == SOUND_MIXER_PRIVATE2) {
-               return put_user(status, (int *)arg);
+               return put_user(status, p);
        }
        if (cmd == SOUND_MIXER_PRIVATE3) {
                u32 control;
-               if (copy_from_user(&control,(void*)arg,sizeof(control)))
+               if (copy_from_user(&control,argp,sizeof(control)))
                        return -EFAULT;
                if (file->f_mode & FMODE_WRITE) {
                        s->control_register &= ~RME96xx_mixer_allowed;
@@ -1840,7 +1843,7 @@ static int rme96xx_mixer_ioctl(struct inode *inode, struct file *file, unsigned
                        writel(control,s->iobase + RME96xx_control_register);
                }
 
-            return put_user(s->control_register, (int *)arg);
+            return put_user(s->control_register, p);
        }
        return -1;
 }
index 7f7b1c1..40914dd 100644 (file)
@@ -836,7 +836,7 @@ static signed short *lbuf16 = (signed short *)lbuf8;
 static void
 sb16_copy_from_user(int dev,
                char *localbuf, int localoffs,
-               const char *userbuf, int useroffs,
+               const char __user *userbuf, int useroffs,
                int max_in, int max_out,
                int *used, int *returned,
                int len)
index b5f5ecb..012f6d2 100644 (file)
@@ -309,7 +309,13 @@ static int __init sb_init(void)
 
        /* If either PnP or Legacy registered a card then return
         * success */
-       return (pres > 0 || lres > 0) ? 0 : -ENODEV;
+       if (pres <= 0 && lres <= 0) {
+#ifdef CONFIG_PNP
+               pnp_unregister_card_driver(&sb_pnp_driver);
+#endif
+               return -ENODEV;
+       }
+       return 0;
 }
 
 static void __exit sb_exit(void)
index 3639a53..249d69c 100644 (file)
@@ -943,7 +943,10 @@ void sb_setmixer(sb_devc * devc, unsigned int port, unsigned int value)
 {
        unsigned long flags;
 
-       if (devc->model == MDL_ESS) return ess_setmixer (devc, port, value);
+       if (devc->model == MDL_ESS) {
+               ess_setmixer (devc, port, value);
+               return;
+       }
 
        spin_lock_irqsave(&devc->lock, flags);
 
index 9bb3596..e231cf0 100644 (file)
@@ -1042,6 +1042,7 @@ 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) {
@@ -1050,7 +1051,7 @@ static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg)
                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 *)arg, &info, sizeof(info)))
+               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
@@ -1059,14 +1060,14 @@ static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg)
                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 *)arg, &info, sizeof(info)))
+               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
        if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, (int *)arg);
+               return put_user(SOUND_VERSION, p);
        if (cmd == SOUND_MIXER_PRIVATE1) {  /* SRS settings */
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                spin_lock_irqsave(&s->lock, flags);
                if (val & 1) {
@@ -1086,47 +1087,47 @@ static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg)
                r = rdindir(s, SV_CISRSCENTER);
                spin_unlock_irqrestore(&s->lock, flags);
                if (l & 0x80)
-                       return put_user(0, (int *)arg);
-               return put_user(((4 - (l & 7)) << 2) | ((4 - (r & 7)) << 5) | 2, (int *)arg);
+                       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), (int *)arg);
+                       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, (int *)arg);
+                       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, (int *)arg);
+                       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, (int *)arg);
+                       return put_user(val, p);
                        
                 case SOUND_MIXER_CAPS:
-                       return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg);
+                       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, (int *)arg);
+                       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], (int *)arg);
+                       return put_user(s->mix.vol[volidx[i]-1], p);
 #endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
                }
        }
@@ -1135,7 +1136,7 @@ static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg)
        s->mix.modcnt++;
        switch (_IOC_NR(cmd)) {
        case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                i = hweight32(val);
                if (i == 0)
@@ -1160,7 +1161,7 @@ static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg)
                i = _IOC_NR(cmd);
                if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
                        return -EINVAL;
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                l = val & 0xff;
                r = (val >> 8) & 0xff;
@@ -1224,12 +1225,12 @@ static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg)
                }
                spin_unlock_irqrestore(&s->lock, flags);
 #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                return return_mixval(s, i, (int *)arg);
+                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], (int *)arg);
+               return put_user(s->mix.vol[volidx[i]-1], p);
 #endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
        }
 }
@@ -1314,7 +1315,7 @@ static int drain_dac(struct sv_state *s, int nonblock)
 
 /* --------------------------------------------------------------------- */
 
-static ssize_t sv_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+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);
@@ -1399,7 +1400,7 @@ static ssize_t sv_read(struct file *file, char *buffer, size_t count, loff_t *pp
        return ret;
 }
 
-static ssize_t sv_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+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);
@@ -1570,13 +1571,15 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
        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, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_SYNC:
                if (file->f_mode & FMODE_WRITE)
@@ -1587,7 +1590,7 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
        case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+               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) {
@@ -1603,7 +1606,7 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
         case SNDCTL_DSP_SPEED:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val >= 0) {
                        if (file->f_mode & FMODE_READ) {
@@ -1617,10 +1620,10 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                                set_dac_rate(s, val);
                        }
                }
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
                
         case SNDCTL_DSP_STEREO:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                fmtd = 0;
                fmtm = ~0;
@@ -1644,7 +1647,7 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 0) {
                        fmtd = 0;
@@ -1668,13 +1671,13 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        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, (int *)arg);
+                                          : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, p);
                
        case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+                return put_user(AFMT_S16_LE|AFMT_U8, p);
                
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (val != AFMT_QUERY) {
                        fmtd = 0;
@@ -1698,7 +1701,7 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        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, (int *)arg);
+                                          : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? AFMT_S16_LE : AFMT_U8, p);
                
        case SNDCTL_DSP_POST:
                 return 0;
@@ -1709,10 +1712,10 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        val |= PCM_ENABLE_INPUT;
                if (file->f_mode & FMODE_WRITE && s->enable & SV_CENABLE_PE) 
                        val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, (int *)arg);
+               return put_user(val, p);
                
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        if (val & PCM_ENABLE_INPUT) {
@@ -1753,7 +1756,7 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                 abinfo.fragstotal = s->dma_dac.numfrag;
                 abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETISPACE:
                if (!(file->f_mode & FMODE_READ))
@@ -1770,7 +1773,7 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                 abinfo.fragstotal = s->dma_adc.numfrag;
                 abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
                spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
                
         case SNDCTL_DSP_NONBLOCK:
                 file->f_flags |= O_NONBLOCK;
@@ -1787,7 +1790,7 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                spin_unlock_irqrestore(&s->lock, flags);
                if (count < 0)
                        count = 0;
-               return put_user(count, (int *)arg);
+               return put_user(count, p);
 
         case SNDCTL_DSP_GETIPTR:
                if (!(file->f_mode & FMODE_READ))
@@ -1805,7 +1808,7 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                if (s->dma_adc.mapped)
                        s->dma_adc.count &= s->dma_adc.fragsize-1;
                spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -1825,7 +1828,7 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                if (s->dma_dac.mapped)
                        s->dma_dac.count &= s->dma_dac.fragsize-1;
                spin_unlock_irqrestore(&s->lock, flags);
-                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+                if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
                        return -EFAULT;
                return 0;
 
@@ -1833,14 +1836,14 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                if (file->f_mode & FMODE_WRITE) {
                        if ((val = prog_dmabuf(s, 0)))
                                return val;
-                       return put_user(s->dma_dac.fragsize, (int *)arg);
+                       return put_user(s->dma_dac.fragsize, p);
                }
                if ((val = prog_dmabuf(s, 1)))
                        return val;
-               return put_user(s->dma_adc.fragsize, (int *)arg);
+               return put_user(s->dma_adc.fragsize, p);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, (int *)arg))
+                if (get_user(val, p))
                        return -EFAULT;
                if (file->f_mode & FMODE_READ) {
                        s->dma_adc.ossfragshift = val & 0xffff;
@@ -1868,7 +1871,7 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                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))
+                if (get_user(val, p))
                        return -EFAULT;
                if (val != 1 && val != 2 && val != 4)
                        return -EINVAL;
@@ -1879,15 +1882,15 @@ static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                return 0;
 
         case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+               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, (int *)arg);
+                                          : (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, (int *)arg);
+                                          : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? 16 : 8, p);
 
         case SOUND_PCM_WRITE_FILTER:
         case SNDCTL_DSP_SETSYNCRO:
@@ -1992,7 +1995,7 @@ static /*const*/ struct file_operations sv_audio_fops = {
 
 /* --------------------------------------------------------------------- */
 
-static ssize_t sv_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+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);
@@ -2055,7 +2058,7 @@ static ssize_t sv_midi_read(struct file *file, char *buffer, size_t count, loff_
        return ret;
 }
 
-static ssize_t sv_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+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);
@@ -2297,7 +2300,7 @@ static int sv_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cm
                return 0;
 
        case FM_IOCTL_PLAY_NOTE:
-               if (copy_from_user(&n, (void *)arg, sizeof(n)))
+               if (copy_from_user(&n, (void __user *)arg, sizeof(n)))
                        return -EFAULT;
                if (n.voice >= 18)
                        return -EINVAL;
@@ -2315,7 +2318,7 @@ static int sv_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cm
                return 0;
 
        case FM_IOCTL_SET_VOICE:
-               if (copy_from_user(&v, (void *)arg, sizeof(v)))
+               if (copy_from_user(&v, (void __user *)arg, sizeof(v)))
                        return -EFAULT;
                if (v.voice >= 18)
                        return -EINVAL;
@@ -2345,7 +2348,7 @@ static int sv_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cm
                return 0;
                
        case FM_IOCTL_SET_PARAMS:
-               if (copy_from_user(&p, (void *)arg, sizeof(p)))
+               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);
index e5e14cf..ed04f40 100644 (file)
@@ -497,7 +497,8 @@ static void ali_setup_spdif_in(struct trident_card *card);
 static void ali_disable_spdif_in(struct trident_card *card);
 static void ali_disable_special_channel(struct trident_card *card, int ch);
 static void ali_setup_spdif_out(struct trident_card *card, int flag);
-static int ali_write_5_1(struct trident_state *state, const char *buffer, 
+static int ali_write_5_1(struct trident_state *state,
+                        const char __user *buffer, 
                         int cnt_for_multi_channel, unsigned int *copy_count, 
                         unsigned int *state_cnt);
 static int ali_allocate_other_states_resources(struct trident_state *state, 
@@ -1861,7 +1862,7 @@ trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 /* to be copied to the user's buffer.  it is filled by the dma machine and */ 
 /* drained by this loop. */
 static ssize_t
-trident_read(struct file *file, char *buffer, size_t count, loff_t * ppos)
+trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
 {
        struct trident_state *state = (struct trident_state *)file->private_data;
        struct dmabuf *dmabuf = &state->dmabuf;
@@ -1976,7 +1977,7 @@ out:
    the soundcard.  it is drained by the dma machine and filled by this loop. */
 
 static ssize_t
-trident_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
+trident_write(struct file *file, const char __user *buffer, size_t count, loff_t * ppos)
 {
        struct trident_state *state = (struct trident_state *)file->private_data;
        struct dmabuf *dmabuf = &state->dmabuf;
@@ -2247,8 +2248,9 @@ trident_ioctl(struct inode *inode, struct file *file,
        audio_buf_info abinfo;
        count_info cinfo;
        int val, mapped, ret = 0;
-
        struct trident_card *card = state->card;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
 
        VALIDATE_STATE(state);
 
@@ -2256,11 +2258,11 @@ trident_ioctl(struct inode *inode, struct file *file,
        mapped = ((file->f_mode & (FMODE_WRITE | FMODE_READ)) && dmabuf->mapped);
 
        pr_debug("trident: trident_ioctl, command = %2d, arg = 0x%08x\n",
-                _IOC_NR(cmd), arg ? *(int *) arg : 0);
+                _IOC_NR(cmd), arg ? *p : 0);
 
        switch (cmd) {
        case OSS_GETVERSION:
-               ret = put_user(SOUND_VERSION, (int *) arg);
+               ret = put_user(SOUND_VERSION, p);
                break;
 
        case SNDCTL_DSP_RESET:
@@ -2287,7 +2289,7 @@ trident_ioctl(struct inode *inode, struct file *file,
                break;
 
        case SNDCTL_DSP_SPEED:  /* set smaple rate */
-               if (get_user(val, (int *) arg)) {
+               if (get_user(val, p)) {
                        ret = -EFAULT;
                        break;
                }
@@ -2307,11 +2309,11 @@ trident_ioctl(struct inode *inode, struct file *file,
                                spin_unlock_irqrestore(&state->card->lock, flags);
                        }
                }
-               ret = put_user(dmabuf->rate, (int *) arg);
+               ret = put_user(dmabuf->rate, p);
                break;
 
        case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
-               if (get_user(val, (int *) arg)) {
+               if (get_user(val, p)) {
                        ret = -EFAULT;
                        break;
                }
@@ -2342,14 +2344,14 @@ trident_ioctl(struct inode *inode, struct file *file,
                        if ((val = prog_dmabuf_playback(state)))
                                ret = val;
                        else
-                               ret = put_user(dmabuf->fragsize, (int *) arg);
+                               ret = put_user(dmabuf->fragsize, p);
                        break;
                }
                if (file->f_mode & FMODE_READ) {
                        if ((val = prog_dmabuf_record(state)))
                                ret = val;
                        else
-                               ret = put_user(dmabuf->fragsize, (int *) arg);
+                               ret = put_user(dmabuf->fragsize, p);
                        break;
                }
                /* neither READ nor WRITE? is this even possible? */
@@ -2359,11 +2361,11 @@ trident_ioctl(struct inode *inode, struct file *file,
 
        case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format */
                ret = put_user(AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 | 
-                              AFMT_U8, (int *) arg);
+                              AFMT_U8, p);
                break;
 
        case SNDCTL_DSP_SETFMT: /* Select sample format */
-               if (get_user(val, (int *) arg)) {
+               if (get_user(val, p)) {
                        ret = -EFAULT;
                        break;
                }
@@ -2390,11 +2392,11 @@ trident_ioctl(struct inode *inode, struct file *file,
                }
                unlock_set_fmt(state);
                ret = put_user((dmabuf->fmt & TRIDENT_FMT_16BIT) ? AFMT_S16_LE : 
-                              AFMT_U8, (int *) arg);
+                              AFMT_U8, p);
                break;
 
        case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, (int *) arg)) {
+               if (get_user(val, p)) {
                        ret = -EFAULT;
                        break;
                }
@@ -2458,7 +2460,7 @@ trident_ioctl(struct inode *inode, struct file *file,
                        }
                        unlock_set_fmt(state);
                }
-               ret = put_user(val, (int *) arg);
+               ret = put_user(val, p);
                break;
 
        case SNDCTL_DSP_POST:
@@ -2470,7 +2472,7 @@ trident_ioctl(struct inode *inode, struct file *file,
                        ret = -EINVAL;
                        break;
                }
-               if (get_user(val, (int *) arg)) {
+               if (get_user(val, p)) {
                        ret = -EFAULT;
                        break;
                }
@@ -2482,7 +2484,7 @@ trident_ioctl(struct inode *inode, struct file *file,
                break;
 
        case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, (int *) arg)) {
+               if (get_user(val, p)) {
                        ret = -EFAULT;
                        break;
                }
@@ -2514,7 +2516,7 @@ trident_ioctl(struct inode *inode, struct file *file,
                abinfo.fragstotal = dmabuf->numfrag;
                abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
                spin_unlock_irqrestore(&state->card->lock, flags);
-               ret = copy_to_user((void *) arg, &abinfo, sizeof (abinfo)) ? 
+               ret = copy_to_user(argp, &abinfo, sizeof (abinfo)) ? 
                        -EFAULT : 0;
                break;
 
@@ -2534,7 +2536,7 @@ trident_ioctl(struct inode *inode, struct file *file,
                abinfo.fragstotal = dmabuf->numfrag;
                abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
                spin_unlock_irqrestore(&state->card->lock, flags);
-               ret = copy_to_user((void *) arg, &abinfo, sizeof (abinfo)) ? 
+               ret = copy_to_user(argp, &abinfo, sizeof (abinfo)) ? 
                        -EFAULT : 0;
                break;
 
@@ -2544,7 +2546,7 @@ trident_ioctl(struct inode *inode, struct file *file,
 
        case SNDCTL_DSP_GETCAPS:
                ret = put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | 
-                              DSP_CAP_MMAP | DSP_CAP_BIND, (int *) arg);
+                              DSP_CAP_MMAP | DSP_CAP_BIND, p);
                break;
 
        case SNDCTL_DSP_GETTRIGGER:
@@ -2553,11 +2555,11 @@ trident_ioctl(struct inode *inode, struct file *file,
                        val |= PCM_ENABLE_INPUT;
                if ((file->f_mode & FMODE_WRITE) && dmabuf->enable)
                        val |= PCM_ENABLE_OUTPUT;
-               ret = put_user(val, (int *) arg);
+               ret = put_user(val, p);
                break;
 
        case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *) arg)) {
+               if (get_user(val, p)) {
                        ret = -EFAULT;
                        break;
                }
@@ -2599,7 +2601,7 @@ trident_ioctl(struct inode *inode, struct file *file,
                if (dmabuf->mapped)
                        dmabuf->count &= dmabuf->fragsize - 1;
                spin_unlock_irqrestore(&state->card->lock, flags);
-               ret = copy_to_user((void *) arg, &cinfo, sizeof (cinfo)) ? 
+               ret = copy_to_user(argp, &cinfo, sizeof (cinfo)) ? 
                        -EFAULT : 0;
                break;
 
@@ -2622,7 +2624,7 @@ trident_ioctl(struct inode *inode, struct file *file,
                if (dmabuf->mapped)
                        dmabuf->count &= dmabuf->fragsize - 1;
                spin_unlock_irqrestore(&state->card->lock, flags);
-               ret = copy_to_user((void *) arg, &cinfo, sizeof (cinfo)) ? 
+               ret = copy_to_user(argp, &cinfo, sizeof (cinfo)) ? 
                        -EFAULT : 0;
                break;
 
@@ -2643,26 +2645,26 @@ trident_ioctl(struct inode *inode, struct file *file,
                trident_update_ptr(state);
                val = dmabuf->count;
                spin_unlock_irqrestore(&state->card->lock, flags);
-               ret = put_user(val, (int *) arg);
+               ret = put_user(val, p);
                break;
 
        case SOUND_PCM_READ_RATE:
-               ret = put_user(dmabuf->rate, (int *) arg);
+               ret = put_user(dmabuf->rate, p);
                break;
 
        case SOUND_PCM_READ_CHANNELS:
                ret = put_user((dmabuf->fmt & TRIDENT_FMT_STEREO) ? 2 : 1, 
-                              (int *) arg);
+                              p);
                break;
 
        case SOUND_PCM_READ_BITS:
                ret = put_user((dmabuf->fmt & TRIDENT_FMT_16BIT) ? AFMT_S16_LE : 
-                              AFMT_U8, (int *) arg);
+                              AFMT_U8, p);
                break;
 
        case SNDCTL_DSP_GETCHANNELMASK:
                ret = put_user(DSP_BIND_FRONT | DSP_BIND_SURR | 
-                              DSP_BIND_CENTER_LFE,  (int *) arg);
+                              DSP_BIND_CENTER_LFE,  p);
                break;
 
        case SNDCTL_DSP_BIND_CHANNEL:
@@ -2671,7 +2673,7 @@ trident_ioctl(struct inode *inode, struct file *file,
                        break;
                }
 
-               if (get_user(val, (int *) arg)) {
+               if (get_user(val, p)) {
                        ret = -EFAULT;
                        break;
                }
@@ -2688,7 +2690,7 @@ trident_ioctl(struct inode *inode, struct file *file,
                                                              SRC_ENABLE);
                        dmabuf->channel->attribute |= mask2attr[ffs(val)];
                }
-               ret = put_user(val, (int *) arg);
+               ret = put_user(val, p);
                break;
 
        case SNDCTL_DSP_MAPINBUF:
@@ -3878,14 +3880,14 @@ depend on a master state's DMA, and changing the counters of the master
 state DMA is protected by a spinlock.
 */
 static int
-ali_write_5_1(struct trident_state *state, const char *buf, 
+ali_write_5_1(struct trident_state *state, const char __user *buf, 
              int cnt_for_multi_channel, unsigned int *copy_count, 
              unsigned int *state_cnt)
 {
 
        struct dmabuf *dmabuf = &state->dmabuf;
        struct dmabuf *dmabuf_temp;
-       const char *buffer = buf;
+       const char __user *buffer = buf;
        unsigned swptr, other_dma_nums, sample_s;
        unsigned int i, loop;
 
@@ -4018,7 +4020,7 @@ ali_free_other_states_resources(struct trident_state *state)
 
 struct proc_dir_entry *res;
 static int
-ali_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
+ali_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data)
 {
        struct trident_card *card = (struct trident_card *) data;
        unsigned long flags;
index df6ff55..e793222 100644 (file)
@@ -1011,7 +1011,7 @@ wavefront_send_sample (wavefront_patch_info *header,
 
        UINT16 sample_short;
        UINT32 length;
-       UINT16 *data_end = 0;
+       UINT16 __user *data_end = 0;
        unsigned int i;
        const int max_blksize = 4096/2;
        unsigned int written;
@@ -1024,11 +1024,11 @@ wavefront_send_sample (wavefront_patch_info *header,
        int initial_skip = 0;
 
        DPRINT (WF_DEBUG_LOAD_PATCH, "sample %sdownload for slot %d, "
-                                     "type %d, %d bytes from 0x%x\n",
+                                     "type %d, %d bytes from %p\n",
                                      header->size ? "" : "header ", 
                                      header->number, header->subkey,
                                      header->size,
-                                     (int) header->dataptr);
+                                     header->dataptr);
 
        if (header->number == WAVEFRONT_FIND_FREE_SAMPLE_SLOT) {
                int x;
@@ -1688,8 +1688,7 @@ wavefront_load_patch (const char __user *addr)
 
        case WF_ST_MULTISAMPLE:
 
-               if (copy_from_user((unsigned char *) &header.hdr.s,
-                                  (unsigned char *) header.hdrptr,
+               if (copy_from_user(&header.hdr.s, header.hdrptr,
                                   sizeof(wavefront_multisample)))
                        return -EFAULT;
 
@@ -1698,32 +1697,28 @@ wavefront_load_patch (const char __user *addr)
 
        case WF_ST_ALIAS:
 
-               if (copy_from_user((unsigned char *) &header.hdr.a,
-                                  (unsigned char *) header.hdrptr,
+               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((unsigned char *) &header.hdr.d, 
-                                  (unsigned char *) header.hdrptr,
+               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((unsigned char *) &header.hdr.p, 
-                                  (unsigned char *) header.hdrptr,
+               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((unsigned char *) &header.hdr.pr, 
-                                  (unsigned char *) header.hdrptr,
+               if (copy_from_user(&header.hdr.pr, header.hdrptr,
                                   sizeof (wavefront_program)))
                        return -EFAULT;
 
@@ -3002,7 +2997,7 @@ wffx_ioctl (wavefront_fx_info *r)
                                return -(EINVAL);
                        }
                        if (copy_from_user(page_data,
-                                          (unsigned char *)r->data[3],
+                                          (unsigned char __user *)r->data[3],
                                           r->data[2]))
                                return -EFAULT;
                        pd = page_data;
index c6183e7..7b3236f 100644 (file)
@@ -1220,7 +1220,7 @@ out0:
  * machine and drained by this loop.
  */
 static ssize_t
-ymf_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+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;
@@ -1335,7 +1335,7 @@ ymf_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
 }
 
 static ssize_t
-ymf_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+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;
@@ -1568,11 +1568,13 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
        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, (int *)arg);
+               return put_user(SOUND_VERSION, p);
 
        case SNDCTL_DSP_RESET:
                YMFDBGX("ymf_ioctl: cmd 0x%x(RESET)\n", cmd);
@@ -1614,7 +1616,7 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
                return 0;
 
        case SNDCTL_DSP_SPEED: /* set smaple rate */
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                YMFDBGX("ymf_ioctl: cmd 0x%x(SPEED) sp %d\n", cmd, val);
                if (val >= 8000 && val <= 48000) {
@@ -1637,7 +1639,7 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
                                spin_unlock_irqrestore(&state->unit->reg_lock, flags);
                        }
                }
-               return put_user(state->format.rate, (int *)arg);
+               return put_user(state->format.rate, p);
 
        /*
         * OSS manual does not mention SNDCTL_DSP_STEREO at all.
@@ -1646,7 +1648,7 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
         * However, mpg123 calls it. I wonder, why Michael Hipp used it.
         */
        case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
-               if (get_user(val, (int *)arg))
+               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) {
@@ -1676,23 +1678,23 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
                                return val;
                        val = state->wpcm.dmabuf.fragsize;
                        YMFDBGX("ymf_ioctl: GETBLK w %d\n", val);
-                       return put_user(val, (int *)arg);
+                       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, (int *)arg);
+                       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, (int *)arg);
+               return put_user(AFMT_S16_LE|AFMT_U8, p);
 
        case SNDCTL_DSP_SETFMT: /* Select sample format */
-               if (get_user(val, (int *)arg))
+               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) {
@@ -1715,10 +1717,10 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
                                spin_unlock_irqrestore(&state->unit->reg_lock, flags);
                        }
                }
-               return put_user(state->format.format, (int *)arg);
+               return put_user(state->format.format, p);
 
        case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                YMFDBGX("ymf_ioctl: cmd 0x%x(CHAN) ch %d\n", cmd, val);
                if (val != 0) {
@@ -1745,7 +1747,7 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
                                }
                        }
                }
-               return put_user(state->format.voices, (int *)arg);
+               return put_user(state->format.voices, p);
 
        case SNDCTL_DSP_POST:
                YMFDBGX("ymf_ioctl: cmd 0x%x(POST)\n", cmd);
@@ -1768,7 +1770,7 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
                return 0;
 
        case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, (int *)arg))
+               if (get_user(val, p))
                        return -EFAULT;
                YMFDBGX("ymf_ioctl: cmd 0x%x(SETFRAG) fr 0x%04x:%04x(%d:%d)\n",
                    cmd,
@@ -1799,7 +1801,7 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
                abinfo.fragstotal = dmabuf->numfrag;
                abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
                spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETISPACE:
                YMFDBGX("ymf_ioctl: cmd 0x%x(GETISPACE)\n", cmd);
@@ -1814,7 +1816,7 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
                abinfo.fragstotal = dmabuf->numfrag;
                abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
                spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_NONBLOCK:
                YMFDBGX("ymf_ioctl: cmd 0x%x(NONBLOCK)\n", cmd);
@@ -1824,8 +1826,8 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
        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,
-                           (int *)arg); */
-               return put_user(0, (int *)arg);
+                           p); */
+               return put_user(0, p);
 
        case SNDCTL_DSP_GETIPTR:
                YMFDBGX("ymf_ioctl: cmd 0x%x(GETIPTR)\n", cmd);
@@ -1839,7 +1841,7 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
                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((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETOPTR:
                YMFDBGX("ymf_ioctl: cmd 0x%x(GETOPTR)\n", cmd);
@@ -1853,7 +1855,7 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
                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((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+               return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_SETDUPLEX:
                YMFDBGX("ymf_ioctl: cmd 0x%x(SETDUPLEX)\n", cmd);
@@ -1861,15 +1863,15 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
 
        case SOUND_PCM_READ_RATE:
                YMFDBGX("ymf_ioctl: cmd 0x%x(READ_RATE)\n", cmd);
-               return put_user(state->format.rate, (int *)arg);
+               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, (int *)arg);
+               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, (int *)arg);
+               return put_user(AFMT_S16_LE, p);
 
        case SNDCTL_DSP_MAPINBUF:
        case SNDCTL_DSP_MAPOUTBUF:
index 287b7d4..91a6041 100644 (file)
@@ -1185,7 +1185,7 @@ static void snd_cs4281_proc_read(snd_info_entry_t *entry,
 }
 
 static long snd_cs4281_BA0_read(snd_info_entry_t *entry, void *file_private_data,
-                               struct file *file, char *buf, long count)
+                               struct file *file, char __user *buf, long count)
 {
        long size;
        cs4281_t *chip = snd_magic_cast(cs4281_t, entry->private_data, return -ENXIO);
@@ -1202,7 +1202,7 @@ static long snd_cs4281_BA0_read(snd_info_entry_t *entry, void *file_private_data
 }
 
 static long snd_cs4281_BA1_read(snd_info_entry_t *entry, void *file_private_data,
-                               struct file *file, char *buf, long count)
+                               struct file *file, char __user *buf, long count)
 {
        long size;
        cs4281_t *chip = snd_magic_cast(cs4281_t, entry->private_data, return -ENXIO);
index 29861bb..9a17583 100644 (file)
@@ -2866,7 +2866,7 @@ void __devinit snd_cs46xx_gameport(cs46xx_t *chip)
  */
 
 static long snd_cs46xx_io_read(snd_info_entry_t *entry, void *file_private_data,
-                              struct file *file, char *buf, long count)
+                              struct file *file, char __user *buf, long count)
 {
        long size;
        snd_cs46xx_region_t *region = (snd_cs46xx_region_t *)entry->private_data;
index 3100d00..c02a949 100644 (file)
@@ -246,6 +246,12 @@ void cs46xx_dsp_proc_register_scb_desc (cs46xx_t *chip,dsp_scb_descriptor_t * sc
                if ((entry = snd_info_create_card_entry(ins->snd_card, scb->scb_name, 
                                                        ins->proc_dsp_dir)) != NULL) {
                        scb_info = kmalloc(sizeof(proc_scb_info_t), GFP_KERNEL);
+                       if (!scb_info) {
+                               snd_info_free_entry(entry);
+                               entry = NULL;
+                               goto out;
+                       }
+
                        scb_info->chip = chip;
                        scb_info->scb_desc = scb;
       
@@ -262,7 +268,7 @@ void cs46xx_dsp_proc_register_scb_desc (cs46xx_t *chip,dsp_scb_descriptor_t * sc
                                entry = NULL;
                        }
                }
-
+out:
                scb->proc_info = entry;
        }
 }
index 22eb444..c4f7630 100644 (file)
@@ -898,8 +898,10 @@ static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ct
 static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
        unsigned int i;
-       snd_ctl_elem_id_t *_id, id;
-       emu10k1_fx8010_control_gpr_t *_gctl, gctl;
+       snd_ctl_elem_id_t __user *_id;
+       snd_ctl_elem_id_t id;
+       emu10k1_fx8010_control_gpr_t __user *_gctl;
+       emu10k1_fx8010_control_gpr_t gctl;
        
        for (i = 0, _id = icode->gpr_del_controls;
             i < icode->gpr_del_control_count; i++, _id++) {
@@ -946,7 +948,8 @@ static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
 static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
        unsigned int i, j;
-       emu10k1_fx8010_control_gpr_t *_gctl, gctl;
+       emu10k1_fx8010_control_gpr_t __user *_gctl;
+       emu10k1_fx8010_control_gpr_t gctl;
        snd_emu10k1_fx8010_ctl_t *ctl, nctl;
        snd_kcontrol_new_t knew;
        snd_kcontrol_t *kctl;
@@ -1012,7 +1015,8 @@ static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icod
 static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
        unsigned int i;
-       snd_ctl_elem_id_t *_id, id;
+       snd_ctl_elem_id_t id;
+       snd_ctl_elem_id_t __user *_id;
        snd_emu10k1_fx8010_ctl_t *ctl;
        snd_card_t *card = emu->card;
        
@@ -1031,7 +1035,8 @@ static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icod
 {
        unsigned int i = 0, j;
        unsigned int total = 0;
-       emu10k1_fx8010_control_gpr_t *_gctl, gctl;
+       emu10k1_fx8010_control_gpr_t gctl;
+       emu10k1_fx8010_control_gpr_t __user *_gctl;
        snd_emu10k1_fx8010_ctl_t *ctl;
        snd_ctl_elem_id_t *id;
        struct list_head *list;
@@ -2297,6 +2302,7 @@ static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigne
        emu10k1_fx8010_code_t *icode;
        emu10k1_fx8010_pcm_t *ipcm;
        unsigned int addr;
+       void __user *argp = (void __user *)arg;
        int res;
        
        switch (cmd) {
@@ -2308,7 +2314,7 @@ static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigne
                        kfree(info);
                        return res;
                }
-               if (copy_to_user((void *)arg, info, sizeof(*info))) {
+               if (copy_to_user(argp, info, sizeof(*info))) {
                        kfree(info);
                        return -EFAULT;
                }
@@ -2320,7 +2326,7 @@ static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigne
                icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
                if (icode == NULL)
                        return -ENOMEM;
-               if (copy_from_user(icode, (void *)arg, sizeof(*icode))) {
+               if (copy_from_user(icode, argp, sizeof(*icode))) {
                        kfree(icode);
                        return -EFAULT;
                }
@@ -2331,12 +2337,12 @@ static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigne
                icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
                if (icode == NULL)
                        return -ENOMEM;
-               if (copy_from_user(icode, (void *)arg, sizeof(*icode))) {
+               if (copy_from_user(icode, argp, sizeof(*icode))) {
                        kfree(icode);
                        return -EFAULT;
                }
                res = snd_emu10k1_icode_peek(emu, icode);
-               if (res == 0 && copy_to_user((void *)arg, icode, sizeof(*icode))) {
+               if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
                        kfree(icode);
                        return -EFAULT;
                }
@@ -2348,7 +2354,7 @@ static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigne
                ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
                if (ipcm == NULL)
                        return -ENOMEM;
-               if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) {
+               if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
                        kfree(ipcm);
                        return -EFAULT;
                }
@@ -2361,12 +2367,12 @@ static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigne
                ipcm = (emu10k1_fx8010_pcm_t *)snd_kcalloc(sizeof(*ipcm), GFP_KERNEL);
                if (ipcm == NULL)
                        return -ENOMEM;
-               if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) {
+               if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
                        kfree(ipcm);
                        return -EFAULT;
                }
                res = snd_emu10k1_ipcm_peek(emu, ipcm);
-               if (res == 0 && copy_to_user((void *)arg, ipcm, sizeof(*ipcm))) {
+               if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
                        kfree(ipcm);
                        return -EFAULT;
                }
@@ -2377,7 +2383,7 @@ static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigne
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               if (get_user(addr, (unsigned int *)arg))
+               if (get_user(addr, (unsigned int __user *)argp))
                        return -EFAULT;
                down(&emu->fx8010.lock);
                res = snd_emu10k1_fx8010_tram_setup(emu, addr);
@@ -2415,7 +2421,7 @@ static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigne
        case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               if (get_user(addr, (unsigned int *)arg))
+               if (get_user(addr, (unsigned int __user *)argp))
                        return -EFAULT;
                if (addr > 0x1ff)
                        return -EINVAL;
@@ -2434,7 +2440,7 @@ static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigne
                        addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
                else
                        addr = snd_emu10k1_ptr_read(emu, DBG, 0);
-               if (put_user(addr, (unsigned int *)arg))
+               if (put_user(addr, (unsigned int __user *)argp))
                        return -EFAULT;
                return 0;
        }
index 918bc68..39f5307 100644 (file)
@@ -191,7 +191,7 @@ static void snd_emu10k1_proc_acode_read(snd_info_entry_t *entry,
 #define TOTAL_SIZE_CODE                (0x200*8)
 
 static long snd_emu10k1_fx8010_read(snd_info_entry_t *entry, void *file_private_data,
-                                   struct file *file, char *buf, long count)
+                                   struct file *file, char __user *buf, long count)
 {
        long size;
        emu10k1_t *emu = snd_magic_cast(emu10k1_t, entry->private_data, return -ENXIO);
index 7924508..87afa49 100644 (file)
@@ -822,7 +822,7 @@ static snd_pcm_uframes_t snd_es1938_playback_pointer(snd_pcm_substream_t *substr
 static int snd_es1938_capture_copy(snd_pcm_substream_t *substream,
                                   int channel,
                                   snd_pcm_uframes_t pos,
-                                  void *dst,
+                                  void __user *dst,
                                   snd_pcm_uframes_t count)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
@@ -836,7 +836,7 @@ static int snd_es1938_capture_copy(snd_pcm_substream_t *substream,
        } else {
                if (copy_to_user(dst, runtime->dma_area + pos + 1, count - 1))
                        return -EFAULT;
-               if (put_user(runtime->dma_area[0], ((unsigned char *)dst) + count - 1))
+               if (put_user(runtime->dma_area[0], ((unsigned char __user *)dst) + count - 1))
                        return -EFAULT;
        }
        return 0;
index c2fc6e3..edd2260 100644 (file)
@@ -1328,7 +1328,7 @@ static int snd_korg1212_silence(korg1212_t *korg1212, int pos, int count, int of
        return 0;
 }
 
-static int snd_korg1212_copy_to(korg1212_t *korg1212, void *dst, int pos, int count, int offset, int size)
+static int snd_korg1212_copy_to(korg1212_t *korg1212, void __user *dst, int pos, int count, int offset, int size)
 {
        KorgAudioFrame * src =  korg1212->recordDataBufsPtr[0].bufferData + pos;
        int i, rc;
@@ -1346,7 +1346,7 @@ static int snd_korg1212_copy_to(korg1212_t *korg1212, void *dst, int pos, int co
                        return -EFAULT;
                }
 #endif
-               rc = copy_to_user((void*) dst + offset, src, size);
+               rc = copy_to_user(dst + offset, src, size);
                if (rc) {
 #if K1212_DEBUG_LEVEL > 0
                        K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i);
@@ -1360,7 +1360,7 @@ static int snd_korg1212_copy_to(korg1212_t *korg1212, void *dst, int pos, int co
        return 0;
 }
 
-static int snd_korg1212_copy_from(korg1212_t *korg1212, void *src, int pos, int count, int offset, int size)
+static int snd_korg1212_copy_from(korg1212_t *korg1212, void __user *src, int pos, int count, int offset, int size)
 {
        KorgAudioFrame * dst =  korg1212->playDataBufsPtr[0].bufferData + pos;
        int i, rc;
@@ -1671,7 +1671,7 @@ static snd_pcm_uframes_t snd_korg1212_capture_pointer(snd_pcm_substream_t *subst
 static int snd_korg1212_playback_copy(snd_pcm_substream_t *substream,
                         int channel, /* not used (interleaved data) */
                         snd_pcm_uframes_t pos,
-                        void *src,
+                        void __user *src,
                         snd_pcm_uframes_t count)
 {
         korg1212_t *korg1212 = _snd_pcm_substream_chip(substream);
@@ -1701,7 +1701,7 @@ static int snd_korg1212_playback_silence(snd_pcm_substream_t *substream,
 static int snd_korg1212_capture_copy(snd_pcm_substream_t *substream,
                         int channel, /* not used (interleaved data) */
                         snd_pcm_uframes_t pos,
-                        void *dst,
+                        void __user *dst,
                         snd_pcm_uframes_t count)
 {
         korg1212_t *korg1212 = _snd_pcm_substream_chip(substream);
index 4b1a5b2..2b918cc 100644 (file)
@@ -1154,7 +1154,7 @@ static long long snd_mixart_BA1_llseek(snd_info_entry_t *entry,
   mixart_BA0 proc interface for BAR 0 - read callback
  */
 static long snd_mixart_BA0_read(snd_info_entry_t *entry, void *file_private_data,
-                               struct file *file, char *buf, long count)
+                               struct file *file, char __user *buf, long count)
 {
        mixart_mgr_t *mgr = snd_magic_cast(mixart_mgr_t, entry->private_data, return -ENXIO);
 
@@ -1173,7 +1173,7 @@ static long snd_mixart_BA0_read(snd_info_entry_t *entry, void *file_private_data
   mixart_BA1 proc interface for BAR 1 - read callback
  */
 static long snd_mixart_BA1_read(snd_info_entry_t *entry, void *file_private_data,
-                               struct file *file, char *buf, long count)
+                               struct file *file, char __user *buf, long count)
 {
        mixart_mgr_t *mgr = snd_magic_cast(mixart_mgr_t, entry->private_data, return -ENXIO);
 
index 8a2fa86..ee3b246 100644 (file)
@@ -684,7 +684,7 @@ static int
 snd_nm256_playback_copy(snd_pcm_substream_t *substream,
                        int channel, /* not used (interleaved data) */
                        snd_pcm_uframes_t pos,
-                       void *src,
+                       void __user *src,
                        snd_pcm_uframes_t count)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
index 1d19e7e..2f20966 100644 (file)
@@ -298,7 +298,7 @@ static int snd_rme32_playback_silence(snd_pcm_substream_t * substream, int chann
 
 static int snd_rme32_playback_copy(snd_pcm_substream_t * substream, int channel,       /* not used (interleaved data) */
                                   snd_pcm_uframes_t pos,
-                                  void *src, snd_pcm_uframes_t count)
+                                  void __user *src, snd_pcm_uframes_t count)
 {
        rme32_t *rme32 = _snd_pcm_substream_chip(substream);
        count <<= rme32->playback_frlog;
@@ -311,7 +311,7 @@ static int snd_rme32_playback_copy(snd_pcm_substream_t * substream, int channel,
 
 static int snd_rme32_capture_copy(snd_pcm_substream_t * substream, int channel,        /* not used (interleaved data) */
                                  snd_pcm_uframes_t pos,
-                                 void *dst, snd_pcm_uframes_t count)
+                                 void __user *dst, snd_pcm_uframes_t count)
 {
        rme32_t *rme32 = _snd_pcm_substream_chip(substream);
        count <<= rme32->capture_frlog;
index cf1776b..0e04ae4 100644 (file)
@@ -361,7 +361,7 @@ static int
 snd_rme96_playback_copy(snd_pcm_substream_t *substream,
                        int channel, /* not used (interleaved data) */
                        snd_pcm_uframes_t pos,
-                       void *src,
+                       void __user *src,
                        snd_pcm_uframes_t count)
 {
        rme96_t *rme96 = _snd_pcm_substream_chip(substream);
@@ -376,7 +376,7 @@ static int
 snd_rme96_capture_copy(snd_pcm_substream_t *substream,
                       int channel, /* not used (interleaved data) */
                       snd_pcm_uframes_t pos,
-                      void *dst,
+                      void __user *dst,
                       snd_pcm_uframes_t count)
 {
        rme96_t *rme96 = _snd_pcm_substream_chip(substream);
index 88eb352..c91602c 100644 (file)
@@ -1250,9 +1250,9 @@ static inline void snd_hdsp_midi_write_byte (hdsp_t *hdsp, int id, int val)
 {
        /* the hardware already does the relevant bit-mask with 0xff */
        if (id) {
-               return hdsp_write(hdsp, HDSP_midiDataOut1, val);
+               hdsp_write(hdsp, HDSP_midiDataOut1, val);
        } else {
-               return hdsp_write(hdsp, HDSP_midiDataOut0, val);
+               hdsp_write(hdsp, HDSP_midiDataOut0, val);
        }
 }
 
@@ -3834,7 +3834,7 @@ static char *hdsp_channel_buffer_location(hdsp_t *hdsp,
 }
 
 static int snd_hdsp_playback_copy(snd_pcm_substream_t *substream, int channel,
-                                 snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count)
+                                 snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
 {
        hdsp_t *hdsp = _snd_pcm_substream_chip(substream);
        char *channel_buf;
@@ -3849,7 +3849,7 @@ static int snd_hdsp_playback_copy(snd_pcm_substream_t *substream, int channel,
 }
 
 static int snd_hdsp_capture_copy(snd_pcm_substream_t *substream, int channel,
-                                snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count)
+                                snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
 {
        hdsp_t *hdsp = _snd_pcm_substream_chip(substream);
        char *channel_buf;
@@ -4531,10 +4531,11 @@ static int snd_hdsp_hwdep_dummy_op(snd_hwdep_t *hw, struct file *file)
 static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int cmd, unsigned long arg)
 {
        hdsp_t *hdsp = (hdsp_t *)hw->private_data;      
+       void __user *argp = (void __user *)arg;
 
        switch (cmd) {
        case SNDRV_HDSP_IOCTL_GET_PEAK_RMS: {
-               hdsp_peak_rms_t *peak_rms;
+               hdsp_peak_rms_t __user *peak_rms;
                int i;
                
                if (hdsp->io_type == H9652) {
@@ -4542,38 +4543,38 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
                        int doublespeed = 0;
                        if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
                                doublespeed = 1;
-                       peak_rms = (hdsp_peak_rms_t *)arg;
+                       peak_rms = (hdsp_peak_rms_t __user *)arg;
                        for (i = 0; i < 26; ++i) {
                                if (!(doublespeed && (i & 4))) {
-                                       if (copy_to_user_fromio((void *)peak_rms->input_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-i*4, 4) != 0)
+                                       if (copy_to_user_fromio((void __user *)peak_rms->input_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-i*4, 4) != 0)
                                                return -EFAULT;
-                                       if (copy_to_user_fromio((void *)peak_rms->playback_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-(doublespeed ? 14 : 26)*4-i*4, 4) != 0)
+                                       if (copy_to_user_fromio((void __user *)peak_rms->playback_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-(doublespeed ? 14 : 26)*4-i*4, 4) != 0)
                                                return -EFAULT;
-                                       if (copy_to_user_fromio((void *)peak_rms->output_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-2*(doublespeed ? 14 : 26)*4-i*4, 4) != 0)
+                                       if (copy_to_user_fromio((void __user *)peak_rms->output_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-2*(doublespeed ? 14 : 26)*4-i*4, 4) != 0)
                                                return -EFAULT;
                                        rms_low = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+i*8) & 0xFFFFFF00;
                                        rms_high = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+i*8+4) & 0xFFFFFF00;
                                        rms_high += (rms_low >> 24);
                                        rms_low <<= 8;
-                                       if (copy_to_user((void *)peak_rms->input_rms+i*8, &rms_low, 4) != 0)
+                                       if (copy_to_user((void __user *)peak_rms->input_rms+i*8, &rms_low, 4) != 0)
                                                return -EFAULT;
-                                       if (copy_to_user((void *)peak_rms->input_rms+i*8+4, &rms_high, 4) != 0)
+                                       if (copy_to_user((void __user *)peak_rms->input_rms+i*8+4, &rms_high, 4) != 0)
                                                return -EFAULT;                                 
                                        rms_low = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+(doublespeed ? 14 : 26)*8+i*8) & 0xFFFFFF00;
                                        rms_high = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+(doublespeed ? 14 : 26)*8+i*8+4) & 0xFFFFFF00;
                                        rms_high += (rms_low >> 24);
                                        rms_low <<= 8;
-                                       if (copy_to_user((void *)peak_rms->playback_rms+i*8, &rms_low, 4) != 0)
+                                       if (copy_to_user((void __user *)peak_rms->playback_rms+i*8, &rms_low, 4) != 0)
                                                return -EFAULT;
-                                       if (copy_to_user((void *)peak_rms->playback_rms+i*8+4, &rms_high, 4) != 0)
+                                       if (copy_to_user((void __user *)peak_rms->playback_rms+i*8+4, &rms_high, 4) != 0)
                                                return -EFAULT;                                 
                                        rms_low = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+2*(doublespeed ? 14 : 26)*8+i*8) & 0xFFFFFF00;
                                        rms_high = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+2*(doublespeed ? 14 : 26)*8+i*8+4) & 0xFFFFFF00;
                                        rms_high += (rms_low >> 24);
                                        rms_low <<= 8;
-                                       if (copy_to_user((void *)peak_rms->output_rms+i*8, &rms_low, 4) != 0)
+                                       if (copy_to_user((void __user *)peak_rms->output_rms+i*8, &rms_low, 4) != 0)
                                                return -EFAULT;
-                                       if (copy_to_user((void *)peak_rms->output_rms+i*8+4, &rms_high, 4) != 0)
+                                       if (copy_to_user((void __user *)peak_rms->output_rms+i*8+4, &rms_high, 4) != 0)
                                                return -EFAULT;                                 
                                }
                        }
@@ -4586,25 +4587,25 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
                        if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
                                doublespeed = 1;
                        m = (hdsp_9632_meters_t *)(hdsp->iobase+HDSP_9632_metersBase);
-                       peak_rms = (hdsp_peak_rms_t *)arg;
+                       peak_rms = (hdsp_peak_rms_t __user *)arg;
                        for (i = 0, j = 0; i < 16; ++i, ++j) {
-                               if (copy_to_user((void *)peak_rms->input_peaks+i*4, &(m->input_peak[j]), 4) != 0)
+                               if (copy_to_user((void __user *)peak_rms->input_peaks+i*4, &(m->input_peak[j]), 4) != 0)
                                        return -EFAULT;
-                               if (copy_to_user((void *)peak_rms->playback_peaks+i*4, &(m->playback_peak[j]), 4) != 0)
+                               if (copy_to_user((void __user *)peak_rms->playback_peaks+i*4, &(m->playback_peak[j]), 4) != 0)
                                        return -EFAULT;
-                               if (copy_to_user((void *)peak_rms->output_peaks+i*4, &(m->output_peak[j]), 4) != 0)
+                               if (copy_to_user((void __user *)peak_rms->output_peaks+i*4, &(m->output_peak[j]), 4) != 0)
                                        return -EFAULT;
-                               if (copy_to_user((void *)peak_rms->input_rms+i*8, &(m->input_rms_low[j]), 4) != 0)
+                               if (copy_to_user((void __user *)peak_rms->input_rms+i*8, &(m->input_rms_low[j]), 4) != 0)
                                        return -EFAULT;
-                               if (copy_to_user((void *)peak_rms->playback_rms+i*8, &(m->playback_rms_low[j]), 4) != 0)
+                               if (copy_to_user((void __user *)peak_rms->playback_rms+i*8, &(m->playback_rms_low[j]), 4) != 0)
                                        return -EFAULT;
-                               if (copy_to_user((void *)peak_rms->output_rms+i*8, &(m->output_rms_low[j]), 4) != 0)
+                               if (copy_to_user((void __user *)peak_rms->output_rms+i*8, &(m->output_rms_low[j]), 4) != 0)
                                        return -EFAULT;
-                               if (copy_to_user((void *)peak_rms->input_rms+i*8+4, &(m->input_rms_high[j]), 4) != 0)
+                               if (copy_to_user((void __user *)peak_rms->input_rms+i*8+4, &(m->input_rms_high[j]), 4) != 0)
                                        return -EFAULT;
-                               if (copy_to_user((void *)peak_rms->playback_rms+i*8+4, &(m->playback_rms_high[j]), 4) != 0)
+                               if (copy_to_user((void __user *)peak_rms->playback_rms+i*8+4, &(m->playback_rms_high[j]), 4) != 0)
                                        return -EFAULT;
-                               if (copy_to_user((void *)peak_rms->output_rms+i*8+4, &(m->output_rms_high[j]), 4) != 0)
+                               if (copy_to_user((void __user *)peak_rms->output_rms+i*8+4, &(m->output_rms_high[j]), 4) != 0)
                                        return -EFAULT;
                                if (doublespeed && i == 3) i += 4;
                        }
@@ -4614,25 +4615,25 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
                        snd_printk("firmware needs to be uploaded to the card.\n");     
                        return -EINVAL;
                }
-               peak_rms = (hdsp_peak_rms_t *)arg;
+               peak_rms = (hdsp_peak_rms_t __user *)arg;
                for (i = 0; i < 26; ++i) {
-                   if (copy_to_user((void *)peak_rms->playback_peaks+i*4, (void *)hdsp->iobase+HDSP_playbackPeakLevel+i*4, 4) != 0)
+                   if (copy_to_user((void __user *)peak_rms->playback_peaks+i*4, (void *)hdsp->iobase+HDSP_playbackPeakLevel+i*4, 4) != 0)
                            return -EFAULT;
-                   if (copy_to_user((void *)peak_rms->input_peaks+i*4, (void *)hdsp->iobase+HDSP_inputPeakLevel+i*4, 4) != 0)
+                   if (copy_to_user((void __user *)peak_rms->input_peaks+i*4, (void *)hdsp->iobase+HDSP_inputPeakLevel+i*4, 4) != 0)
                            return -EFAULT;
                }
                for (i = 0; i < 26; ++i) {
-                       if (copy_to_user((void *)peak_rms->playback_rms+i*8+4, (void *)hdsp->iobase+HDSP_playbackRmsLevel+i*8, 4) != 0)
+                       if (copy_to_user((void __user *)peak_rms->playback_rms+i*8+4, (void *)hdsp->iobase+HDSP_playbackRmsLevel+i*8, 4) != 0)
                                return -EFAULT;
-                       if (copy_to_user((void *)peak_rms->playback_rms+i*8, (void *)hdsp->iobase+HDSP_playbackRmsLevel+i*8+4, 4) != 0)
+                       if (copy_to_user((void __user *)peak_rms->playback_rms+i*8, (void *)hdsp->iobase+HDSP_playbackRmsLevel+i*8+4, 4) != 0)
                                return -EFAULT;
-                       if (copy_to_user((void *)peak_rms->input_rms+i*8+4, (void *)hdsp->iobase+HDSP_inputRmsLevel+i*8, 4) != 0)
+                       if (copy_to_user((void __user *)peak_rms->input_rms+i*8+4, (void *)hdsp->iobase+HDSP_inputRmsLevel+i*8, 4) != 0)
                                return -EFAULT;
-                       if (copy_to_user((void *)peak_rms->input_rms+i*8, (void *)hdsp->iobase+HDSP_inputRmsLevel+i*8+4, 4) != 0)
+                       if (copy_to_user((void __user *)peak_rms->input_rms+i*8, (void *)hdsp->iobase+HDSP_inputRmsLevel+i*8+4, 4) != 0)
                                return -EFAULT;
                }
                for (i = 0; i < 28; ++i) {
-                   if (copy_to_user((void *)peak_rms->output_peaks+i*4, (void *)hdsp->iobase+HDSP_outputPeakLevel+i*4, 4) != 0)
+                   if (copy_to_user((void __user *)peak_rms->output_peaks+i*4, (void *)hdsp->iobase+HDSP_outputPeakLevel+i*4, 4) != 0)
                            return -EFAULT;
                }
                break;
@@ -4680,7 +4681,7 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
                        info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
                }
                spin_unlock_irqrestore(&hdsp->lock, flags);
-               if (copy_to_user((void *)arg, &info, sizeof(info)))
+               if (copy_to_user(argp, &info, sizeof(info)))
                        return -EFAULT;
                break;
        }
@@ -4690,7 +4691,7 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
                if (hdsp->io_type != H9632) return -EINVAL;
                h9632_aeb.aebi = hdsp->ss_in_channels - H9632_SS_CHANNELS;
                h9632_aeb.aebo = hdsp->ss_out_channels - H9632_SS_CHANNELS;
-               if (copy_to_user((void *)arg, &h9632_aeb, sizeof(h9632_aeb)))
+               if (copy_to_user(argp, &h9632_aeb, sizeof(h9632_aeb)))
                        return -EFAULT;
                break;
        }
@@ -4706,14 +4707,14 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
                }
                hdsp_version.io_type = hdsp->io_type;
                hdsp_version.firmware_rev = hdsp->firmware_rev;
-               if ((err = copy_to_user((void *)arg, &hdsp_version, sizeof(hdsp_version)))) {
+               if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version)))) {
                        return -EFAULT;
                }
                break;
        }
        case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
-               hdsp_firmware_t *firmware;
-               unsigned long *firmware_data;
+               hdsp_firmware_t __user *firmware;
+               unsigned long __user *firmware_data;
                int err;
                
                if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
@@ -4721,7 +4722,7 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
                if (hdsp->io_type == Undefined) return -EINVAL;
 
                snd_printk("initializing firmware upload\n");
-               firmware = (hdsp_firmware_t *)arg;
+               firmware = (hdsp_firmware_t __user *)argp;
 
                if (get_user(firmware_data, &firmware->firmware_data)) {
                        return -EFAULT;
@@ -4754,9 +4755,7 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
                break;
        }
        case SNDRV_HDSP_IOCTL_GET_MIXER: {
-               hdsp_mixer_t *mixer;
-               
-               mixer = (hdsp_mixer_t *)arg;
+               hdsp_mixer_t __user *mixer = (hdsp_mixer_t __user *)argp;
                if (copy_to_user(mixer->matrix, hdsp->mixer_matrix, sizeof(unsigned short)*HDSP_MATRIX_MIXER_SIZE))
                        return -EFAULT;
                break;
index 155d72a..e1abd98 100644 (file)
@@ -2011,7 +2011,7 @@ static char *rme9652_channel_buffer_location(rme9652_t *rme9652,
 }
 
 static int snd_rme9652_playback_copy(snd_pcm_substream_t *substream, int channel,
-                                    snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count)
+                                    snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
 {
        rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
        char *channel_buf;
@@ -2028,7 +2028,7 @@ static int snd_rme9652_playback_copy(snd_pcm_substream_t *substream, int channel
 }
 
 static int snd_rme9652_capture_copy(snd_pcm_substream_t *substream, int channel,
-                                   snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count)
+                                   snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
 {
        rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
        char *channel_buf;
index fdffd38..3c79110 100644 (file)
@@ -471,7 +471,7 @@ int snd_trident_synth_bzero(trident_t *trident, snd_util_memblk_t *blk, int offs
 /*
  * copy_from_user(blk + offset, data, size)
  */
-int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char *data, int size)
+int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char __user *data, int size)
 {
        int page, nextofs, end_offset, temp, temp1;
 
index a2098ea..8f9797d 100644 (file)
@@ -504,7 +504,7 @@ static void sample_private1(trident_t * trident, snd_trident_voice_t * voice, un
  */
 
 static int snd_trident_simple_put_sample(void *private_data, simple_instrument_t * instr,
-                                        char *data, long len, int atomic)
+                                        char __user *data, long len, int atomic)
 {
        trident_t *trident = snd_magic_cast(trident_t, private_data, return -ENXIO);
        int size = instr->size;
@@ -557,7 +557,7 @@ static int snd_trident_simple_put_sample(void *private_data, simple_instrument_t
 }
 
 static int snd_trident_simple_get_sample(void *private_data, simple_instrument_t * instr,
-                                        char *data, long len, int atomic)
+                                        char __user *data, long len, int atomic)
 {
        //trident_t *trident = snd_magic_cast(trident_t, private_data, return -ENXIO);
        int size = instr->size;
index 6f73d05..c9dfb2b 100644 (file)
@@ -357,7 +357,8 @@ static int vx2_load_xilinx_binary(vx_core_t *chip, const snd_hwdep_dsp_image_t *
 {
        unsigned int i;
        unsigned int port;
-       unsigned char *image, data;
+       unsigned char data;
+       unsigned char __user *image;
 
        /* XILINX reset (wait at least 1 milisecond between reset on and off). */
        vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE | VX_XILINX_RESET_MASK);
index a23eb4d..c0e1fd0 100644 (file)
@@ -152,7 +152,8 @@ static int vxp_load_xilinx_binary(vx_core_t *_chip, const snd_hwdep_dsp_image_t
        unsigned int i;
        int c;
        int regCSUER, regRUER;
-       unsigned char *image, data;
+       unsigned char __user *image;
+       unsigned char data;
 
        /* Switch to programmation mode */
        chip->regDIALOG |= VXP_DLG_XILINX_REPROG_MASK;
index a536d9f..8db2e2d 100644 (file)
@@ -34,7 +34,7 @@
 
 /* Prototypes for static functions */
 
-static int open_patch(snd_sf_list_t *sflist, const char *data, int count, int client);
+static int open_patch(snd_sf_list_t *sflist, const char __user *data, int count, int client);
 static snd_soundfont_t *newsf(snd_sf_list_t *sflist, int type, char *name);
 static int is_identical_font(snd_soundfont_t *sf, int type, unsigned char *name);
 static int close_patch(snd_sf_list_t *sflist);